diff options
author | Alexandra Ellwood <lxs@mit.edu> | 2008-03-18 19:25:16 +0000 |
---|---|---|
committer | Alexandra Ellwood <lxs@mit.edu> | 2008-03-18 19:25:16 +0000 |
commit | f8d4e9aaad429fd6fac6504a527ab0258f47b854 (patch) | |
tree | 113cf627b1a1cbffd54f632670a8b06768012ca4 /src/ccapi | |
parent | d8d990c823f7ba6070622acf5ff2d08af7c1d7a9 (diff) | |
download | krb5-f8d4e9aaad429fd6fac6504a527ab0258f47b854.tar.gz krb5-f8d4e9aaad429fd6fac6504a527ab0258f47b854.tar.xz krb5-f8d4e9aaad429fd6fac6504a527ab0258f47b854.zip |
CCacheServer should track client iterators
The CCacheServer needs to track client iterators so that if
a client crashes while iterating the resources on the server
for that iterator are freed.
ticket: new
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20279 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/ccapi')
-rw-r--r-- | src/ccapi/common/cci_array_internal.c | 19 | ||||
-rw-r--r-- | src/ccapi/server/ccs_array.c | 57 | ||||
-rw-r--r-- | src/ccapi/server/ccs_array.h | 20 | ||||
-rw-r--r-- | src/ccapi/server/ccs_cache_collection.c | 15 | ||||
-rw-r--r-- | src/ccapi/server/ccs_ccache.c | 9 | ||||
-rw-r--r-- | src/ccapi/server/ccs_client.c | 81 | ||||
-rw-r--r-- | src/ccapi/server/ccs_client.h | 6 | ||||
-rw-r--r-- | src/ccapi/server/ccs_list.c | 17 | ||||
-rw-r--r-- | src/ccapi/server/ccs_list.h | 8 | ||||
-rw-r--r-- | src/ccapi/server/ccs_list_internal.c | 67 | ||||
-rw-r--r-- | src/ccapi/server/ccs_list_internal.h | 6 | ||||
-rw-r--r-- | src/ccapi/server/ccs_types.h | 5 |
12 files changed, 279 insertions, 31 deletions
diff --git a/src/ccapi/common/cci_array_internal.c b/src/ccapi/common/cci_array_internal.c index bdd939dbcd..b5a0f693bd 100644 --- a/src/ccapi/common/cci_array_internal.c +++ b/src/ccapi/common/cci_array_internal.c @@ -52,7 +52,6 @@ static cc_int32 cci_array_resize (cci_array_t io_array, { cc_int32 err = ccNoError; cc_uint64 new_max_count = 0; - cci_array_object_t *objects = NULL; if (!io_array) { err = cci_check_error (ccErrBadParam); } @@ -75,8 +74,8 @@ static cc_int32 cci_array_resize (cci_array_t io_array, } } - if (!err) { - objects = io_array->objects; + if (!err && io_array->max_count != new_max_count) { + cci_array_object_t *objects = io_array->objects; if (!objects) { objects = malloc (new_max_count * sizeof (*objects)); @@ -84,11 +83,11 @@ static cc_int32 cci_array_resize (cci_array_t io_array, objects = realloc (objects, new_max_count * sizeof (*objects)); } if (!objects) { err = cci_check_error (ccErrNoMem); } - } - - if (!err) { - io_array->objects = objects; - io_array->max_count = new_max_count; + + if (!err) { + io_array->objects = objects; + io_array->max_count = new_max_count; + } } return cci_check_error (err); @@ -236,12 +235,12 @@ cc_int32 cci_array_remove (cci_array_t io_array, memmove (&io_array->objects[in_position], &io_array->objects[in_position + 1], move_count * sizeof (*io_array->objects)); } + io_array->count--; if (io_array->object_release) { io_array->object_release (object); } - io_array->count--; cci_array_resize (io_array, io_array->count); - } + } return cci_check_error (err); } diff --git a/src/ccapi/server/ccs_array.c b/src/ccapi/server/ccs_array.c index 82aa024543..d5dd4adb2a 100644 --- a/src/ccapi/server/ccs_array.c +++ b/src/ccapi/server/ccs_array.c @@ -212,7 +212,8 @@ cc_int32 ccs_callback_array_remove (ccs_callback_array_t io_array, cc_int32 ccs_callbackref_array_new (ccs_callbackref_array_t *out_array) { - return cci_array_new (out_array, NULL /* Just a reference, not owner */ ); + /* Ref arrays do not own their contents; pass NULL for release function */ + return cci_array_new (out_array, NULL); } /* ------------------------------------------------------------------------ */ @@ -253,3 +254,57 @@ cc_int32 ccs_callbackref_array_remove (ccs_callbackref_array_t io_array, { return cci_array_remove (io_array, in_position); } + +#ifdef TARGET_OS_MAC +#pragma mark - +#endif + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_iteratorref_array_new (ccs_iteratorref_array_t *out_array) +{ + /* Ref arrays do not own their contents; pass NULL for release function */ + return cci_array_new (out_array, NULL); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_iteratorref_array_release (ccs_iteratorref_array_t io_array) +{ + return cci_array_release (io_array); +} + +/* ------------------------------------------------------------------------ */ + +cc_uint64 ccs_iteratorref_array_count (ccs_iteratorref_array_t in_array) +{ + return cci_array_count (in_array); +} + +/* ------------------------------------------------------------------------ */ + +ccs_generic_list_iterator_t ccs_iteratorref_array_object_at_index (ccs_iteratorref_array_t io_array, + cc_uint64 in_position) +{ + return (ccs_generic_list_iterator_t) cci_array_object_at_index (io_array, + in_position); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_iteratorref_array_insert (ccs_iteratorref_array_t io_array, + ccs_generic_list_iterator_t in_iterator, + cc_uint64 in_position) +{ + return cci_array_insert (io_array, + (cci_array_object_t) in_iterator, + in_position); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_iteratorref_array_remove (ccs_iteratorref_array_t io_array, + cc_uint64 in_position) +{ + return cci_array_remove (io_array, in_position); +} diff --git a/src/ccapi/server/ccs_array.h b/src/ccapi/server/ccs_array.h index 800e15de81..93dc9d8c2c 100644 --- a/src/ccapi/server/ccs_array.h +++ b/src/ccapi/server/ccs_array.h @@ -110,4 +110,24 @@ cc_int32 ccs_callbackref_array_insert (ccs_callbackref_array_t io_array, cc_int32 ccs_callbackref_array_remove (ccs_callbackref_array_t io_array, cc_uint64 in_position); +#ifdef TARGET_OS_MAC +#pragma mark - +#endif + +cc_int32 ccs_iteratorref_array_new (ccs_iteratorref_array_t *out_array); + +cc_int32 ccs_iteratorref_array_release (ccs_iteratorref_array_t io_array); + +cc_uint64 ccs_iteratorref_array_count (ccs_iteratorref_array_t in_array); + +ccs_generic_list_iterator_t ccs_iteratorref_array_object_at_index (ccs_iteratorref_array_t io_array, + cc_uint64 in_position); + +cc_int32 ccs_iteratorref_array_insert (ccs_iteratorref_array_t io_array, + ccs_generic_list_iterator_t in_iterator, + cc_uint64 in_position); + +cc_int32 ccs_iteratorref_array_remove (ccs_iteratorref_array_t io_array, + cc_uint64 in_position); + #endif /* CCS_ARRAY_H */ diff --git a/src/ccapi/server/ccs_cache_collection.c b/src/ccapi/server/ccs_cache_collection.c index 2500c29749..02d4d8f7da 100644 --- a/src/ccapi/server/ccs_cache_collection.c +++ b/src/ccapi/server/ccs_cache_collection.c @@ -229,7 +229,9 @@ static cc_int32 ccs_cache_collection_find_ccache_by_name (ccs_cache_collection_t if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } if (!err) { - err = ccs_ccache_list_new_iterator (in_cache_collection->ccaches, &iterator); + err = ccs_ccache_list_new_iterator (in_cache_collection->ccaches, + CCS_PIPE_NULL, + &iterator); } while (!err) { @@ -374,7 +376,9 @@ cc_int32 ccs_cache_collection_find_credentials_iterator (ccs_cache_collection_t if (!out_credentials_iterator) { err = cci_check_error (ccErrBadParam); } if (!err) { - err = ccs_ccache_list_new_iterator (in_cache_collection->ccaches, &iterator); + err = ccs_ccache_list_new_iterator (in_cache_collection->ccaches, + CCS_PIPE_NULL, + &iterator); } while (!err) { @@ -473,6 +477,7 @@ static cc_int32 ccs_cache_collection_get_default_ccache (ccs_cache_collection_t ccs_ccache_list_iterator_t iterator = NULL; err = ccs_ccache_list_new_iterator (in_cache_collection->ccaches, + CCS_PIPE_NULL, &iterator); if (!err) { @@ -916,6 +921,7 @@ static cc_int32 ccs_cache_collection_create_new_ccache (ccs_cache_collection_t i /* ------------------------------------------------------------------------ */ static cc_int32 ccs_cache_collection_new_ccache_iterator (ccs_cache_collection_t io_cache_collection, + ccs_pipe_t in_client_pipe, cci_stream_t in_request_data, cci_stream_t io_reply_data) { @@ -928,6 +934,7 @@ static cc_int32 ccs_cache_collection_new_ccache_iterator (ccs_cache_collection_ if (!err) { err = ccs_ccache_list_new_iterator (io_cache_collection->ccaches, + in_client_pipe, &ccache_iterator); } @@ -1070,7 +1077,9 @@ static cc_int32 ccs_cache_collection_unlock (ccs_pipe_t in_client_pi } else if (in_request_name == cci_context_new_ccache_iterator_msg_id) { err = ccs_cache_collection_new_ccache_iterator (io_cache_collection, - in_request_data, reply_data); + in_client_pipe, + in_request_data, + reply_data); } else if (in_request_name == cci_context_lock_msg_id) { err = ccs_cache_collection_lock (in_client_pipe, in_reply_pipe, diff --git a/src/ccapi/server/ccs_ccache.c b/src/ccapi/server/ccs_ccache.c index 2f7d45d8b6..b35081feb5 100644 --- a/src/ccapi/server/ccs_ccache.c +++ b/src/ccapi/server/ccs_ccache.c @@ -747,6 +747,7 @@ static cc_int32 ccs_ccache_remove_credentials (ccs_ccache_t io_ccache, static cc_int32 ccs_ccache_new_credentials_iterator (ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, + ccs_pipe_t in_client_pipe, cci_stream_t in_request_data, cci_stream_t io_reply_data) { @@ -760,6 +761,7 @@ static cc_int32 ccs_ccache_new_credentials_iterator (ccs_ccache_t io_c if (!err) { err = ccs_credentials_list_new_iterator (io_ccache->credentials, + in_client_pipe, &credentials_iterator); } @@ -1163,8 +1165,11 @@ cc_int32 ccs_ccache_handle_message (ccs_pipe_t in_client_pipe, in_request_data, reply_data); } else if (in_request_name == cci_ccache_new_credentials_iterator_msg_id) { - err = ccs_ccache_new_credentials_iterator (io_ccache, io_cache_collection, - in_request_data, reply_data); + err = ccs_ccache_new_credentials_iterator (io_ccache, + io_cache_collection, + in_client_pipe, + in_request_data, + reply_data); } else if (in_request_name == cci_ccache_move_msg_id) { err = ccs_ccache_move (io_ccache, io_cache_collection, diff --git a/src/ccapi/server/ccs_client.c b/src/ccapi/server/ccs_client.c index 5ec5de33d7..31ed14ff47 100644 --- a/src/ccapi/server/ccs_client.c +++ b/src/ccapi/server/ccs_client.c @@ -28,10 +28,13 @@ struct ccs_client_d { ccs_pipe_t client_pipe; - ccs_callbackref_array_t callbacks; /* references, not owner */ + + /* The following arrays do not own their contents */ + ccs_callbackref_array_t callbacks; + ccs_iteratorref_array_t iterators; }; -struct ccs_client_d ccs_client_initializer = { CCS_PIPE_NULL, NULL }; +struct ccs_client_d ccs_client_initializer = { CCS_PIPE_NULL, NULL, NULL }; /* ------------------------------------------------------------------------ */ @@ -58,6 +61,10 @@ cc_int32 ccs_client_new (ccs_client_t *out_client, } if (!err) { + err = ccs_iteratorref_array_new (&client->iterators); + } + + if (!err) { err = ccs_pipe_copy (&client->client_pipe, in_client_pipe); } @@ -79,16 +86,27 @@ cc_int32 ccs_client_release (ccs_client_t io_client) if (!err && io_client) { cc_uint64 i; - cc_uint64 lock_count = ccs_callbackref_array_count (io_client->callbacks); + cc_uint64 callback_count = ccs_callbackref_array_count (io_client->callbacks); + cc_uint64 iterator_count = ccs_iteratorref_array_count (io_client->iterators); - for (i = 0; !err && i < lock_count; i++) { + for (i = 0; !err && i < callback_count; i++) { ccs_callback_t callback = ccs_callbackref_array_object_at_index (io_client->callbacks, i); - cci_debug_printf ("%s: Invalidating callback reference %p.", __FUNCTION__, callback); + cci_debug_printf ("%s: Invalidating callback reference %p.", + __FUNCTION__, callback); ccs_callback_invalidate (callback); } + for (i = 0; !err && i < iterator_count; i++) { + ccs_generic_list_iterator_t iterator = ccs_iteratorref_array_object_at_index (io_client->iterators, i); + + cci_debug_printf ("%s: Invalidating iterator reference %p.", + __FUNCTION__, iterator); + ccs_generic_list_iterator_invalidate (iterator); + } + ccs_callbackref_array_release (io_client->callbacks); + ccs_iteratorref_array_release (io_client->iterators); ccs_pipe_release (io_client->client_pipe); free (io_client); } @@ -108,7 +126,7 @@ cc_int32 ccs_client_add_callback (ccs_client_t io_client, if (!err) { err = ccs_callbackref_array_insert (io_client->callbacks, in_callback, - ccs_callback_array_count (io_client->callbacks)); + ccs_callbackref_array_count (io_client->callbacks)); } return cci_check_error (err); @@ -150,6 +168,57 @@ cc_int32 ccs_client_remove_callback (ccs_client_t io_client, /* ------------------------------------------------------------------------ */ +cc_int32 ccs_client_add_iterator (ccs_client_t io_client, + ccs_generic_list_iterator_t in_iterator) +{ + cc_int32 err = ccNoError; + + if (!io_client ) { err = cci_check_error (ccErrBadParam); } + if (!in_iterator) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_iteratorref_array_insert (io_client->iterators, in_iterator, + ccs_iteratorref_array_count (io_client->iterators)); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_client_remove_iterator (ccs_client_t io_client, + ccs_generic_list_iterator_t in_iterator) +{ + cc_int32 err = ccNoError; + cc_uint32 found_iterator = 0; + + if (!io_client) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + cc_uint64 i; + cc_uint64 lock_count = ccs_iteratorref_array_count (io_client->iterators); + + for (i = 0; !err && i < lock_count; i++) { + ccs_generic_list_iterator_t iterator = ccs_iteratorref_array_object_at_index (io_client->iterators, i); + + if (iterator == in_iterator) { + cci_debug_printf ("%s: Removing iterator reference %p.", __FUNCTION__, iterator); + found_iterator = 1; + err = ccs_iteratorref_array_remove (io_client->iterators, i); + break; + } + } + } + + if (!err && !found_iterator) { + cci_debug_printf ("%s: WARNING! iterator not found.", __FUNCTION__); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + cc_int32 ccs_client_uses_pipe (ccs_client_t in_client, ccs_pipe_t in_pipe, cc_uint32 *out_uses_pipe) diff --git a/src/ccapi/server/ccs_client.h b/src/ccapi/server/ccs_client.h index fe3ea71b99..58c963707b 100644 --- a/src/ccapi/server/ccs_client.h +++ b/src/ccapi/server/ccs_client.h @@ -40,6 +40,12 @@ cc_int32 ccs_client_add_callback (ccs_client_t io_client, cc_int32 ccs_client_remove_callback (ccs_client_t io_client, ccs_callback_t in_lock); +cc_int32 ccs_client_add_iterator (ccs_client_t io_client, + ccs_generic_list_iterator_t in_iterator); + +cc_int32 ccs_client_remove_iterator (ccs_client_t io_client, + ccs_generic_list_iterator_t in_iterator); + cc_int32 ccs_client_uses_pipe (ccs_client_t in_client, ccs_pipe_t in_pipe, cc_uint32 *out_uses_pipe); diff --git a/src/ccapi/server/ccs_list.c b/src/ccapi/server/ccs_list.c index bc34fa2577..2743994a14 100644 --- a/src/ccapi/server/ccs_list.c +++ b/src/ccapi/server/ccs_list.c @@ -132,9 +132,10 @@ cc_int32 ccs_ccache_list_new (ccs_ccache_list_t *out_list) /* ------------------------------------------------------------------------ */ cc_int32 ccs_ccache_list_new_iterator (ccs_ccache_list_t in_list, + ccs_pipe_t in_client_pipe, ccs_ccache_list_iterator_t *out_list_iterator) { - return ccs_list_new_iterator (in_list, out_list_iterator); + return ccs_list_new_iterator (in_list, in_client_pipe, out_list_iterator); } /* ------------------------------------------------------------------------ */ @@ -262,9 +263,10 @@ cc_int32 ccs_credentials_list_new (ccs_credentials_list_t *out_list) /* ------------------------------------------------------------------------ */ cc_int32 ccs_credentials_list_new_iterator (ccs_credentials_list_t in_list, + ccs_pipe_t in_client_pipe, ccs_credentials_list_iterator_t *out_list_iterator) { - return ccs_list_new_iterator (in_list, out_list_iterator); + return ccs_list_new_iterator (in_list, in_client_pipe, out_list_iterator); } /* ------------------------------------------------------------------------ */ @@ -347,3 +349,14 @@ cc_int32 ccs_credentials_list_iterator_release (ccs_credentials_list_iterator_t { return ccs_list_iterator_release (io_list_iterator); } + +#ifdef TARGET_OS_MAC +#pragma mark- +#endif + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_generic_list_iterator_invalidate (ccs_generic_list_iterator_t io_list_iterator) +{ + return ccs_list_iterator_invalidate (io_list_iterator); +} diff --git a/src/ccapi/server/ccs_list.h b/src/ccapi/server/ccs_list.h index 7346216974..fff2f5421e 100644 --- a/src/ccapi/server/ccs_list.h +++ b/src/ccapi/server/ccs_list.h @@ -54,6 +54,7 @@ cc_int32 ccs_cache_collection_list_release (ccs_cache_collection_list_t io_list) cc_int32 ccs_ccache_list_new (ccs_ccache_list_t *out_list); cc_int32 ccs_ccache_list_new_iterator (ccs_ccache_list_t in_list, + ccs_pipe_t in_client_pipe, ccs_ccache_list_iterator_t *out_list_iterator); cc_int32 ccs_ccache_list_count (ccs_ccache_list_t in_list, @@ -97,6 +98,7 @@ cc_int32 ccs_ccache_list_iterator_release (ccs_ccache_list_iterator_t io_list_it cc_int32 ccs_credentials_list_new (ccs_credentials_list_t *out_list); cc_int32 ccs_credentials_list_new_iterator (ccs_credentials_list_t in_list, + ccs_pipe_t in_client_pipe, ccs_credentials_list_iterator_t *out_list_iterator); cc_int32 ccs_credentials_list_count (ccs_credentials_list_t in_list, @@ -130,4 +132,10 @@ cc_int32 ccs_credentials_list_iterator_next (ccs_credentials_list_iterator_t io cc_int32 ccs_credentials_list_iterator_release (ccs_credentials_list_iterator_t io_list_iterator); +#ifdef TARGET_OS_MAC +#pragma mark - +#endif + +cc_int32 ccs_generic_list_iterator_invalidate (ccs_generic_list_iterator_t io_list_iterator); + #endif /* CCS_LIST_H */ diff --git a/src/ccapi/server/ccs_list_internal.c b/src/ccapi/server/ccs_list_internal.c index d74a0ff9ef..0066f36fd8 100644 --- a/src/ccapi/server/ccs_list_internal.c +++ b/src/ccapi/server/ccs_list_internal.c @@ -53,14 +53,16 @@ struct ccs_list_d ccs_list_initializer = { NULL, NULL, -1, -1, NULL }; struct ccs_list_iterator_d { cci_identifier_t identifier; + ccs_pipe_t client_pipe; ccs_list_t list; cc_uint64 current; }; -struct ccs_list_iterator_d ccs_list_iterator_initializer = { NULL, NULL, 0 }; +struct ccs_list_iterator_d ccs_list_iterator_initializer = { NULL, CCS_PIPE_NULL, NULL, 0 }; static cc_int32 ccs_list_iterator_new (ccs_list_iterator_t *out_list_iterator, - ccs_list_t in_list); + ccs_list_t in_list, + ccs_pipe_t in_client_pipe); static cc_int32 ccs_list_iterator_object_release (cci_array_object_t io_list_iterator); @@ -138,9 +140,12 @@ cc_int32 ccs_list_release (ccs_list_t io_list) /* ------------------------------------------------------------------------ */ cc_int32 ccs_list_new_iterator (ccs_list_t io_list, + ccs_pipe_t in_client_pipe, ccs_list_iterator_t *out_list_iterator) { - return cci_check_error (ccs_list_iterator_new (out_list_iterator, io_list)); + return cci_check_error (ccs_list_iterator_new (out_list_iterator, + io_list, + in_client_pipe)); } /* ------------------------------------------------------------------------ */ @@ -415,13 +420,15 @@ cc_int32 ccs_list_push_front (ccs_list_t io_list, /* ------------------------------------------------------------------------ */ static cc_int32 ccs_list_iterator_new (ccs_list_iterator_t *out_list_iterator, - ccs_list_t io_list) + ccs_list_t io_list, + ccs_pipe_t in_client_pipe) { cc_int32 err = ccNoError; ccs_list_iterator_t list_iterator = NULL; if (!out_list_iterator) { err = cci_check_error (ccErrBadParam); } if (!io_list ) { err = cci_check_error (ccErrBadParam); } + /* client_pipe may be NULL if the iterator exists for internal server use */ if (!err) { list_iterator = malloc (sizeof (*list_iterator)); @@ -444,6 +451,20 @@ static cc_int32 ccs_list_iterator_new (ccs_list_iterator_t *out_list_iterator, (cci_array_object_t) list_iterator, cci_array_count (io_list->iterators)); } + + if (!err && ccs_pipe_valid (in_client_pipe)) { + ccs_client_t client = NULL; + + err = ccs_pipe_copy (&list_iterator->client_pipe, in_client_pipe); + + if (!err) { + err = ccs_server_client_for_pipe (in_client_pipe, &client); + } + + if (!err) { + err = ccs_client_add_iterator (client, list_iterator); + } + } if (!err) { *out_list_iterator = list_iterator; @@ -485,7 +506,9 @@ cc_int32 ccs_list_iterator_clone (ccs_list_iterator_t in_list_iterator, if (!out_list_iterator) { err = cci_check_error (ccErrBadParam); } if (!err) { - err = ccs_list_iterator_new (&list_iterator, in_list_iterator->list); + err = ccs_list_iterator_new (&list_iterator, + in_list_iterator->list, + in_list_iterator->client_pipe); } if (!err) { @@ -509,7 +532,19 @@ static cc_int32 ccs_list_iterator_object_release (cci_array_object_t io_list_ite if (!io_list_iterator) { err = ccErrBadParam; } + if (!err && ccs_pipe_valid (list_iterator->client_pipe)) { + ccs_client_t client = NULL; + + err = ccs_server_client_for_pipe (list_iterator->client_pipe, &client); + + if (!err && client) { + /* if client object still has a reference to us, remove it */ + err = ccs_client_remove_iterator (client, list_iterator); + } + } + if (!err) { + ccs_pipe_release (list_iterator->client_pipe); cci_identifier_release (list_iterator->identifier); free (io_list_iterator); } @@ -541,6 +576,28 @@ cc_int32 ccs_list_iterator_release (ccs_list_iterator_t io_list_iterator) /* ------------------------------------------------------------------------ */ +cc_int32 ccs_list_iterator_invalidate (ccs_list_iterator_t io_list_iterator) +{ + cc_int32 err = ccNoError; + ccs_list_iterator_t list_iterator = (ccs_list_iterator_t) io_list_iterator; + + if (!io_list_iterator) { err = ccErrBadParam; } + + if (!err) { + /* Client owner died. Remove client reference and then the iterator. */ + if (ccs_pipe_valid (list_iterator->client_pipe)) { + ccs_pipe_release (list_iterator->client_pipe); + list_iterator->client_pipe = CCS_PIPE_NULL; + } + + err = ccs_list_iterator_release (io_list_iterator); + } + + return err; +} + +/* ------------------------------------------------------------------------ */ + cc_int32 ccs_list_iterator_current (ccs_list_iterator_t io_list_iterator, ccs_list_object_t *out_object) { diff --git a/src/ccapi/server/ccs_list_internal.h b/src/ccapi/server/ccs_list_internal.h index 5bb52d0612..1ab6aa4c10 100644 --- a/src/ccapi/server/ccs_list_internal.h +++ b/src/ccapi/server/ccs_list_internal.h @@ -27,7 +27,7 @@ #ifndef CCS_LIST_INTERNAL_H #define CCS_LIST_INTERNAL_H -#include "cci_common.h" +#include "ccs_common.h" #include "cci_array_internal.h" struct ccs_list_d; @@ -49,6 +49,7 @@ cc_int32 ccs_list_new (ccs_list_t *out_list, cc_int32 ccs_list_release (ccs_list_t io_list); cc_int32 ccs_list_new_iterator (ccs_list_t io_list, + ccs_pipe_t in_client_pipe, ccs_list_iterator_t *out_list_iterator); cc_int32 ccs_list_release_iterator (ccs_list_t io_list, @@ -87,7 +88,8 @@ cc_int32 ccs_list_iterator_current (ccs_list_iterator_t io_list_iterator, cc_int32 ccs_list_iterator_next (ccs_list_iterator_t io_list_iterator, ccs_list_object_t *out_object); -cc_int32 ccs_list_iterator_release (ccs_list_iterator_t io_list_iterator); +cc_int32 ccs_list_iterator_invalidate (ccs_list_iterator_t io_list_iterator); +cc_int32 ccs_list_iterator_release (ccs_list_iterator_t io_list_iterator); #endif /* CCS_LIST_INTERNAL_H */ diff --git a/src/ccapi/server/ccs_types.h b/src/ccapi/server/ccs_types.h index a1e65a2515..aaea0336c6 100644 --- a/src/ccapi/server/ccs_types.h +++ b/src/ccapi/server/ccs_types.h @@ -41,6 +41,8 @@ typedef struct cci_array_d *ccs_callback_array_t; typedef struct cci_array_d *ccs_callbackref_array_t; +typedef struct cci_array_d *ccs_iteratorref_array_t; + typedef struct cci_array_d *ccs_lock_array_t; #ifdef TARGET_OS_MAC @@ -79,6 +81,9 @@ typedef struct ccs_callback_d *ccs_callback_t; struct ccs_list_d; struct ccs_list_iterator_d; +/* Used for iterator array invalidate function */ +typedef struct ccs_list_iterator_d *ccs_generic_list_iterator_t; + typedef struct ccs_list_d *ccs_cache_collection_list_t; typedef struct ccs_list_d *ccs_ccache_list_t; |