From e623c00ce9df3580e6eb1b0337fe1d9727fb61e6 Mon Sep 17 00:00:00 2001 From: Alexandra Ellwood Date: Wed, 25 Jul 2007 19:29:39 +0000 Subject: [PATCH] Added callback support for wait_for_change functions ticket: 4644 status: open git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@19731 dc483132-0cff-0310-8789-dd5450dbe970 --- src/ccapi/common/cci_array_internal.c | 4 +- src/ccapi/common/cci_identifier.c | 6 +-- src/ccapi/common/cci_stream.c | 4 +- src/ccapi/lib/ccapi_ccache.c | 22 ++++++++- src/ccapi/lib/ccapi_context.c | 28 +++++++++-- src/ccapi/server/ccs_cache_collection.c | 64 +++++++++++++++++-------- src/ccapi/server/ccs_callback.c | 47 +++++++++--------- src/ccapi/server/ccs_ccache.c | 64 +++++++++++++++++-------- src/ccapi/server/ccs_client.c | 35 +++++++------- src/ccapi/server/ccs_credentials.c | 4 +- src/ccapi/server/ccs_list_internal.c | 8 +--- src/ccapi/server/ccs_lock.c | 4 +- src/ccapi/server/ccs_lock_state.c | 4 +- 13 files changed, 186 insertions(+), 108 deletions(-) diff --git a/src/ccapi/common/cci_array_internal.c b/src/ccapi/common/cci_array_internal.c index 85578c2b1..3d1e35ef3 100644 --- a/src/ccapi/common/cci_array_internal.c +++ b/src/ccapi/common/cci_array_internal.c @@ -128,9 +128,7 @@ cc_int32 cci_array_release (cci_array_t io_array) { cc_int32 err = ccNoError; - if (!io_array) { err = ccErrBadParam; } - - if (!err) { + if (!err && io_array) { cc_uint64 i; if (io_array->object_release) { diff --git a/src/ccapi/common/cci_identifier.c b/src/ccapi/common/cci_identifier.c index 8695d2171..b6e918892 100644 --- a/src/ccapi/common/cci_identifier.c +++ b/src/ccapi/common/cci_identifier.c @@ -141,16 +141,14 @@ cc_int32 cci_identifier_release (cci_identifier_t in_identifier) { cc_int32 err = ccNoError; - if (!in_identifier) { err = ccErrBadParam; } - /* Do not free the static "uninitialized" identifier */ - if (!err && in_identifier != cci_identifier_uninitialized) { + if (!err && in_identifier && in_identifier != cci_identifier_uninitialized) { free (in_identifier->server_id); free (in_identifier->object_id); free (in_identifier); } - return err; + return cci_check_error (err); } #pragma mark - diff --git a/src/ccapi/common/cci_stream.c b/src/ccapi/common/cci_stream.c index 1532f1ed8..b19e7bbfb 100644 --- a/src/ccapi/common/cci_stream.c +++ b/src/ccapi/common/cci_stream.c @@ -134,9 +134,7 @@ cc_uint32 cci_stream_release (cci_stream_t io_stream) { cc_int32 err = ccNoError; - if (!io_stream) { err = ccErrBadParam; } - - if (!err) { + if (!err && io_stream) { free (io_stream->data); free (io_stream); } diff --git a/src/ccapi/lib/ccapi_ccache.c b/src/ccapi/lib/ccapi_ccache.c index 5a975810c..485e6ceea 100644 --- a/src/ccapi/lib/ccapi_ccache.c +++ b/src/ccapi/lib/ccapi_ccache.c @@ -44,6 +44,7 @@ typedef struct cci_ccache_d { cc_ccache_f *vector_functions; #endif cci_identifier_t identifier; + cc_time_t last_wait_for_change_time; } *cci_ccache_t; /* ------------------------------------------------------------------------ */ @@ -52,6 +53,7 @@ struct cci_ccache_d cci_ccache_initializer = { NULL VECTOR_FUNCTIONS_INITIALIZER, NULL, + 0 }; cc_ccache_f cci_ccache_f_initializer = { @@ -594,15 +596,33 @@ cc_int32 ccapi_ccache_wait_for_change (cc_ccache_t in_ccache) { cc_int32 err = ccNoError; cci_ccache_t ccache = (cci_ccache_t) in_ccache; + cci_stream_t request = NULL; + cci_stream_t reply = NULL; if (!in_ccache) { err = cci_check_error (ccErrBadParam); } + if (!err) { + err = cci_stream_new (&request); + } + + if (!err) { + err = cci_stream_write_time (request, ccache->last_wait_for_change_time); + } + if (!err) { err = cci_ipc_send (cci_ccache_wait_for_change_msg_id, ccache->identifier, - NULL, NULL); + request, + &reply); } + + if (!err) { + err = cci_stream_read_time (reply, &ccache->last_wait_for_change_time); + } + cci_stream_release (request); + cci_stream_release (reply); + return cci_check_error (err); } diff --git a/src/ccapi/lib/ccapi_context.c b/src/ccapi/lib/ccapi_context.c index 7a24f2248..feccc85a4 100644 --- a/src/ccapi/lib/ccapi_context.c +++ b/src/ccapi/lib/ccapi_context.c @@ -43,6 +43,7 @@ typedef struct cci_context_d { #endif cci_identifier_t identifier; cc_uint32 synchronized; + cc_time_t last_wait_for_change_time; } *cci_context_t; /* ------------------------------------------------------------------------ */ @@ -51,6 +52,7 @@ struct cci_context_d cci_context_initializer = { NULL VECTOR_FUNCTIONS_INITIALIZER, NULL, + 0, 0 }; @@ -249,19 +251,37 @@ cc_int32 ccapi_context_wait_for_change (cc_context_t in_context) { cc_int32 err = ccNoError; cci_context_t context = (cci_context_t) in_context; + cci_stream_t request = NULL; + cci_stream_t reply = NULL; if (!in_context) { err = cci_check_error (ccErrBadParam); } if (!err) { - err = cci_context_sync (context, 0); + err = cci_stream_new (&request); } if (!err) { - err = cci_ipc_send_no_launch (cci_context_wait_for_change_msg_id, - context->identifier, - NULL, NULL); + err = cci_stream_write_time (request, context->last_wait_for_change_time); + } + + if (!err) { + err = cci_context_sync (context, 1); } + if (!err) { + err = cci_ipc_send (cci_context_wait_for_change_msg_id, + context->identifier, + request, + &reply); + } + + if (!err) { + err = cci_stream_read_time (reply, &context->last_wait_for_change_time); + } + + cci_stream_release (request); + cci_stream_release (reply); + return cci_check_error (err); } diff --git a/src/ccapi/server/ccs_cache_collection.c b/src/ccapi/server/ccs_cache_collection.c index 1356bc574..543f99c20 100644 --- a/src/ccapi/server/ccs_cache_collection.c +++ b/src/ccapi/server/ccs_cache_collection.c @@ -94,9 +94,7 @@ cc_int32 ccs_cache_collection_release (ccs_cache_collection_t io_cache_collectio { cc_int32 err = ccNoError; - if (!io_cache_collection) { err = ccErrBadParam; } - - if (!err) { + if (!err && io_cache_collection) { cci_identifier_release (io_cache_collection->identifier); ccs_lock_state_release (io_cache_collection->lock_state); ccs_ccache_list_release (io_cache_collection->ccaches); @@ -135,6 +133,7 @@ cc_int32 ccs_cache_collection_compare_identifier (ccs_cache_collection_t in_cac cc_int32 ccs_cache_collection_changed (ccs_cache_collection_t io_cache_collection) { cc_int32 err = ccNoError; + cci_stream_t reply_data = NULL; if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } @@ -148,6 +147,14 @@ cc_int32 ccs_cache_collection_changed (ccs_cache_collection_t io_cache_collectio } } + if (!err) { + err = cci_stream_new (&reply_data); + } + + if (!err) { + err = cci_stream_write_time (reply_data, io_cache_collection->last_changed_time); + } + if (!err) { /* Loop over callbacks sending messages to them */ cc_uint64 i; @@ -156,7 +163,7 @@ cc_int32 ccs_cache_collection_changed (ccs_cache_collection_t io_cache_collectio for (i = 0; !err && i < count; i++) { ccs_callback_t callback = ccs_callback_array_object_at_index (io_cache_collection->change_callbacks, i); - err = ccs_callback_reply_to_client (callback, NULL); + err = ccs_callback_reply_to_client (callback, reply_data); if (!err) { cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback); @@ -164,9 +171,10 @@ cc_int32 ccs_cache_collection_changed (ccs_cache_collection_t io_cache_collectio break; } } - } + cci_stream_release (reply_data); + return cci_check_error (err); } @@ -580,10 +588,12 @@ static cc_int32 ccs_cache_collection_wait_for_change (ccs_pipe_t in ccs_pipe_t in_reply_pipe, ccs_cache_collection_t io_cache_collection, cci_stream_t in_request_data, + cci_stream_t io_reply_data, cc_uint32 *out_will_block) { cc_int32 err = ccNoError; - ccs_callback_t callback = NULL; + cc_time_t last_wait_for_change_time = 0; + cc_uint32 will_block = 0; if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } if (!ccs_pipe_valid (in_reply_pipe )) { err = cci_check_error (ccErrBadParam); } @@ -592,25 +602,38 @@ static cc_int32 ccs_cache_collection_wait_for_change (ccs_pipe_t in if (!out_will_block ) { err = cci_check_error (ccErrBadParam); } if (!err) { - err = ccs_callback_new (&callback, - ccErrInvalidContext, - in_client_pipe, - in_reply_pipe, - (ccs_callback_owner_t) io_cache_collection, - ccs_cache_collection_invalidate_change_callback); + err = cci_stream_read_time (in_request_data, &last_wait_for_change_time); } if (!err) { - err = ccs_callback_array_insert (io_cache_collection->change_callbacks, callback, - ccs_callback_array_count (io_cache_collection->change_callbacks)); - if (!err) { callback = NULL; /* take ownership */ } - } + if (last_wait_for_change_time < io_cache_collection->last_changed_time) { + err = cci_stream_write_time (io_reply_data, io_cache_collection->last_changed_time); + + } else { + ccs_callback_t callback = NULL; - if (!err) { - *out_will_block = 1; + err = ccs_callback_new (&callback, + ccErrInvalidContext, + in_client_pipe, + in_reply_pipe, + (ccs_callback_owner_t) io_cache_collection, + ccs_cache_collection_invalidate_change_callback); + + if (!err) { + err = ccs_callback_array_insert (io_cache_collection->change_callbacks, callback, + ccs_callback_array_count (io_cache_collection->change_callbacks)); + if (!err) { callback = NULL; /* take ownership */ } + + will_block = 1; + } + + ccs_callback_release (callback); + } } - ccs_callback_release (callback); + if (!err) { + *out_will_block = will_block; + } return cci_check_error (err); } @@ -995,7 +1018,8 @@ static cc_int32 ccs_cache_collection_unlock (ccs_pipe_t in_client_pi } else if (in_request_name == cci_context_wait_for_change_msg_id) { err = ccs_cache_collection_wait_for_change (in_client_pipe, in_reply_pipe, io_cache_collection, - in_request_data, &will_block); + in_request_data, reply_data, + &will_block); } else if (in_request_name == cci_context_get_default_ccache_name_msg_id) { err = ccs_cache_collection_get_default_ccache_name (io_cache_collection, diff --git a/src/ccapi/server/ccs_callback.c b/src/ccapi/server/ccs_callback.c index 8035e5af1..1076d9025 100644 --- a/src/ccapi/server/ccs_callback.c +++ b/src/ccapi/server/ccs_callback.c @@ -102,29 +102,30 @@ cc_int32 ccs_callback_new (ccs_callback_t *out_callback, cc_int32 ccs_callback_release (ccs_callback_t io_callback) { cc_int32 err = ccNoError; - ccs_client_t client = NULL; - - if (!io_callback) { err = cci_check_error (ccErrBadParam); } - if (!err && io_callback->pending) { - err = ccs_server_send_reply (io_callback->reply_pipe, - io_callback->invalid_object_err, NULL); - - io_callback->pending = 0; - } - - if (!err) { - err = ccs_server_client_for_pipe (io_callback->client_pipe, &client); - } - - if (!err) { - err = ccs_client_remove_callback (client, io_callback); - } - - if (!err) { - ccs_pipe_release (io_callback->client_pipe); - ccs_pipe_release (io_callback->reply_pipe); - free (io_callback); + if (!err && io_callback) { + ccs_client_t client = NULL; + + if (io_callback->pending) { + err = ccs_server_send_reply (io_callback->reply_pipe, + io_callback->invalid_object_err, NULL); + + io_callback->pending = 0; + } + + if (!err) { + err = ccs_server_client_for_pipe (io_callback->client_pipe, &client); + } + + if (!err) { + err = ccs_client_remove_callback (client, io_callback); + } + + if (!err) { + ccs_pipe_release (io_callback->client_pipe); + ccs_pipe_release (io_callback->reply_pipe); + free (io_callback); + } } return cci_check_error (err); @@ -157,6 +158,8 @@ cc_int32 ccs_callback_reply_to_client (ccs_callback_t io_callback, if (!err) { if (io_callback->pending) { + cci_debug_printf ("%s: callback %p replying to client.", __FUNCTION__, io_callback); + err = ccs_server_send_reply (io_callback->reply_pipe, err, in_stream); if (err) { diff --git a/src/ccapi/server/ccs_ccache.c b/src/ccapi/server/ccs_ccache.c index da6a8318f..3eab42fa7 100644 --- a/src/ccapi/server/ccs_ccache.c +++ b/src/ccapi/server/ccs_ccache.c @@ -229,9 +229,7 @@ cc_int32 ccs_ccache_release (ccs_ccache_t io_ccache) { cc_int32 err = ccNoError; - if (!io_ccache) { err = ccErrBadParam; } - - if (!err) { + if (!err && io_ccache) { cci_identifier_release (io_ccache->identifier); ccs_lock_state_release (io_ccache->lock_state); free (io_ccache->name); @@ -294,6 +292,7 @@ static cc_int32 ccs_ccache_changed (ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection) { cc_int32 err = ccNoError; + cci_stream_t reply_data = NULL; if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } @@ -312,6 +311,14 @@ static cc_int32 ccs_ccache_changed (ccs_ccache_t io_ccache, err = ccs_cache_collection_changed (io_cache_collection); } + if (!err) { + err = cci_stream_new (&reply_data); + } + + if (!err) { + err = cci_stream_write_time (reply_data, io_ccache->last_changed_time); + } + if (!err) { /* Loop over callbacks sending messages to them */ cc_uint64 i; @@ -320,7 +327,7 @@ static cc_int32 ccs_ccache_changed (ccs_ccache_t io_ccache, for (i = 0; !err && i < count; i++) { ccs_callback_t callback = ccs_callback_array_object_at_index (io_ccache->change_callbacks, i); - err = ccs_callback_reply_to_client (callback, NULL); + err = ccs_callback_reply_to_client (callback, reply_data); if (!err) { cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback); @@ -328,9 +335,10 @@ static cc_int32 ccs_ccache_changed (ccs_ccache_t io_ccache, break; } } - } + cci_stream_release (reply_data); + return cci_check_error (err); } @@ -834,10 +842,12 @@ static cc_int32 ccs_ccache_wait_for_change (ccs_pipe_t in_client_pi ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, cci_stream_t in_request_data, + cci_stream_t io_reply_data, cc_uint32 *out_will_block) { cc_int32 err = ccNoError; - ccs_callback_t callback = NULL; + cc_time_t last_wait_for_change_time = 0; + cc_uint32 will_block = 0; if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } if (!ccs_pipe_valid (in_reply_pipe )) { err = cci_check_error (ccErrBadParam); } @@ -847,26 +857,39 @@ static cc_int32 ccs_ccache_wait_for_change (ccs_pipe_t in_client_pi if (!out_will_block ) { err = cci_check_error (ccErrBadParam); } if (!err) { - err = ccs_callback_new (&callback, - ccErrInvalidCCache, - in_client_pipe, - in_reply_pipe, - (ccs_callback_owner_t) io_ccache, - ccs_ccache_invalidate_change_callback); + err = cci_stream_read_time (in_request_data, &last_wait_for_change_time); } if (!err) { - err = ccs_callback_array_insert (io_ccache->change_callbacks, callback, - ccs_callback_array_count (io_ccache->change_callbacks)); - if (!err) { callback = NULL; /* take ownership */ } + if (last_wait_for_change_time < io_ccache->last_changed_time) { + err = cci_stream_write_time (io_reply_data, io_ccache->last_changed_time); + + } else { + ccs_callback_t callback = NULL; + + err = ccs_callback_new (&callback, + ccErrInvalidCCache, + in_client_pipe, + in_reply_pipe, + (ccs_callback_owner_t) io_ccache, + ccs_ccache_invalidate_change_callback); + + if (!err) { + err = ccs_callback_array_insert (io_ccache->change_callbacks, callback, + ccs_callback_array_count (io_ccache->change_callbacks)); + if (!err) { callback = NULL; /* take ownership */ } + + will_block = 1; + } + + ccs_callback_release (callback); + } } - + if (!err) { - *out_will_block = 1; + *out_will_block = will_block; } - ccs_callback_release (callback); - return cci_check_error (err); } @@ -1087,7 +1110,8 @@ cc_int32 ccs_ccache_handle_message (ccs_pipe_t in_client_pipe, } else if (in_request_name == cci_ccache_wait_for_change_msg_id) { err = ccs_ccache_wait_for_change (in_client_pipe, in_reply_pipe, io_ccache, io_cache_collection, - in_request_data, &will_block); + in_request_data, reply_data, + &will_block); } else if (in_request_name == cci_ccache_get_kdc_time_offset_msg_id) { err = ccs_ccache_get_kdc_time_offset (io_ccache, io_cache_collection, diff --git a/src/ccapi/server/ccs_client.c b/src/ccapi/server/ccs_client.c index 0cb19dae9..9e8a81c8b 100644 --- a/src/ccapi/server/ccs_client.c +++ b/src/ccapi/server/ccs_client.c @@ -77,12 +77,20 @@ cc_int32 ccs_client_release (ccs_client_t io_client) { cc_int32 err = ccNoError; - if (!io_client) { err = cci_check_error (ccErrBadParam); } - - if (!err) { - ccs_callbackref_array_release (io_client->callbacks); + if (!err && io_client) { + cc_uint64 i; + cc_uint64 lock_count = ccs_callbackref_array_count (io_client->callbacks); + + for (i = 0; !err && i < lock_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); + ccs_callback_invalidate (callback); + } + + ccs_callbackref_array_release (io_client->callbacks); ccs_pipe_release (io_client->client_pipe); - free (io_client); + free (io_client); } return cci_check_error (err); @@ -125,14 +133,9 @@ cc_int32 ccs_client_remove_callback (ccs_client_t io_client, ccs_callback_t callback = ccs_callbackref_array_object_at_index (io_client->callbacks, i); if (callback == in_callback) { - err = ccs_callback_invalidate (callback); - - if (!err) { - cci_debug_printf ("%s: Removing callback reference %p.", - __FUNCTION__, callback); - err = ccs_callbackref_array_remove (io_client->callbacks, i); - break; - } + cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback); + err = ccs_callbackref_array_remove (io_client->callbacks, i); + break; } } } @@ -152,9 +155,9 @@ cc_int32 ccs_client_uses_pipe (ccs_client_t in_client, { cc_int32 err = ccNoError; - if (in_client ) { err = cci_check_error (ccErrBadParam); } - if (in_pipe ) { err = cci_check_error (ccErrBadParam); } - if (out_uses_pipe) { err = cci_check_error (ccErrBadParam); } + if (!in_client ) { err = cci_check_error (ccErrBadParam); } + if (!in_pipe ) { err = cci_check_error (ccErrBadParam); } + if (!out_uses_pipe) { err = cci_check_error (ccErrBadParam); } if (!err) { *out_uses_pipe = (in_client->client_pipe == in_pipe); diff --git a/src/ccapi/server/ccs_credentials.c b/src/ccapi/server/ccs_credentials.c index a5bc70c9a..f30479946 100644 --- a/src/ccapi/server/ccs_credentials.c +++ b/src/ccapi/server/ccs_credentials.c @@ -82,9 +82,7 @@ cc_int32 ccs_credentials_release (ccs_credentials_t io_credentials) { cc_int32 err = ccNoError; - if (!io_credentials) { err = ccErrBadParam; } - - if (!err) { + if (!err && io_credentials) { cci_cred_union_release (io_credentials->cred_union); cci_identifier_release (io_credentials->identifier); free (io_credentials); diff --git a/src/ccapi/server/ccs_list_internal.c b/src/ccapi/server/ccs_list_internal.c index 2b3e27f29..2f99ebdb8 100644 --- a/src/ccapi/server/ccs_list_internal.c +++ b/src/ccapi/server/ccs_list_internal.c @@ -119,9 +119,7 @@ cc_int32 ccs_list_release (ccs_list_t io_list) { cc_int32 err = ccNoError; - if (!io_list) { err = ccErrBadParam; } - - if (!err) { + if (!err && io_list) { cc_uint64 i; for (i = 0; i < cci_array_count (io_list->iterators); i++) { @@ -521,9 +519,7 @@ cc_int32 ccs_list_iterator_release (ccs_list_iterator_t io_list_iterator) { cc_int32 err = ccNoError; - if (!io_list_iterator) { err = ccErrBadParam; } - - if (!err) { + if (!err && io_list_iterator) { cc_uint64 i = 0; if (ccs_list_find_iterator_index (io_list_iterator->list, diff --git a/src/ccapi/server/ccs_lock.c b/src/ccapi/server/ccs_lock.c index 1934640fe..1fc54db78 100644 --- a/src/ccapi/server/ccs_lock.c +++ b/src/ccapi/server/ccs_lock.c @@ -98,9 +98,7 @@ cc_int32 ccs_lock_release (ccs_lock_t io_lock) { cc_int32 err = ccNoError; - if (!io_lock) { err = cci_check_error (ccErrBadParam); } - - if (!err) { + if (!err && io_lock) { free (io_lock->callback); free (io_lock); } diff --git a/src/ccapi/server/ccs_lock_state.c b/src/ccapi/server/ccs_lock_state.c index b8dc5debf..0d8dcdadf 100644 --- a/src/ccapi/server/ccs_lock_state.c +++ b/src/ccapi/server/ccs_lock_state.c @@ -81,9 +81,7 @@ cc_int32 ccs_lock_state_release (ccs_lock_state_t io_lock_state) { cc_int32 err = ccNoError; - if (!io_lock_state) { err = ccErrBadParam; } - - if (!err) { + if (!err && io_lock_state) { ccs_lock_array_release (io_lock_state->locks); free (io_lock_state); } -- 2.26.2