1/*
2 * Copyright (c) 2003-2010 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 2003-2010 Apple Inc.  All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25
26#ifndef __NOTIFICATION_H__
27#define __NOTIFICATION_H__
28
29#include <sys/cdefs.h>
30#include <stdint.h>
31#include <mach/message.h>
32#include <Availability.h>
33#ifdef __BLOCKS__
34#include <dispatch/dispatch.h>
35#endif /* __BLOCKS__ */
36
37/*! @header
38 * These routines allow processes to exchange stateless notification events.
39 * Processes post notifications to a single system-wide notification server,
40 * which then distributes notifications to client processes that have
41 * registered to receive those notifications, including processes run by
42 * other users.
43 *
44 * Notifications are associated with names in a namespace shared by all
45 * clients of the system.  Clients may post notifications for names, and
46 * may monitor names for posted notifications.  Clients may request
47 * notification delivery by a number of different methods.
48 *
49 * Clients desiring to monitor names in the notification system must
50 * register with the system, providing a name and other information
51 * required for the desired notification delivery method.  Clients are
52 * given an integer token representing the registration.
53 *
54 * Note that the kernel provides limited queues for mach message and file
55 * descriptor messages.  It is important to make sure that clients read
56 * mach ports and file descriptors frequently to prevent messages from
57 * being lost due to resource limitations.  Clients that use signal-based
58 * notification should be aware that signals are not delivered to
59 * a process while it is running in a signal handler.  This may affect
60 * the delivery of signals in close succession.
61 *
62 * Notifications may be coalesced in some cases.  Multiple events posted
63 * for a name in rapid succession may result in a single notification sent
64 * to clients registered for notification for that name.  Clients checking
65 * for changes using the notify_check() routine cannot determine if
66 * more than one event pas been posted since a previous call to
67 * notify_check() for that name.
68 *
69 * "False positives" may occur in notify_check() when used with a token
70 * generated by notify_register_check() due to implementation constraints.
71 * This behavior may vary in future releases.
72 *
73 * Synchronization between two processes may be achieved using the
74 * notify_set_state() and notify_get_state() routines.
75 */
76
77/*! @defineblock Status Codes
78 * Status codes returned by the API.
79 */
80#define NOTIFY_STATUS_OK 0
81#define NOTIFY_STATUS_INVALID_NAME 1
82#define NOTIFY_STATUS_INVALID_TOKEN 2
83#define NOTIFY_STATUS_INVALID_PORT 3
84#define NOTIFY_STATUS_INVALID_FILE 4
85#define NOTIFY_STATUS_INVALID_SIGNAL 5
86#define NOTIFY_STATUS_INVALID_REQUEST 6
87#define NOTIFY_STATUS_NOT_AUTHORIZED 7
88#define NOTIFY_STATUS_FAILED 1000000
89/*! @/defineblock */
90
91/*!
92 * Flag bits used for registration.
93 */
94#define NOTIFY_REUSE 0x00000001
95
96
97/*!
98 * Token values are zero or positive integers.
99 * NOTIFY_TOKEN_INVALID is useful as an initial value for
100 * a token value passed as an in/out parameter to one of
101 * the registration routines below.
102 */
103#define NOTIFY_TOKEN_INVALID -1
104
105__BEGIN_DECLS
106
107/*!
108 * Post a notification for a name.
109 *
110 * This is the only call that is required for a notification producer.
111 * Returns status.
112 */
113uint32_t notify_post(const char *name);
114
115
116#ifdef __BLOCKS__
117typedef void (^notify_handler_t)(int token);
118
119/*!
120 * @function   notify_register
121 * @abstract   Request notification delivery to a dispatch queue.
122 * @discussion When notifications are received by the process, the notify
123 *             subsystem will deliver the registered Block to the target
124 *             dispatch queue.  Notification blocks are not re-entrant,
125 *             and subsequent notification Blocks will not be delivered
126 *             for the same registration until the previous Block has
127 *             returned.
128 * @param name (input) The notification name.
129 * @param out_token (output) The registration token.
130 * @param queue (input) The dispatch queue to which the Block is submitted.
131 *              The dispatch queue is retained by the notify subsystem while
132 *              the notification is registered, and will be released when
133 *              notification is canceled.
134 * @param block (input) The Block to invoke on the dispatch queue in response
135 *              to a notification.  The notification token is passed to the
136 *              Block as an argument so that the callee can modify the state
137 *              of the notification or cancel the registration.
138 * @result Returns status.
139 */
140uint32_t notify_register_dispatch(const char *name, int *out_token, dispatch_queue_t queue, notify_handler_t handler)
141__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_3_2);
142#endif /* __BLOCKS__ */
143
144/*!
145 * Creates a registration token be used with notify_check(),
146 * but no active notifications will be delivered.
147 *
148 * @param name
149 *    (input) notification name
150 * @param out_token
151 *    (output) registration token
152 * @result Returns status.
153 */
154uint32_t notify_register_check(const char *name, int *out_token);
155
156/*!
157 * Request notification delivery by UNIX signal.
158 *
159 * A client may request signal notification for multiple names.  After a signal
160 * is delivered, the notify_check() routine may be called with each notification
161 * token to determine which name (if any) generated the signal notification.
162 *
163 * @param name (input) notification name
164 * @param sig (input) signal number (see signal(3))
165 * @param out_token (output) notification token
166 * @result Returns status.
167 */
168uint32_t notify_register_signal(const char *name, int sig, int *out_token);
169
170/*!
171 * Request notification by mach message.
172 *
173 * Notifications are delivered by an empty message sent to a mach port.
174 * By default, a new port is allocated and a pointer to it is returned
175 * as the value of "notify_port".  A mach port previously returned by a
176 * call to this routine may be used for notifications if a pointer to that
177 * port is passed in to the routine and NOTIFY_REUSE is set in the flags
178 * parameter.  The notification service must be able to extract send
179 * rights to the port.
180 *
181 * Note that the kernel limits the size of the message queue for any port.
182 * If it is important that notifications should not be lost due to queue
183 * overflow, clients should service messages quickly, and be careful about
184 * using the same port for notifications for more than one name.
185 *
186 * A notification message has an empty message body.  The msgh_id field
187 * in the mach message header will have the value of the notification
188 * token.  If a port is reused for multiple notification registrations,
189 * the msgh_id value may be used to determine which name generated
190 * the notification.
191 *
192 * @param name
193 *     (input) notification name
194 * @param  out_token
195 *     (output) notification token
196 * @param  notify_port
197 *     (input/output) pointer to a mach port
198 * @result Returns status.
199 */
200uint32_t notify_register_mach_port(const char *name, mach_port_t *notify_port, int flags, int *out_token);
201
202/*
203 * Request notification by a write to a file descriptor.
204 *
205 * Notifications are delivered by a write to a file descriptor.
206 * By default, a new file descriptor is created and a pointer to it
207 * is returned as the value of "notify_fd".  A file descriptor created
208 * by a previous call to this routine may be used for notifications if
209 * a pointer to that file descriptor is passed in to the routine and
210 * NOTIFY_REUSE is set in the flags parameter.
211 *
212 * Note that the kernel limits the buffer space for queued writes on a
213 * file descriptor.  If it is important that notifications should not be
214 * lost due to queue overflow, clients should service messages quickly,
215 * and be careful about using the same file descriptor for notifications
216 * for more than one name.
217 *
218 * Notifications are delivered by an integer value written to the
219 * file descriptor.  The value will match the notification token
220 * for which the notification was generated.
221 *
222 * @param name
223 *     (input) notification name
224 * @param out_token
225 *     (output) notification token
226 * @param notify_fd
227 *     (input/output) pointer to a file descriptor
228 * @result Returns status.
229 */
230uint32_t notify_register_file_descriptor(const char *name, int *notify_fd, int flags, int *out_token);
231
232/*!
233 * Check if any notifications have been posted.
234 *
235 * Output parameter check is set to 0 for false, 1 for true.  Returns status.
236 * check is set to true the first time notify_check is called for a token.
237 * Subsequent calls set check to true when notifications have been posted for
238 * the name associated with the notification token.  This routine is independent
239 * of notify_post().  That is, check will be true if an application calls
240 * notify_post() for a name and then calls notify_check() for a token associated
241 * with that name.
242 *
243 * @param token
244 *     (input)notification token
245 * @param check
246 *     (output) true/false indication
247 * @result Returns status.
248 */
249uint32_t notify_check(int token, int *check);
250
251/*!
252 * Cancel notification and free resources associated with a notification
253 * token.  Mach ports and file descriptor associated with a token are released
254 * (deallocated or closed) when all registration tokens associated with
255 * the port or file descriptor have been cancelled.
256 *
257 * @param token
258 *     (input) notification token
259 * @result Returns status.
260 */
261uint32_t notify_cancel(int token);
262
263/*!
264 * Suspend delivery of notifications for a token. Notifications for this token will be
265 * pended and coalesced, then delivered following a matching call to notify_resume.
266 * Calls to notify_suspend may be nested.  Notifications remain suspended until
267 * an equal number of calls have been made to notify_resume.
268 *
269 * @param token
270 *     (input) notification token
271 * @result Returns status.
272 */
273uint32_t notify_suspend(int token)
274__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0);
275
276/*!
277 * Removes one level of suspension for a token previously suspended
278 * by a call to notify_suspend.  Notifications will resume when a matching
279 * call to notify_resume is made for each previous call to notify_suspend.
280 * Notifications posted while a token is suspended are coalesced into
281 * a single notification sent following a resumption.
282 *
283 * @param token
284 *     (input) notification token
285 * @result Returns status.
286 */
287uint32_t notify_resume(int token)
288__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0);
289
290/*!
291 * Set or get a state value associated with a notification token.
292 * Each key in the notification namespace has an associated integer value available
293 * for use by clients as for application-specific purposes.  A common usage is to
294 * allow two processes or threads to synchronize their activities.  For example, a
295 * server process may need send a notification when a resource becomes available.
296 * A client process can register for the notification, but when it starts up it will
297 * not know whether the resource is available.  The server can set the state value,
298 * and the client can check the value at startup time to synchronize with the server.
299 *
300 * Set the 64-bit integer state value.
301 *
302 * @param token
303 *     (input) notification token
304 * @param state64
305 *     (input) 64-bit unsigned integer value
306 * @result Returns status.
307 */
308uint32_t notify_set_state(int token, uint64_t state64)
309__OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
310
311/*!
312 * Get the 64-bit integer state value.
313 *
314 * @param token
315 *     (input) notification token
316 * @param state64
317 *     (output) 64-bit unsigned integer value
318 * @result Returns status.
319 */
320uint32_t notify_get_state(int token, uint64_t *state64)
321__OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);
322
323/*!
324 * Determine if a token is valid (currently registered).
325 * Negative integer values are always invalid.  Positive or
326 * zero values are valid only if they are associated with an
327 * existing registratiom.
328 *
329 * @param val
330 *     (input) integer value
331 * @result Returns true if the value is a valid token, false otherwise.
332 */
333bool notify_is_valid_token(int val)
334__OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0);
335
336__END_DECLS
337
338#endif /* __NOTIFICATION_H__ */
339