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