2 * Copyright (c) 2000-2004,2011-2012,2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
26 // machrunloopserver - C++ shell for writing Mach 3 servers called by CFRunLoop
28 #include "machrunloopserver.h"
29 #include <security_utilities/cfutilities.h>
30 #include <mach/mach_error.h>
31 #include <security_utilities/debugging.h>
35 namespace MachPlusPlus
{
39 // Generic Mach server
41 MachRunLoopServer::MachRunLoopServer(const char *name
)
42 : MachServer(name
), CFAutoPort(primaryServicePort())
46 MachRunLoopServer::MachRunLoopServer(const char *name
, const Bootstrap
&boot
)
47 : MachServer(name
, boot
), CFAutoPort(primaryServicePort())
51 void MachRunLoopServer::run(mach_msg_size_t bufferSize
, mach_msg_options_t options
)
53 // allocate reply buffer
54 mReplyMessage
.setBuffer(bufferSize
);
60 perThread().server
= this;
64 MachRunLoopServer::~MachRunLoopServer()
66 // no longer active on this thread
67 perThread().server
= NULL
;
72 // Handle dead-port notifications.
73 // Since we don't actually run our own runloop here, we can't well use standard
74 // notifications to our own server port. So we use a CFMachPort facility instead.
76 void MachRunLoopServer::notifyIfDead(Port port
, bool doNotify
) const
78 if (CFMachPortRef cfPort
= CFMachPortCreateWithPort(NULL
, port
, NULL
, NULL
, NULL
))
79 CFMachPortSetInvalidationCallBack(cfPort
, cfInvalidate
);
82 void MachRunLoopServer::cfInvalidate(CFMachPortRef cfPort
, void *context
)
84 reinterpret_cast<MachRunLoopServer
*>(context
)->notifyDeadName(CFMachPortGetPort(cfPort
));
85 //@@@ should we CFRelease cfPort here?
92 void MachRunLoopServer::receive(const Message
&request
)
94 active().oneRequest(request
);
97 void MachRunLoopServer::oneRequest(const Message
&request
)
99 if (!handle(request
, mReplyMessage
)) { // MIG dispatch failed
100 secinfo("machrls", "MachRunLoopServer dispatch failed");
102 // MIG dispatch handled the call. Send reply back to caller.
103 mReplyMessage
.send((MACH_MSGH_BITS_REMOTE(mReplyMessage
.bits()) == MACH_MSG_TYPE_MOVE_SEND_ONCE
) ?
104 MACH_SEND_MSG
: MACH_SEND_MSG
|MACH_SEND_TIMEOUT
);
106 active().releaseDeferredAllocations();
110 } // end namespace MachPlusPlus
111 } // end namespace Security