/src/ghostpdl/base/gsnotify.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2001-2023 Artifex Software, Inc. |
2 | | All Rights Reserved. |
3 | | |
4 | | This software is provided AS-IS with no warranty, either express or |
5 | | implied. |
6 | | |
7 | | This software is distributed under license and may not be copied, |
8 | | modified or distributed except as expressly authorized under the terms |
9 | | of the license contained in the file LICENSE in this distribution. |
10 | | |
11 | | Refer to licensing information at http://www.artifex.com or contact |
12 | | Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, |
13 | | CA 94129, USA, for further information. |
14 | | */ |
15 | | |
16 | | |
17 | | /* Notification machinery implementation */ |
18 | | #include "gx.h" |
19 | | #include "gserrors.h" |
20 | | #include "gsstruct.h" |
21 | | #include "gsnotify.h" |
22 | | |
23 | | /* GC descriptors */ |
24 | | private_st_gs_notify_registration(); |
25 | | public_st_gs_notify_list(); |
26 | | |
27 | | /* Initialize a notification list. */ |
28 | | void |
29 | | gs_notify_init(gs_notify_list_t *nlist, gs_memory_t *mem) |
30 | 2.23M | { |
31 | 2.23M | nlist->first = 0; |
32 | 2.23M | nlist->memory = mem; |
33 | 2.23M | } |
34 | | |
35 | | /* Register a client. */ |
36 | | int |
37 | | gs_notify_register(gs_notify_list_t *nlist, gs_notify_proc_t proc, |
38 | | void *proc_data) |
39 | 1.16M | { |
40 | 1.16M | gs_notify_registration_t *nreg = |
41 | 1.16M | gs_alloc_struct(nlist->memory, gs_notify_registration_t, |
42 | 1.16M | &st_gs_notify_registration, "gs_notify_register"); |
43 | | |
44 | 1.16M | if (nreg == 0) |
45 | 0 | return_error(gs_error_VMerror); |
46 | 1.16M | nreg->proc = proc; |
47 | 1.16M | nreg->proc_data = proc_data; |
48 | 1.16M | nreg->next = nlist->first; |
49 | 1.16M | nlist->first = nreg; |
50 | 1.16M | return 0; |
51 | 1.16M | } |
52 | | |
53 | | /* |
54 | | * Unregister a client. Return 1 if the client was registered, 0 if not. |
55 | | * If proc_data is 0, unregister all registrations of that proc; otherwise, |
56 | | * unregister only the registration of that procedure with that proc_data. |
57 | | */ |
58 | | static void |
59 | | no_unreg_proc(void *pdata) |
60 | 38.7k | { |
61 | 38.7k | } |
62 | | int |
63 | | gs_notify_unregister_calling(gs_notify_list_t *nlist, gs_notify_proc_t proc, |
64 | | void *proc_data, |
65 | | void (*unreg_proc)(void *pdata)) |
66 | 38.7k | { |
67 | 38.7k | gs_notify_registration_t **prev = &nlist->first; |
68 | 38.7k | gs_notify_registration_t *cur; |
69 | 38.7k | bool found = 0; |
70 | | |
71 | 114k | while ((cur = *prev) != 0) |
72 | 75.4k | if (cur->proc == proc && |
73 | 75.4k | (proc_data == 0 || cur->proc_data == proc_data) |
74 | 75.4k | ) { |
75 | 38.7k | *prev = cur->next; |
76 | 38.7k | unreg_proc(cur->proc_data); |
77 | 38.7k | gs_free_object(nlist->memory, cur, "gs_notify_unregister"); |
78 | 38.7k | found = 1; |
79 | 38.7k | } else |
80 | 36.7k | prev = &cur->next; |
81 | 38.7k | return found; |
82 | 38.7k | } |
83 | | int |
84 | | gs_notify_unregister(gs_notify_list_t *nlist, gs_notify_proc_t proc, |
85 | | void *proc_data) |
86 | 38.7k | { |
87 | 38.7k | return gs_notify_unregister_calling(nlist, proc, proc_data, no_unreg_proc); |
88 | 38.7k | } |
89 | | |
90 | | /* |
91 | | * Notify the clients on a list. If an error occurs, return the first |
92 | | * error code, but notify all clients regardless. |
93 | | */ |
94 | | int |
95 | | gs_notify_all(gs_notify_list_t *nlist, void *event_data) |
96 | 1.36M | { |
97 | 1.36M | gs_notify_registration_t *cur; |
98 | 1.36M | gs_notify_registration_t *next; |
99 | 1.36M | int ecode = 0; |
100 | | |
101 | 2.52M | for (next = nlist->first; (cur = next) != 0;) { |
102 | 1.16M | int code; |
103 | | |
104 | 1.16M | next = cur->next; |
105 | 1.16M | code = cur->proc(cur->proc_data, event_data); |
106 | 1.16M | if (code < 0 && ecode == 0) |
107 | 0 | ecode = code; |
108 | 1.16M | } |
109 | 1.36M | return ecode; |
110 | 1.36M | } |
111 | | |
112 | | /* Release a notification list. */ |
113 | | void |
114 | | gs_notify_release(gs_notify_list_t *nlist) |
115 | 1.36M | { |
116 | 1.36M | gs_memory_t *mem = nlist->memory; |
117 | | |
118 | 2.48M | while (nlist->first) { |
119 | 1.12M | gs_notify_registration_t *next = nlist->first->next; |
120 | | |
121 | 1.12M | gs_free_object(mem, nlist->first, "gs_notify_release"); |
122 | 1.12M | nlist->first = next; |
123 | 1.12M | } |
124 | 1.36M | } |