xref: /trueos/lib/libnotify/notify.3 (revision df708cfae8b36425e4c55a0170b15d8434283555)
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