1 /* ccapi/server/ccs_client.c */
2 /*
3 * Copyright 2006 Massachusetts Institute of Technology.
4 * All Rights Reserved.
5 *
6 * Export of this software from the United States of America may
7 * require a specific license from the United States Government.
8 * It is the responsibility of any person or organization contemplating
9 * export to obtain such a license before exporting.
10 *
11 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
12 * distribute this software and its documentation for any purpose and
13 * without fee is hereby granted, provided that the above copyright
14 * notice appear in all copies and that both that copyright notice and
15 * this permission notice appear in supporting documentation, and that
16 * the name of M.I.T. not be used in advertising or publicity pertaining
17 * to distribution of the software without specific, written prior
18 * permission. Furthermore if you modify this software you must label
19 * your software as modified software and not distribute it in such a
20 * fashion that it might be confused with the original M.I.T. software.
21 * M.I.T. makes no representations about the suitability of
22 * this software for any purpose. It is provided "as is" without express
23 * or implied warranty.
24 */
25
26 #include "ccs_common.h"
27
28 struct ccs_client_d {
29 ccs_pipe_t client_pipe;
30
31 /* The following arrays do not own their contents */
32 ccs_callbackref_array_t callbacks;
33 ccs_iteratorref_array_t iterators;
34 };
35
36 struct ccs_client_d ccs_client_initializer = { CCS_PIPE_NULL, NULL, NULL };
37
38 /* ------------------------------------------------------------------------ */
39
ccs_client_new(ccs_client_t * out_client,ccs_pipe_t in_client_pipe)40 cc_int32 ccs_client_new (ccs_client_t *out_client,
41 ccs_pipe_t in_client_pipe)
42 {
43 cc_int32 err = ccNoError;
44 ccs_client_t client = NULL;
45
46 if (!out_client ) { err = cci_check_error (ccErrBadParam); }
47 if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
48
49 if (!err) {
50 client = malloc (sizeof (*client));
51 if (client) {
52 *client = ccs_client_initializer;
53 } else {
54 err = cci_check_error (ccErrNoMem);
55 }
56 }
57
58 if (!err) {
59 err = ccs_callbackref_array_new (&client->callbacks);
60 }
61
62 if (!err) {
63 err = ccs_iteratorref_array_new (&client->iterators);
64 }
65
66 if (!err) {
67 err = ccs_pipe_copy (&client->client_pipe, in_client_pipe);
68 }
69
70 if (!err) {
71 *out_client = client;
72 client = NULL;
73 }
74
75 ccs_client_release (client);
76
77 return cci_check_error (err);
78 }
79
80 /* ------------------------------------------------------------------------ */
81
ccs_client_release(ccs_client_t io_client)82 cc_int32 ccs_client_release (ccs_client_t io_client)
83 {
84 cc_int32 err = ccNoError;
85
86 if (!err && io_client) {
87 cc_uint64 i;
88 cc_uint64 callback_count = ccs_callbackref_array_count (io_client->callbacks);
89 cc_uint64 iterator_count = ccs_iteratorref_array_count (io_client->iterators);
90
91 for (i = 0; !err && i < callback_count; i++) {
92 ccs_callback_t callback = ccs_callbackref_array_object_at_index (io_client->callbacks, i);
93
94 cci_debug_printf ("%s: Invalidating callback reference %p.",
95 __FUNCTION__, callback);
96 ccs_callback_invalidate (callback);
97 }
98
99 for (i = 0; !err && i < iterator_count; i++) {
100 ccs_generic_list_iterator_t iterator = ccs_iteratorref_array_object_at_index (io_client->iterators, i);
101
102 cci_debug_printf ("%s: Invalidating iterator reference %p.",
103 __FUNCTION__, iterator);
104 ccs_generic_list_iterator_invalidate (iterator);
105 }
106
107 ccs_callbackref_array_release (io_client->callbacks);
108 ccs_iteratorref_array_release (io_client->iterators);
109 ccs_pipe_release (io_client->client_pipe);
110 free (io_client);
111 }
112
113 return cci_check_error (err);
114 }
115
116 /* ------------------------------------------------------------------------ */
117
ccs_client_add_callback(ccs_client_t io_client,ccs_callback_t in_callback)118 cc_int32 ccs_client_add_callback (ccs_client_t io_client,
119 ccs_callback_t in_callback)
120 {
121 cc_int32 err = ccNoError;
122
123 if (!io_client ) { err = cci_check_error (ccErrBadParam); }
124 if (!in_callback) { err = cci_check_error (ccErrBadParam); }
125
126 if (!err) {
127 err = ccs_callbackref_array_insert (io_client->callbacks, in_callback,
128 ccs_callbackref_array_count (io_client->callbacks));
129 }
130
131 return cci_check_error (err);
132 }
133
134
135 /* ------------------------------------------------------------------------ */
136
ccs_client_remove_callback(ccs_client_t io_client,ccs_callback_t in_callback)137 cc_int32 ccs_client_remove_callback (ccs_client_t io_client,
138 ccs_callback_t in_callback)
139 {
140 cc_int32 err = ccNoError;
141 cc_uint32 found_callback = 0;
142
143 if (!io_client) { err = cci_check_error (ccErrBadParam); }
144
145 if (!err) {
146 cc_uint64 i;
147 cc_uint64 lock_count = ccs_callbackref_array_count (io_client->callbacks);
148
149 for (i = 0; !err && i < lock_count; i++) {
150 ccs_callback_t callback = ccs_callbackref_array_object_at_index (io_client->callbacks, i);
151
152 if (callback == in_callback) {
153 cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback);
154 found_callback = 1;
155 err = ccs_callbackref_array_remove (io_client->callbacks, i);
156 break;
157 }
158 }
159 }
160
161 if (!err && !found_callback) {
162 cci_debug_printf ("%s: WARNING! callback not found.", __FUNCTION__);
163 }
164
165 return cci_check_error (err);
166 }
167
168 /* ------------------------------------------------------------------------ */
169
ccs_client_add_iterator(ccs_client_t io_client,ccs_generic_list_iterator_t in_iterator)170 cc_int32 ccs_client_add_iterator (ccs_client_t io_client,
171 ccs_generic_list_iterator_t in_iterator)
172 {
173 cc_int32 err = ccNoError;
174
175 if (!io_client ) { err = cci_check_error (ccErrBadParam); }
176 if (!in_iterator) { err = cci_check_error (ccErrBadParam); }
177
178 if (!err) {
179 err = ccs_iteratorref_array_insert (io_client->iterators, in_iterator,
180 ccs_iteratorref_array_count (io_client->iterators));
181 }
182
183 return cci_check_error (err);
184 }
185
186 /* ------------------------------------------------------------------------ */
187
ccs_client_remove_iterator(ccs_client_t io_client,ccs_generic_list_iterator_t in_iterator)188 cc_int32 ccs_client_remove_iterator (ccs_client_t io_client,
189 ccs_generic_list_iterator_t in_iterator)
190 {
191 cc_int32 err = ccNoError;
192 cc_uint32 found_iterator = 0;
193
194 if (!io_client) { err = cci_check_error (ccErrBadParam); }
195
196 if (!err) {
197 cc_uint64 i;
198 cc_uint64 lock_count = ccs_iteratorref_array_count (io_client->iterators);
199
200 for (i = 0; !err && i < lock_count; i++) {
201 ccs_generic_list_iterator_t iterator = ccs_iteratorref_array_object_at_index (io_client->iterators, i);
202
203 if (iterator == in_iterator) {
204 cci_debug_printf ("%s: Removing iterator reference %p.", __FUNCTION__, iterator);
205 found_iterator = 1;
206 err = ccs_iteratorref_array_remove (io_client->iterators, i);
207 break;
208 }
209 }
210 }
211
212 if (!err && !found_iterator) {
213 cci_debug_printf ("%s: WARNING! iterator not found.", __FUNCTION__);
214 }
215
216 return cci_check_error (err);
217 }
218
219 /* ------------------------------------------------------------------------ */
220
ccs_client_uses_pipe(ccs_client_t in_client,ccs_pipe_t in_pipe,cc_uint32 * out_uses_pipe)221 cc_int32 ccs_client_uses_pipe (ccs_client_t in_client,
222 ccs_pipe_t in_pipe,
223 cc_uint32 *out_uses_pipe)
224 {
225 cc_int32 err = ccNoError;
226
227 if (!in_client ) { err = cci_check_error (ccErrBadParam); }
228 if (!in_pipe ) { err = cci_check_error (ccErrBadParam); }
229 if (!out_uses_pipe) { err = cci_check_error (ccErrBadParam); }
230
231 if (!err) {
232 err = ccs_pipe_compare (in_client->client_pipe, in_pipe, out_uses_pipe);
233 }
234
235 return cci_check_error (err);
236 }
237