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 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 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 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 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 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 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 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