1.\" Copyright (c) 2003-2014 Apple Inc. All rights reserved. 2.\" 3.\" @APPLE_LICENSE_HEADER_START@ 4.\" 5.\" Portions Copyright (c) 2003-2010 Apple Inc. All Rights Reserved. 6.\" 7.\" This file contains Original Code and/or Modifications of Original Code 8.\" as defined in and that are subject to the Apple Public Source License 9.\" Version 2.0 (the 'License'). You may not use this file except in 10.\" compliance with the License. Please obtain a copy of the License at 11.\" http://www.opensource.apple.com/apsl/ and read it before using this 12.\" file. 13.\" 14.\" The Original Code and all software distributed under the License are 15.\" distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18.\" FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 19.\" Please see the License for the specific language governing rights and 20.\" limitations under the License. 21.\" 22.\" @APPLE_LICENSE_HEADER_END@ 23.\" 24.\" 25.Dd September 3, 2008 26.Dt notify 3 27.Os "Mac OS X" 28.Sh NAME 29.Nm notify_post , 30.Nm notify_register_check , 31.Nm notify_register_dispatch , 32.Nm notify_register_signal , 33.Nm notify_register_mach_port , 34.Nm notify_register_file_descriptor , 35.Nm notify_check , 36.Nm notify_get_state , 37.Nm notify_set_state , 38.Nm notify_suspend , 39.Nm notify_resume , 40.Nm notify_cancel , 41.Nm notify_is_valid_token 42.Nd event distribution functions 43.Sh SYNOPSIS 44.Fd #include <notify.h> 45.Ft uint32_t 46.Fn notify_post "const char *name" 47.Ft uint32_t 48.Fn notify_register_check "const char *name, int *out_token" 49.Ft uint32_t 50.Fn notify_register_dispatch "const char *name, int *out_token" "dispatch_queue_t queue" "notify_handler_t handler" 51.Ft uint32_t 52.Fn notify_register_signal "const char *name, int sig, int *out_token" 53.Ft uint32_t 54.Fn notify_register_mach_port "const char *name, mach_port_t *notify_port, int flags, int *out_token" 55.Ft uint32_t 56.Fn notify_register_file_descriptor "const char *name, int *notify_fd, int flags, int *out_token" 57.Ft uint32_t 58.Fn notify_check "int token, int *check" 59.Ft uint32_t 60.Fn notify_set_state "int token, uint64_t state" 61.Ft uint32_t 62.Fn notify_get_state "int token, uint64_t *state" 63.Ft uint32_t 64.Fn notify_suspend "int token" 65.Ft uint32_t 66.Fn notify_resume "int token" 67.Ft uint32_t 68.Fn notify_cancel "int token" 69.Ft bool 70.Fn notify_is_valid_token "int val" 71.Sh DESCRIPTION 72These routines allow processes to exchange stateless notification events. 73Processes post notifications to a single system-wide notification server, 74which then distributes notifications to client processes that have 75registered to receive those notifications, including processes run by 76other users. 77.Pp 78Notifications are associated with names in a namespace shared by all 79clients of the system. 80Clients may post notifications for names, and 81may monitor names for posted notifications. 82Clients may request 83notification delivery by a number of different methods. 84.Pp 85Clients desiring to monitor names in the notification system must 86register with the system, providing a name and other information 87required for the desired notification delivery method. 88Clients are 89given an integer token representing the registration. 90Token values are zero or positive integers. 91.Pp 92The kernel provides limited queues for mach message and file descriptor messages. 93It is important to make sure that clients read mach ports and file descriptors frequently 94to prevent messages from being lost due to resource limitations. 95Clients that use signal-based notification should be aware that signals 96are not delivered to a process while it is running in a signal handler. 97This may affect the delivery of signals in close succession. 98.Pp 99Notifications may be coalesced in some cases. 100Multiple events posted 101for a name in rapid succession may result in a single notification sent 102to clients registered for notification for that name. 103Clients checking 104for changes using the notify_check() routine cannot determine if 105more than one event has been posted since a previous call to 106notify_check() for that name. 107.Pp 108"False positives" may occur in notify_check() when used with a token 109generated by notify_register_check() due to implementation constraints. 110This behavior may vary in future releases. 111.Ss notify_post 112This routine causes the system to send a notification for the given 113name to all clients that have registered for notifications of this name. 114This is the only API required for an application that only produces 115notifications. 116.Ss notify_register_check 117Registers for passive notification for the given name. 118The routine generates 119a token that may be used with the 120.Fn notify_check 121routine to check if any notifications have been posted for the name. 122The check is implemented using a shared memory scheme, making the check 123very fast and efficient. 124The implementation has a limited amount 125of shared memory, so developers are encouraged to use this mechanism 126sparingly. 127It is also important to release the resources consumed 128by a registration with 129.Fn notify_cancel 130when they are no longer required by the application. 131.Ss notify_register_dispatch 132registers a callback handler in the form of a block which will be 133dispatched to the queue when a notification for the given name is 134received. This is a convenient way to register callbacks without any 135management of file descriptors, mach ports, or signals on the part of 136the application. The given queue is retained by the system for the 137lifetime of the notification. Use 138.Fn notify_cancel 139to release the notification and its reference to the queue. 140.Ss notify_register_signal 141registers a client for notification delivery via a signal. 142This fits 143well with the design of many UNIX daemons that use a signal such as SIGHUP 144to reinitialize of reset internal state information. 145Clients may use the 146registration token generated by this routine to check for notifications using 147.Fn notify_check . 148This allows the application to determine if a signal was received as the 149result of a notification, or if the signal was generated by some other source. 150It also permits the application that registers for signal notification for 151multiple names to determine which name was associated with the notification. 152.Ss notify_register_mach_port 153registers a client for notification delivery via mach messaging. 154Notifications are delivered by an empty message sent to a mach port. 155By default, a new port is created by a call to this routine. 156A mach port 157previously created by a call to this routine may be used for notifications 158if a pointer to that port is passed in to the routine and NOTIFY_REUSE is 159set in the flags parameter. 160The notification service must be able to extract 161send rights to the port. 162.Pp 163Note that the kernel limits the size of the message queue for any port. 164If it is important that notifications should not be lost due to queue 165overflow, clients should service messages quickly, and be cautious in 166using the same port for notifications for more than one name. 167.Pp 168A notification message has an empty message body. 169The msgh_id field 170in the mach message header will have the value of the notification 171token. 172If a port is reused for multiple notification registrations, 173the msgh_id value may be used to determine which name generated 174the notification. 175.Ss notify_register_file_descriptor 176Register for notification by a write to a file descriptor. 177.Pp 178By default, a new file descriptor is created and a pointer to it 179is returned as the value of the "notify_fd" parameter. 180A file descriptor 181created by a previous call to this routine may be used for notifications 182if a pointer to that file descriptor is passed in to the routine and 183NOTIFY_REUSE is set in the flags parameter. 184.Pp 185Note that the kernel limits the buffer space for queued writes on a 186file descriptor. 187If it is important that notifications should not be 188lost due to queue overflow, clients should service messages quickly, 189and be cautious in using the same file descriptor for notifications 190for more than one name. 191.Pp 192Notifications are delivered by an integer value written to the 193file descriptor. 194The value is sent in network byte order. 195When converted to host byte order, for example by using 196.Fn ntohl , 197it will match the notification token 198for which the notification was generated. 199.Ss notify_check 200Checks if any notifications have been posted for a name. 201The output 202parameter "check" is set to 0 for false, 1 for true. 203A true indication is 204returned the first time notify_check is called for a token. 205Subsequent calls 206give a true indication when notifications have been posted for the name 207associated with the notification token. 208.Pp 209.Fn notify_check 210may be used with any notification token produced by any of the notification 211registration routines. 212A fast check based on a shared memory implementation 213is used when the token was generated by 214.Fn notify_register_check . 215Other tokens are checked by a call to the notification server. 216.Ss notify_set_state 217Set a 64-bit unsigned integer variable associated with a token. 218.Pp 219Each registered notification key has an associated 64-bit integer variable, 220which may be set using this routine and examined using the 221.Fn notify_get_state 222routine. 223The state variable is free to be used by clients of the notification API. 224It may be used to synchronize state information between cooperating processes or threads. 225(Available in Mac OS X 10.5 or later.) 226.Ss notify_get_state 227Get the 64-bit unsigned integer value associated with a token. 228The default value of a state variable is zero. 229(Available in Mac OS X 10.5 or later.) 230.Ss notify_suspend 231Suspends delivery of notifications for a notification token. 232Any notifications corresponding to a token that are posted while it is suspended 233will be coalesced, and pended until notifications are resumed using 234.Fn notify_resume . 235.Pp 236Calls to 237.Fn notify_suspend 238may be nested. 239Notifications will resume only when a matching number of calls are made to 240.Fn notify_resume . 241.Ss notify_resume 242Removes one level of suspension for a token previously suspended by a call to 243.Fn notify_suspend . 244When resumed, notifications will be delivered normally. 245A single notification will be generated if any notifications were pended while the token was suspended. 246.Ss notify_cancel 247Cancel notification and free resources associated with a notification 248token. 249Mach ports and file descriptor associated with a token are released 250(deallocated or closed) when all registration tokens associated with 251the port or file descriptor have been cancelled. 252.Pp 253.Ss notify_is_valid_token 254Determines if an integer value is valid for a current registration. 255Negative integers are never valid. 256A positive or zero value is valid if the current process has a registration associated with the given value. 257.Sh NAMESPACE CONVENTIONS 258Names in the namespace must be NULL-terminated. 259Names should be encoded as UTF-8 strings. 260.Pp 261The namespace supported by the system is unstructured, but users of 262this API are highly encouraged to follow the reverse-ICANN domain 263name convention used for Java package names and for System Preferences 264on Mac OS X. 265For example, "com.mydomain.example.event". 266.Pp 267Apple reserves the portion 268of the namespace prefixed by "com.apple.". 269This policy is not 270enforced in the current implementation, but may be in the future. 271.Pp 272Names in the space "user.uid.UID", where UID is a numeric user ID number 273are reserved for processes with that UID. 274Names in this protected space may only be accessed or modified by processes 275with the effective UID specified as the UID in the name. 276The name "user.uid.UID" is protected for the given UID, as are any 277names of the form "user.uid.UID.<sub-path>". 278In the latter case, the name must have a dot character following the UID. 279.Pp 280Third party developers are encouraged to choose a prefix for names 281that will avoid conflicts in the shared namespace. 282.Pp 283The portion of the namespace prefixed by the string "self." is set aside 284for private use by applications. 285That is, each client may use that part 286of the namespace for intra-process notifications. 287These notifications 288are private to each individual process and are not propagated between 289processes. 290.Sh USAGE EXAMPLES 291A notification producer. 292.Pp 293 #include <notify.h> 294 ... 295.Pp 296 notify_post("com.eg.random.event"); 297.Pp 298A client using notify_check() to determine when to invalidate a cache. 299.Pp 300 #include <stdio.h> 301 #include <stdlib.h> 302 #include <notify.h> 303.Pp 304 int 305 main(int argc, char *argv[]) 306 { 307 uint32_t status; 308 int token, check; 309.Pp 310 status = notify_register_check("com.eg.update", &token); 311 if (status != NOTIFY_STATUS_OK) 312 { 313 fprintf(stderr, "registration failed (%u)\\n", status); 314 exit(status); 315 } 316.Pp 317 build_my_cache(); 318.Pp 319 ... 320.Pp 321 status = notify_check(token, &check); 322 if ((status == NOTIFY_STATUS_OK) && (check != 0)) 323 { 324 /* An update has occurred - invalidate the cache */ 325 reset_my_cache(); 326 } 327.Pp 328 ... 329.Pp 330A client using file descriptor notifications. 331.Pp 332 #include <stdio.h> 333 #include <stdlib.h> 334 #include <string.h> 335 #include <errno.h> 336 #include <sys/types.h> 337 #include <sys/time.h> 338 #include <unistd.h> 339 #include <notify.h> 340.Pp 341 int 342 main(int argc, char *argv[]) 343 { 344 uint32_t status; 345 int nf, rtoken, qtoken, t, ret; 346 fd_set readfds; 347.Pp 348 status = notify_register_file_descriptor("com.eg.random.event", 349 &nf, 0, &rtoken); 350 if (status != NOTIFY_STATUS_OK) 351 { 352 fprintf(stderr, "registration failed (%u)\\n", status); 353 exit(status); 354 } 355.Pp 356 status = notify_register_file_descriptor("com.eg.random.quit", 357 &nf, NOTIFY_REUSE, &qtoken); 358 if (status != NOTIFY_STATUS_OK) 359 { 360 fprintf(stderr, "registration failed (%u)\\n", status); 361 exit(status); 362 } 363.Pp 364 FD_ZERO(&readfds); 365 FD_SET(nf, &readfds); 366.Pp 367 for (;;) 368 { 369 ret = select(nf+1, &readfds, NULL, NULL, NULL); 370 if (ret <= 0) continue; 371 if (!FD_ISSET(nf, &readfds)) continue; 372.Pp 373 status = read(nf, &t, sizeof(int)); 374 if (status < 0) 375 { 376 perror("read"); 377 break; 378 } 379.Pp 380 t = ntohl(t); 381.Pp 382 if (t == rtoken) printf("random event\\n"); 383 else if (t == qtoken) break; 384 } 385.Pp 386 printf("shutting down\\n"); 387 notify_cancel(rtoken); 388 notify_cancel(qtoken); 389 exit(0); 390 } 391.Pp 392A client using dispatch notifications. 393.Pp 394 #include <stdio.h> 395 #include <stdlib.h> 396 #include <notify.h> 397 #include <dispatch/dispatch.h> 398.Pp 399 int 400 main(void) 401 { 402 uint32_t status; 403 int token; 404.Pp 405 status = notify_register_dispatch("com.eg.random.event", &token, 406 dispatch_get_main_queue(), ^(int t) { 407 printf("com.eg.random.event received!\\n"); }); 408.Pp 409 dispatch_main(); 410 exit(0); 411 } 412.Sh HISTORY 413These functions first appeared in 414Mac OS X 10.3. 415.Sh SEE ALSO 416.Xr ntohl 3 , 417.Xr read 2 , 418.Xr select 2 , 419.Xr signal 3 420