]>
Commit | Line | Data |
---|---|---|
b1ab9ed8 | 1 | /* |
d8f41ccd | 2 | * Copyright (c) 2000-2004,2011-2012,2014 Apple Inc. All Rights Reserved. |
b1ab9ed8 A |
3 | * |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
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 | |
11 | * file. | |
12 | * | |
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. | |
20 | * | |
21 | * @APPLE_LICENSE_HEADER_END@ | |
22 | */ | |
23 | ||
24 | ||
25 | // | |
26 | // cfmach++ - a marriage of CoreFoundation with Mach/C++ | |
27 | // | |
28 | #include <security_utilities/cfmach++.h> | |
29 | ||
30 | ||
31 | namespace Security { | |
32 | namespace MachPlusPlus { | |
33 | ||
34 | ||
35 | // | |
36 | // Construct CFAutoPorts | |
37 | // | |
38 | CFAutoPort::CFAutoPort() | |
39 | : mEnabled(false) | |
40 | { } | |
41 | ||
42 | CFAutoPort::CFAutoPort(mach_port_t p) | |
43 | : Port(p), mEnabled(false) | |
44 | { } | |
45 | ||
46 | ||
47 | // | |
48 | // On destruction, make sure we're disengaged from the CFRunLoop | |
49 | // | |
50 | CFAutoPort::~CFAutoPort() | |
51 | { | |
52 | disable(); | |
53 | ||
54 | // invalidate everything | |
55 | if (mPort) | |
56 | { | |
57 | CFMachPortInvalidate(mPort); | |
58 | CFRunLoopSourceInvalidate(mSource); | |
59 | } | |
60 | } | |
61 | ||
62 | ||
63 | // | |
64 | // enable() will lazily allocate needed resources, then click into the runloop | |
65 | // | |
66 | void CFAutoPort::enable() | |
67 | { | |
68 | if (!mEnabled) { | |
69 | if (!*this) | |
70 | allocate(); | |
71 | if (!mPort) { | |
72 | // first-time creation of CF resources | |
73 | CFMachPortContext ctx = { 1, this, NULL, NULL, NULL }; | |
74 | CFMachPortRef machPort = CFMachPortCreateWithPort(NULL, port(), cfCallback, &ctx, NULL); | |
75 | if (machPort != NULL) | |
76 | { | |
77 | // using take here because "assignment" causes an extra retain, which will make the | |
78 | // CF objects leak when this data structure goes away. | |
79 | mPort.take(machPort); | |
80 | ||
81 | CFRunLoopSourceRef sr = CFMachPortCreateRunLoopSource(NULL, mPort, 10); | |
82 | mSource.take(sr); | |
83 | } | |
84 | if (!mPort || !mSource) | |
85 | CFError::throwMe(); // CF won't tell us why... | |
86 | } | |
87 | CFRunLoopAddSource(CFRunLoopGetCurrent(), mSource, kCFRunLoopCommonModes); | |
88 | mEnabled = true; | |
fa7225c8 | 89 | secinfo("autoport", "%p enabled", this); |
b1ab9ed8 A |
90 | } |
91 | } | |
92 | ||
93 | ||
94 | // | |
95 | // Disable() just removes us from the runloop. All the other resources stay | |
96 | // around, ready to be re-enable()d. | |
97 | // | |
98 | void CFAutoPort::disable() | |
99 | { | |
100 | if (mEnabled) { | |
101 | CFRunLoopRemoveSource(CFRunLoopGetCurrent(), mSource, kCFRunLoopCommonModes); | |
102 | mEnabled = false; | |
fa7225c8 | 103 | secinfo("autoport", "%p disabled", this); |
b1ab9ed8 A |
104 | } |
105 | } | |
106 | ||
107 | ||
108 | // | |
109 | // The CF-sponsored port callback. | |
110 | // We pass this to our receive() virtual and eat all exceptions. | |
111 | // | |
112 | static int gNumTimesCalled = 0; | |
113 | ||
114 | void CFAutoPort::cfCallback(CFMachPortRef cfPort, void *msg, CFIndex size, void *context) | |
115 | { | |
116 | ++gNumTimesCalled; | |
fa7225c8 | 117 | secinfo("adhoc", "Callback was called %d times.", gNumTimesCalled); |
427c49bc | 118 | |
427c49bc | 119 | Message message(msg, (mach_msg_size_t)size); |
b1ab9ed8 A |
120 | try { |
121 | reinterpret_cast<CFAutoPort *>(context)->receive(message); | |
122 | } catch (...) { | |
fa7225c8 | 123 | secinfo("autoport", "%p receive handler failed with exception", context); |
b1ab9ed8 A |
124 | } |
125 | } | |
126 | ||
127 | ||
128 | } // end namespace MachPlusPlus | |
129 | } // end namespace Security |