]> git.saurik.com Git - apple/security.git/blob - SecurityServer/eventlistener.cpp
Security-177.tar.gz
[apple/security.git] / SecurityServer / eventlistener.cpp
1 #include "eventlistener.h"
2
3
4 namespace Security {
5 namespace SecurityServer {
6
7 EventListener::EventListener (CssmAllocator &standard, CssmAllocator &returning) : mClientSession (standard, returning),
8 mMachPortRef (NULL),
9 mRunLoopSourceRef (NULL)
10
11 {
12 Initialize ();
13 }
14
15
16
17 EventListener::~EventListener ()
18 {
19 if (mMachPortRef != NULL)
20 {
21 mach_port_t mp = CFMachPortGetPort (mMachPortRef);
22 mClientSession.stopNotification (mp);
23 CFRelease (mMachPortRef);
24 }
25
26 if (mRunLoopSourceRef != NULL)
27 {
28 CFRelease (mRunLoopSourceRef);
29 }
30 }
31
32
33
34 void EventListener::Callback (CFMachPortRef port, void *msg, CFIndex size, void *info)
35 {
36 reinterpret_cast<EventListener*>(info)->HandleCallback (port, msg, size);
37 }
38
39
40
41 void EventListener::Initialize ()
42 {
43 // create a callback information structure
44 CFMachPortContext context = {1, this, NULL, NULL, NULL};
45
46 // create the CFMachPort
47 mMachPortRef = CFMachPortCreate (NULL, Callback, &context, NULL);
48 if (mMachPortRef == NULL)
49 {
50 return;
51 }
52
53 // set the buffer limit for the port
54 mach_port_t mp = CFMachPortGetPort (mMachPortRef);
55
56 mach_port_limits_t limits;
57 limits.mpl_qlimit = MACH_PORT_QLIMIT_MAX;
58 kern_return_t result =
59 mach_port_set_attributes (mach_task_self (), mp, MACH_PORT_LIMITS_INFO,
60 mach_port_info_t (&limits), MACH_PORT_LIMITS_INFO_COUNT);
61
62 if (result != KERN_SUCCESS)
63 {
64 secdebug ("notify", "Got error %d when trying to maximize queue size", result);
65 }
66
67 // make a run loop source for this ref
68 mRunLoopSourceRef = CFMachPortCreateRunLoopSource (NULL, mMachPortRef, NULL);
69 if (mRunLoopSourceRef == NULL)
70 {
71 CFRelease (mMachPortRef);
72 return;
73 }
74
75 // attach this run loop source to the main run loop
76 CFRunLoopAddSource (CFRunLoopGetCurrent (), mRunLoopSourceRef, kCFRunLoopDefaultMode);
77
78 // extract the actual port from the run loop, and request callbacks on that port
79 mClientSession.requestNotification (mp, Listener::databaseNotifications,
80 Listener::allEvents);
81 }
82
83
84
85 void EventListener::HandleCallback (CFMachPortRef port, void *msg, CFIndex size)
86 {
87 // we need to parse the message and see what happened
88 mClientSession.dispatchNotification (reinterpret_cast<mach_msg_header_t *>(msg), ProcessMessage, this);
89 }
90
91
92
93 OSStatus EventListener::ProcessMessage (Listener::Domain domain, Listener::Event event, const void *data, size_t dataLength, void *context)
94 {
95 reinterpret_cast<EventListener*>(context)->EventReceived (domain, event, data, dataLength);
96 return noErr;
97 }
98
99
100
101 void EventListener::RequestEvents (Listener::Domain whichDomain, Listener::EventMask whichEvents)
102 {
103 // stop the old event request and change to the new one
104 mach_port_t mp = CFMachPortGetPort (mMachPortRef);
105 mClientSession.stopNotification (mp);
106 mClientSession.requestNotification (mp, whichDomain, whichEvents);
107 }
108
109
110
111 void EventListener::EventReceived (Listener::Domain domain, Listener::Event event, const void* data, size_t dataLength)
112 {
113 }
114
115
116
117 };
118 };