1 /* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /* $Id: gsnotify.c,v 1.5 2002/06/16 05:48:55 lpd Exp $ */
18 /* Notification machinery implementation */
19 #include "gx.h"
20 #include "gserrors.h"
21 #include "gsstruct.h"
22 #include "gsnotify.h"
23
24 /* GC descriptors */
25 private_st_gs_notify_registration();
26 public_st_gs_notify_list();
27
28 /* Initialize a notification list. */
29 void
gs_notify_init(gs_notify_list_t * nlist,gs_memory_t * mem)30 gs_notify_init(gs_notify_list_t *nlist, gs_memory_t *mem)
31 {
32 nlist->first = 0;
33 nlist->memory = mem;
34 }
35
36 /* Register a client. */
37 int
gs_notify_register(gs_notify_list_t * nlist,gs_notify_proc_t proc,void * proc_data)38 gs_notify_register(gs_notify_list_t *nlist, gs_notify_proc_t proc,
39 void *proc_data)
40 {
41 gs_notify_registration_t *nreg =
42 gs_alloc_struct(nlist->memory, gs_notify_registration_t,
43 &st_gs_notify_registration, "gs_notify_register");
44
45 if (nreg == 0)
46 return_error(gs_error_VMerror);
47 nreg->proc = proc;
48 nreg->proc_data = proc_data;
49 nreg->next = nlist->first;
50 nlist->first = nreg;
51 return 0;
52 }
53
54 /*
55 * Unregister a client. Return 1 if the client was registered, 0 if not.
56 * If proc_data is 0, unregister all registrations of that proc; otherwise,
57 * unregister only the registration of that procedure with that proc_data.
58 */
59 private void
no_unreg_proc(void * pdata)60 no_unreg_proc(void *pdata)
61 {
62 }
63 int
gs_notify_unregister_calling(gs_notify_list_t * nlist,gs_notify_proc_t proc,void * proc_data,void (* unreg_proc)(void * pdata))64 gs_notify_unregister_calling(gs_notify_list_t *nlist, gs_notify_proc_t proc,
65 void *proc_data,
66 void (*unreg_proc)(void *pdata))
67 {
68 gs_notify_registration_t **prev = &nlist->first;
69 gs_notify_registration_t *cur;
70 bool found = 0;
71
72 while ((cur = *prev) != 0)
73 if (cur->proc == proc &&
74 (proc_data == 0 || cur->proc_data == proc_data)
75 ) {
76 *prev = cur->next;
77 unreg_proc(cur->proc_data);
78 gs_free_object(nlist->memory, cur, "gs_notify_unregister");
79 found = 1;
80 } else
81 prev = &cur->next;
82 return found;
83 }
84 int
gs_notify_unregister(gs_notify_list_t * nlist,gs_notify_proc_t proc,void * proc_data)85 gs_notify_unregister(gs_notify_list_t *nlist, gs_notify_proc_t proc,
86 void *proc_data)
87 {
88 return gs_notify_unregister_calling(nlist, proc, proc_data, no_unreg_proc);
89 }
90
91 /*
92 * Notify the clients on a list. If an error occurs, return the first
93 * error code, but notify all clients regardless.
94 */
95 int
gs_notify_all(gs_notify_list_t * nlist,void * event_data)96 gs_notify_all(gs_notify_list_t *nlist, void *event_data)
97 {
98 gs_notify_registration_t *cur;
99 gs_notify_registration_t *next;
100 int ecode = 0;
101
102 for (next = nlist->first; (cur = next) != 0;) {
103 int code;
104
105 next = cur->next;
106 code = cur->proc(cur->proc_data, event_data);
107 if (code < 0 && ecode == 0)
108 ecode = code;
109 }
110 return ecode;
111 }
112
113 /* Release a notification list. */
114 void
gs_notify_release(gs_notify_list_t * nlist)115 gs_notify_release(gs_notify_list_t *nlist)
116 {
117 gs_memory_t *mem = nlist->memory;
118
119 while (nlist->first) {
120 gs_notify_registration_t *next = nlist->first->next;
121
122 gs_free_object(mem, nlist->first, "gs_notify_release");
123 nlist->first = next;
124 }
125 }
126