From c7f2957ec351c161b999c3bdfb654bc8a84556e1 Mon Sep 17 00:00:00 2001 From: Alexandra Ellwood Date: Thu, 19 Jul 2007 21:13:01 +0000 Subject: [PATCH] Made callback code generic so that change time callbacks can use it as well ticket: 4644 status: open git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@19719 dc483132-0cff-0310-8789-dd5450dbe970 --- src/ccapi/common/cci_array_internal.c | 33 ++- src/ccapi/common/cci_array_internal.h | 4 +- src/ccapi/server/ccs_array.c | 91 +++++-- src/ccapi/server/ccs_array.h | 38 ++- src/ccapi/server/ccs_cache_collection.c | 111 ++++++++- src/ccapi/server/ccs_callback.c | 229 ++++++++++++++++++ .../server/{ccs_lockref.h => ccs_callback.h} | 40 ++- src/ccapi/server/ccs_ccache.c | 129 +++++++++- src/ccapi/server/ccs_ccache.h | 12 +- src/ccapi/server/ccs_client.c | 57 ++--- src/ccapi/server/ccs_client.h | 8 +- src/ccapi/server/ccs_common.h | 2 +- src/ccapi/server/ccs_credentials_iterator.c | 16 +- src/ccapi/server/ccs_list.c | 36 +-- src/ccapi/server/ccs_list_internal.c | 38 +-- src/ccapi/server/ccs_list_internal.h | 21 +- src/ccapi/server/ccs_lock.c | 83 +++---- src/ccapi/server/ccs_lock.h | 2 - src/ccapi/server/ccs_lockref.c | 121 --------- src/ccapi/server/ccs_types.h | 8 +- 20 files changed, 736 insertions(+), 343 deletions(-) create mode 100644 src/ccapi/server/ccs_callback.c rename src/ccapi/server/{ccs_lockref.h => ccs_callback.h} (50%) delete mode 100644 src/ccapi/server/ccs_lockref.c diff --git a/src/ccapi/common/cci_array_internal.c b/src/ccapi/common/cci_array_internal.c index 8e6bcd7e2..85578c2b1 100644 --- a/src/ccapi/common/cci_array_internal.c +++ b/src/ccapi/common/cci_array_internal.c @@ -133,9 +133,11 @@ cc_int32 cci_array_release (cci_array_t io_array) if (!err) { cc_uint64 i; - for (i = 0; i < io_array->count; i++) { - io_array->object_release (io_array->objects[i]); - } + if (io_array->object_release) { + for (i = 0; i < io_array->count; i++) { + io_array->object_release (io_array->objects[i]); + } + } free (io_array->objects); free (io_array); } @@ -193,15 +195,14 @@ cc_int32 cci_array_insert (cci_array_t io_array, } if (!err) { - unsigned char **objects = (unsigned char **)io_array->objects; cc_uint64 move_count = io_array->count - in_position; if (move_count > 0) { - memmove (&objects[in_position + 1], &objects[in_position], - move_count * sizeof (*objects)); + memmove (&io_array->objects[in_position + 1], &io_array->objects[in_position], + move_count * sizeof (*io_array->objects)); } - objects[in_position] = in_object; + io_array->objects[in_position] = in_object; io_array->count++; } @@ -222,16 +223,15 @@ cc_int32 cci_array_remove (cci_array_t io_array, } if (!err) { - unsigned char **objects = (unsigned char **)io_array->objects; cc_uint64 move_count = io_array->count - in_position - 1; - cci_array_object_t object = objects[in_position]; + cci_array_object_t object = io_array->objects[in_position]; if (move_count > 0) { - memmove (&objects[in_position], &objects[in_position + 1], - move_count * sizeof (*objects)); + memmove (&io_array->objects[in_position], &io_array->objects[in_position + 1], + move_count * sizeof (*io_array->objects)); } - io_array->object_release (object); + if (io_array->object_release) { io_array->object_release (object); } io_array->count--; cci_array_resize (io_array, io_array->count); @@ -281,12 +281,11 @@ cc_int32 cci_array_move (cci_array_t io_array, } if (move_count > 0) { - unsigned char **objects = (unsigned char **)io_array->objects; - cci_array_object_t object = objects[in_position]; + cci_array_object_t object = io_array->objects[in_position]; - memmove (&objects[move_to], &objects[move_from], - move_count * sizeof (*objects)); - objects[real_new_position] = object; + memmove (&io_array->objects[move_to], &io_array->objects[move_from], + move_count * sizeof (*io_array->objects)); + io_array->objects[real_new_position] = object; } *out_real_new_position = real_new_position; diff --git a/src/ccapi/common/cci_array_internal.h b/src/ccapi/common/cci_array_internal.h index a88e52951..af7c24bc6 100644 --- a/src/ccapi/common/cci_array_internal.h +++ b/src/ccapi/common/cci_array_internal.h @@ -29,7 +29,9 @@ #include "cci_types.h" -typedef void *cci_array_object_t; +struct cci_array_object_d; +typedef struct cci_array_object_d *cci_array_object_t; + typedef cc_int32 (*cci_array_object_release_t) (cci_array_object_t); struct cci_array_d; diff --git a/src/ccapi/server/ccs_array.c b/src/ccapi/server/ccs_array.c index 7683c944c..b648a36a7 100644 --- a/src/ccapi/server/ccs_array.c +++ b/src/ccapi/server/ccs_array.c @@ -29,7 +29,7 @@ /* ------------------------------------------------------------------------ */ -static cc_int32 ccs_client_object_release (void *io_client) +static cc_int32 ccs_client_object_release (cci_array_object_t io_client) { return cci_check_error (ccs_client_release ((ccs_client_t) io_client)); } @@ -60,7 +60,7 @@ cc_uint64 ccs_client_array_count (ccs_client_array_t in_array) ccs_client_t ccs_client_array_object_at_index (ccs_client_array_t io_array, cc_uint64 in_position) { - return cci_array_object_at_index (io_array, in_position); + return (ccs_client_t) cci_array_object_at_index (io_array, in_position); } /* ------------------------------------------------------------------------ */ @@ -69,7 +69,7 @@ cc_int32 ccs_client_array_insert (ccs_client_array_t io_array, ccs_client_t in_client, cc_uint64 in_position) { - return cci_array_insert (io_array, in_client, in_position); + return cci_array_insert (io_array, (cci_array_object_t) in_client, in_position); } /* ------------------------------------------------------------------------ */ @@ -84,7 +84,7 @@ cc_int32 ccs_client_array_remove (ccs_client_array_t io_array, /* ------------------------------------------------------------------------ */ -static cc_int32 ccs_lock_object_release (void *io_lock) +static cc_int32 ccs_lock_object_release (cci_array_object_t io_lock) { return cci_check_error (ccs_lock_release ((ccs_lock_t) io_lock)); } @@ -115,7 +115,7 @@ cc_uint64 ccs_lock_array_count (ccs_lock_array_t in_array) ccs_lock_t ccs_lock_array_object_at_index (ccs_lock_array_t io_array, cc_uint64 in_position) { - return cci_array_object_at_index (io_array, in_position); + return (ccs_lock_t) cci_array_object_at_index (io_array, in_position); } /* ------------------------------------------------------------------------ */ @@ -124,7 +124,7 @@ cc_int32 ccs_lock_array_insert (ccs_lock_array_t io_array, ccs_lock_t in_lock, cc_uint64 in_position) { - return cci_array_insert (io_array, in_lock, in_position); + return cci_array_insert (io_array, (cci_array_object_t) in_lock, in_position); } /* ------------------------------------------------------------------------ */ @@ -148,53 +148,102 @@ cc_int32 ccs_lock_array_move (ccs_lock_array_t io_array, /* ------------------------------------------------------------------------ */ -cc_int32 ccs_lockref_object_release (void *io_lockref) +static cc_int32 ccs_callback_object_release (cci_array_object_t io_callback) { - return cci_check_error (ccs_lockref_release ((ccs_lockref_t) io_lockref)); + return cci_check_error (ccs_callback_release ((ccs_callback_t) io_callback)); } /* ------------------------------------------------------------------------ */ -cc_int32 ccs_lockref_array_new (ccs_lockref_array_t *out_array) +cc_int32 ccs_callback_array_new (ccs_callback_array_t *out_array) { - return cci_array_new (out_array, ccs_lockref_object_release); + return cci_array_new (out_array, ccs_callback_object_release); } /* ------------------------------------------------------------------------ */ -cc_int32 ccs_lockref_array_release (ccs_lockref_array_t io_array) +cc_int32 ccs_callback_array_release (ccs_callback_array_t io_array) { return cci_array_release (io_array); } /* ------------------------------------------------------------------------ */ -cc_uint64 ccs_lockref_array_count (ccs_lockref_array_t in_array) +cc_uint64 ccs_callback_array_count (ccs_callback_array_t in_array) { return cci_array_count (in_array); } /* ------------------------------------------------------------------------ */ -ccs_lockref_t ccs_lockref_array_object_at_index (ccs_lockref_array_t io_array, - cc_uint64 in_position) +ccs_callback_t ccs_callback_array_object_at_index (ccs_callback_array_t io_array, + cc_uint64 in_position) { - return cci_array_object_at_index (io_array, in_position); + return (ccs_callback_t) cci_array_object_at_index (io_array, in_position); } /* ------------------------------------------------------------------------ */ -cc_int32 ccs_lockref_array_insert (ccs_lockref_array_t io_array, - ccs_lockref_t in_lockref, - cc_uint64 in_position) +cc_int32 ccs_callback_array_insert (ccs_callback_array_t io_array, + ccs_callback_t in_callback, + cc_uint64 in_position) { - return cci_array_insert (io_array, in_lockref, in_position); + return cci_array_insert (io_array, (cci_array_object_t) in_callback, in_position); } /* ------------------------------------------------------------------------ */ -cc_int32 ccs_lockref_array_remove (ccs_lockref_array_t io_array, - cc_uint64 in_position) +cc_int32 ccs_callback_array_remove (ccs_callback_array_t io_array, + cc_uint64 in_position) +{ + return cci_array_remove (io_array, in_position); +} + +#pragma mark - + + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_callbackref_array_new (ccs_callbackref_array_t *out_array) +{ + return cci_array_new (out_array, NULL /* Just a reference, not owner */ ); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_callbackref_array_release (ccs_callbackref_array_t io_array) +{ + return cci_array_release (io_array); +} + +/* ------------------------------------------------------------------------ */ + +cc_uint64 ccs_callbackref_array_count (ccs_callbackref_array_t in_array) +{ + return cci_array_count (in_array); +} + +/* ------------------------------------------------------------------------ */ + +ccs_callback_t ccs_callbackref_array_object_at_index (ccs_callbackref_array_t io_array, + cc_uint64 in_position) +{ + return (ccs_callback_t) cci_array_object_at_index (io_array, in_position); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_callbackref_array_insert (ccs_callbackref_array_t io_array, + ccs_callback_t in_callback, + cc_uint64 in_position) +{ + return cci_array_insert (io_array, (cci_array_object_t) in_callback, in_position); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_callbackref_array_remove (ccs_callbackref_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 05bcbdf8e..d4a6ba601 100644 --- a/src/ccapi/server/ccs_array.h +++ b/src/ccapi/server/ccs_array.h @@ -70,22 +70,38 @@ cc_int32 ccs_lock_array_move (ccs_lock_array_t io_array, #pragma mark - -cc_int32 ccs_lockref_object_release (void *io_lockref); +cc_int32 ccs_callback_array_new (ccs_callback_array_t *out_array); -cc_int32 ccs_lockref_array_new (ccs_lockref_array_t *out_array); +cc_int32 ccs_callback_array_release (ccs_callback_array_t io_array); -cc_int32 ccs_lockref_array_release (ccs_lockref_array_t io_array); +cc_uint64 ccs_callback_array_count (ccs_callback_array_t in_array); -cc_uint64 ccs_lockref_array_count (ccs_lockref_array_t in_array); +ccs_callback_t ccs_callback_array_object_at_index (ccs_callback_array_t io_array, + cc_uint64 in_position); -ccs_lockref_t ccs_lockref_array_object_at_index (ccs_lockref_array_t io_array, - cc_uint64 in_position); +cc_int32 ccs_callback_array_insert (ccs_callback_array_t io_array, + ccs_callback_t in_callback, + cc_uint64 in_position); -cc_int32 ccs_lockref_array_insert (ccs_lockref_array_t io_array, - ccs_lockref_t in_lockref, - cc_uint64 in_position); +cc_int32 ccs_callback_array_remove (ccs_callback_array_t io_array, + cc_uint64 in_position); -cc_int32 ccs_lockref_array_remove (ccs_lockref_array_t io_array, - cc_uint64 in_position); +#pragma mark - + +cc_int32 ccs_callbackref_array_new (ccs_callbackref_array_t *out_array); + +cc_int32 ccs_callbackref_array_release (ccs_callbackref_array_t io_array); + +cc_uint64 ccs_callbackref_array_count (ccs_callbackref_array_t in_array); + +ccs_callback_t ccs_callbackref_array_object_at_index (ccs_callbackref_array_t io_array, + cc_uint64 in_position); + +cc_int32 ccs_callbackref_array_insert (ccs_callbackref_array_t io_array, + ccs_callback_t in_callback, + cc_uint64 in_position); + +cc_int32 ccs_callbackref_array_remove (ccs_callbackref_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 e3132744a..1356bc574 100644 --- a/src/ccapi/server/ccs_cache_collection.c +++ b/src/ccapi/server/ccs_cache_collection.c @@ -32,9 +32,10 @@ struct ccs_cache_collection_d { cci_identifier_t identifier; ccs_lock_state_t lock_state; ccs_ccache_list_t ccaches; + ccs_callback_array_t change_callbacks; }; -struct ccs_cache_collection_d ccs_cache_collection_initializer = { 0, 0, NULL, NULL, NULL }; +struct ccs_cache_collection_d ccs_cache_collection_initializer = { 0, 0, NULL, NULL, NULL, NULL }; /* ------------------------------------------------------------------------ */ @@ -69,6 +70,10 @@ cc_int32 ccs_cache_collection_new (ccs_cache_collection_t *out_cache_collection) err = ccs_ccache_list_new (&cache_collection->ccaches); } + if (!err) { + err = ccs_callback_array_new (&cache_collection->change_callbacks); + } + if (!err) { err = ccs_cache_collection_changed (cache_collection); } @@ -95,6 +100,7 @@ cc_int32 ccs_cache_collection_release (ccs_cache_collection_t io_cache_collectio cci_identifier_release (io_cache_collection->identifier); ccs_lock_state_release (io_cache_collection->lock_state); ccs_ccache_list_release (io_cache_collection->ccaches); + ccs_callback_array_release (io_cache_collection->change_callbacks); free (io_cache_collection); } @@ -142,6 +148,55 @@ cc_int32 ccs_cache_collection_changed (ccs_cache_collection_t io_cache_collectio } } + if (!err) { + /* Loop over callbacks sending messages to them */ + cc_uint64 i; + cc_uint64 count = ccs_callback_array_count (io_cache_collection->change_callbacks); + + 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); + + if (!err) { + cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback); + err = ccs_callback_array_remove (io_cache_collection->change_callbacks, i); + break; + } + } + + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_invalidate_change_callback (ccs_callback_owner_t io_cache_collection, + ccs_callback_t in_callback) +{ + cc_int32 err = ccNoError; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_callback ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + /* Remove callback */ + ccs_cache_collection_t cache_collection = (ccs_cache_collection_t) io_cache_collection; + cc_uint64 i; + cc_uint64 count = ccs_callback_array_count (cache_collection->change_callbacks); + + for (i = 0; !err && i < count; i++) { + ccs_callback_t callback = ccs_callback_array_object_at_index (cache_collection->change_callbacks, i); + + if (callback == in_callback) { + cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback); + err = ccs_callback_array_remove (cache_collection->change_callbacks, i); + break; + } + } + } + return cci_check_error (err); } @@ -229,7 +284,9 @@ cc_int32 ccs_ccache_collection_move_ccache (ccs_cache_collection_t io_cache_coll } if (!err) { - err = ccs_ccache_swap_contents (source_ccache, io_destination_ccache); + err = ccs_ccache_swap_contents (source_ccache, + io_destination_ccache, + io_cache_collection); } if (!err) { @@ -519,6 +576,47 @@ static cc_int32 ccs_cache_collection_get_change_time (ccs_cache_collection_t io_ /* ------------------------------------------------------------------------ */ +static cc_int32 ccs_cache_collection_wait_for_change (ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cc_uint32 *out_will_block) +{ + cc_int32 err = ccNoError; + ccs_callback_t callback = NULL; + + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_reply_pipe )) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + 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); + } + + 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 (!err) { + *out_will_block = 1; + } + + ccs_callback_release (callback); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + static cc_int32 ccs_cache_collection_get_default_ccache_name (ccs_cache_collection_t io_cache_collection, cci_stream_t in_request_data, cci_stream_t io_reply_data) @@ -643,7 +741,7 @@ static cc_int32 ccs_cache_collection_create_ccache (ccs_cache_collection_t io_ca &ccache); if (!terr) { - err = ccs_ccache_reset (ccache, cred_vers, principal); + err = ccs_ccache_reset (ccache, io_cache_collection, cred_vers, principal); } else { err = ccs_ccache_new (&ccache, cred_vers, name, principal, @@ -693,7 +791,7 @@ static cc_int32 ccs_cache_collection_create_default_ccache (ccs_cache_collection &ccache); if (!err) { - err = ccs_ccache_reset (ccache, cred_vers, principal); + err = ccs_ccache_reset (ccache, io_cache_collection, cred_vers, principal); } else if (err == ccErrCCacheNotFound) { char *name = NULL; @@ -894,6 +992,11 @@ static cc_int32 ccs_cache_collection_unlock (ccs_pipe_t in_client_pi err = ccs_cache_collection_get_change_time (io_cache_collection, in_request_data, reply_data); + } 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); + } else if (in_request_name == cci_context_get_default_ccache_name_msg_id) { err = ccs_cache_collection_get_default_ccache_name (io_cache_collection, in_request_data, reply_data); diff --git a/src/ccapi/server/ccs_callback.c b/src/ccapi/server/ccs_callback.c new file mode 100644 index 000000000..8035e5af1 --- /dev/null +++ b/src/ccapi/server/ccs_callback.c @@ -0,0 +1,229 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" + +struct ccs_callback_d { + cc_int32 pending; + cc_int32 invalid_object_err; + ccs_pipe_t client_pipe; + ccs_pipe_t reply_pipe; + ccs_callback_owner_t owner; /* pointer to owner */ + ccs_callback_owner_invalidate_t owner_invalidate; +}; + +struct ccs_callback_d ccs_callback_initializer = { 1, 1, CCS_PIPE_NULL, CCS_PIPE_NULL, NULL, NULL }; + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_callback_new (ccs_callback_t *out_callback, + cc_int32 in_invalid_object_err, + ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + ccs_callback_owner_t in_owner, + ccs_callback_owner_invalidate_t in_owner_invalidate_function) +{ + cc_int32 err = ccNoError; + ccs_callback_t callback = NULL; + ccs_client_t client = NULL; + + if (!out_callback ) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); } + if (!in_owner ) { err = cci_check_error (ccErrBadParam); } + if (!in_owner_invalidate_function ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + callback = malloc (sizeof (*callback)); + if (callback) { + *callback = ccs_callback_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + err = ccs_server_client_for_pipe (in_client_pipe, &client); + } + + if (!err) { + err = ccs_pipe_copy (&callback->client_pipe, in_client_pipe); + } + + if (!err) { + err = ccs_pipe_copy (&callback->reply_pipe, in_reply_pipe); + } + + if (!err) { + callback->client_pipe = in_client_pipe; + callback->reply_pipe = in_reply_pipe; + callback->invalid_object_err = in_invalid_object_err; + callback->owner = in_owner; + callback->owner_invalidate = in_owner_invalidate_function; + + err = ccs_client_add_callback (client, callback); + } + + if (!err) { + *out_callback = callback; + callback = NULL; + } + + ccs_callback_release (callback); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +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); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_callback_invalidate (ccs_callback_t io_callback) +{ + cc_int32 err = ccNoError; + + if (!io_callback) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + io_callback->pending = 0; /* client is dead, don't try to talk to it */ + err = io_callback->owner_invalidate (io_callback->owner, io_callback); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_callback_reply_to_client (ccs_callback_t io_callback, + cci_stream_t in_stream) +{ + cc_int32 err = ccNoError; + + if (!io_callback) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + if (io_callback->pending) { + err = ccs_server_send_reply (io_callback->reply_pipe, err, in_stream); + + if (err) { + cci_debug_printf ("WARNING %s() called on a lock belonging to a dead client!", + __FUNCTION__); + } + + io_callback->pending = 0; + } else { + cci_debug_printf ("WARNING %s() called on non-pending callback!", + __FUNCTION__); + } + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_uint32 ccs_callback_is_pending (ccs_callback_t in_callback, + cc_uint32 *out_pending) +{ + cc_int32 err = ccNoError; + + if (!in_callback) { err = cci_check_error (ccErrBadParam); } + if (!out_pending) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_pending = in_callback->pending; + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_callback_is_for_client_pipe (ccs_callback_t in_callback, + ccs_pipe_t in_client_pipe, + cc_uint32 *out_is_for_client_pipe) +{ + cc_int32 err = ccNoError; + + if (!in_callback ) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!out_is_for_client_pipe ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_is_for_client_pipe = (in_callback->client_pipe == in_client_pipe); + } + + return cci_check_error (err); +} + + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_callback_client_pipe (ccs_callback_t in_callback, + ccs_pipe_t *out_client_pipe) +{ + cc_int32 err = ccNoError; + + if (!in_callback ) { err = cci_check_error (ccErrBadParam); } + if (!out_client_pipe) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_client_pipe = in_callback->client_pipe; + } + + return cci_check_error (err); +} diff --git a/src/ccapi/server/ccs_lockref.h b/src/ccapi/server/ccs_callback.h similarity index 50% rename from src/ccapi/server/ccs_lockref.h rename to src/ccapi/server/ccs_callback.h index 2ed09a726..3ebe28d47 100644 --- a/src/ccapi/server/ccs_lockref.h +++ b/src/ccapi/server/ccs_callback.h @@ -24,21 +24,39 @@ * or implied warranty. */ -#ifndef CCS_LOCK_REFERENCE_H -#define CCS_LOCK_REFERENCE_H +#ifndef CCS_CALLBACK_H +#define CCS_CALLBACK_H #include "ccs_types.h" -cc_int32 ccs_lockref_new (ccs_lockref_t *out_lockref, - ccs_client_t in_client_owner, - ccs_lock_t in_lock); +struct ccs_callback_owner_d; +typedef struct ccs_callback_owner_d *ccs_callback_owner_t; -cc_int32 ccs_lockref_release (ccs_lockref_t io_lockref); +typedef cc_int32 (*ccs_callback_owner_invalidate_t) (ccs_callback_owner_t, ccs_callback_t); -cc_int32 ccs_lockref_invalidate (ccs_lockref_t io_lockref); -cc_int32 ccs_lockref_is_for_lock (ccs_lockref_t in_lockref, - ccs_lock_t in_lock, - cc_uint32 *out_is_for_lock); +cc_int32 ccs_callback_new (ccs_callback_t *out_callback, + cc_int32 in_invalid_object_err, + ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + ccs_callback_owner_t in_owner, + ccs_callback_owner_invalidate_t in_owner_invalidate_function); -#endif /* CCS_LOCK_REFERENCE_H */ +cc_int32 ccs_callback_release (ccs_callback_t io_callback); + +cc_int32 ccs_callback_invalidate (ccs_callback_t io_callback); + +cc_int32 ccs_callback_reply_to_client (ccs_callback_t io_callback, + cci_stream_t in_stream); + +cc_uint32 ccs_callback_is_pending (ccs_callback_t in_callback, + cc_uint32 *out_pending); + +cc_int32 ccs_callback_is_for_client_pipe (ccs_callback_t in_callback, + ccs_pipe_t in_client_pipe, + cc_uint32 *out_is_for_client_pipe); + +cc_int32 ccs_callback_client_pipe (ccs_callback_t in_callback, + ccs_pipe_t *out_client_pipe); + +#endif /* CCS_CALLBACK_H */ diff --git a/src/ccapi/server/ccs_ccache.c b/src/ccapi/server/ccs_ccache.c index cafb2bf95..da6a8318f 100644 --- a/src/ccapi/server/ccs_ccache.c +++ b/src/ccapi/server/ccs_ccache.c @@ -39,9 +39,13 @@ struct ccs_ccache_d { cc_uint32 kdc_time_offset_v5_valid; cc_time_t kdc_time_offset_v5; ccs_credentials_list_t credentials; + ccs_callback_array_t change_callbacks; }; -struct ccs_ccache_d ccs_ccache_initializer = { NULL, NULL, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, NULL }; +struct ccs_ccache_d ccs_ccache_initializer = { NULL, NULL, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL }; + +static cc_int32 ccs_ccache_changed (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection); /* ------------------------------------------------------------------------ */ @@ -101,6 +105,10 @@ cc_int32 ccs_ccache_new (ccs_ccache_t *out_ccache, err = ccs_credentials_list_new (&ccache->credentials); } + if (!err) { + err = ccs_callback_array_new (&ccache->change_callbacks); + } + if (!err) { cc_uint64 now = time (NULL); cc_uint64 count = 0; @@ -131,9 +139,10 @@ cc_int32 ccs_ccache_new (ccs_ccache_t *out_ccache, /* ------------------------------------------------------------------------ */ -cc_int32 ccs_ccache_reset (ccs_ccache_t io_ccache, - cc_uint32 in_cred_vers, - const char *in_principal) +cc_int32 ccs_ccache_reset (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cc_uint32 in_cred_vers, + const char *in_principal) { cc_int32 err = ccNoError; char *principal = NULL; @@ -168,6 +177,7 @@ cc_int32 ccs_ccache_reset (ccs_ccache_t io_ccache, io_ccache->credentials = credentials; credentials = NULL; /* take ownership */ + err = ccs_ccache_changed (io_ccache, io_cache_collection); } free (principal); @@ -178,8 +188,9 @@ cc_int32 ccs_ccache_reset (ccs_ccache_t io_ccache, /* ------------------------------------------------------------------------ */ -cc_int32 ccs_ccache_swap_contents (ccs_ccache_t io_source_ccache, - ccs_ccache_t io_destination_ccache) +cc_int32 ccs_ccache_swap_contents (ccs_ccache_t io_source_ccache, + ccs_ccache_t io_destination_ccache, + ccs_cache_collection_t io_cache_collection) { cc_int32 err = ccNoError; @@ -201,6 +212,14 @@ cc_int32 ccs_ccache_swap_contents (ccs_ccache_t io_source_ccache, io_destination_ccache->name = temp_ccache.name; } + if (!err) { + err = ccs_ccache_changed (io_source_ccache, io_cache_collection); + } + + if (!err) { + err = ccs_ccache_changed (io_destination_ccache, io_cache_collection); + } + return cci_check_error (err); } @@ -218,6 +237,7 @@ cc_int32 ccs_ccache_release (ccs_ccache_t io_ccache) free (io_ccache->name); free (io_ccache->principal); ccs_credentials_list_release (io_ccache->credentials); + ccs_callback_array_release (io_ccache->change_callbacks); free (io_ccache); } @@ -292,6 +312,55 @@ static cc_int32 ccs_ccache_changed (ccs_ccache_t io_ccache, err = ccs_cache_collection_changed (io_cache_collection); } + if (!err) { + /* Loop over callbacks sending messages to them */ + cc_uint64 i; + cc_uint64 count = ccs_callback_array_count (io_ccache->change_callbacks); + + 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); + + if (!err) { + cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback); + err = ccs_callback_array_remove (io_ccache->change_callbacks, i); + break; + } + } + + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_invalidate_change_callback (ccs_callback_owner_t io_ccache, + ccs_callback_t in_callback) +{ + cc_int32 err = ccNoError; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!in_callback) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + /* Remove callback */ + ccs_ccache_t ccache = (ccs_ccache_t) io_ccache; + cc_uint64 i; + cc_uint64 count = ccs_callback_array_count (ccache->change_callbacks); + + for (i = 0; !err && i < count; i++) { + ccs_callback_t callback = ccs_callback_array_object_at_index (ccache->change_callbacks, i); + + if (callback == in_callback) { + cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback); + err = ccs_callback_array_remove (ccache->change_callbacks, i); + break; + } + } + } + return cci_check_error (err); } @@ -760,6 +829,49 @@ static cc_int32 ccs_ccache_get_change_time (ccs_ccache_t io_ccache, /* ------------------------------------------------------------------------ */ +static cc_int32 ccs_ccache_wait_for_change (ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cc_uint32 *out_will_block) +{ + cc_int32 err = ccNoError; + ccs_callback_t callback = NULL; + + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_reply_pipe )) { err = cci_check_error (ccErrBadParam); } + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + 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); + } + + 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 (!err) { + *out_will_block = 1; + } + + ccs_callback_release (callback); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + static cc_int32 ccs_ccache_get_kdc_time_offset (ccs_ccache_t io_ccache, ccs_cache_collection_t io_cache_collection, cci_stream_t in_request_data, @@ -972,6 +1084,11 @@ cc_int32 ccs_ccache_handle_message (ccs_pipe_t in_client_pipe, err = ccs_ccache_get_change_time (io_ccache, io_cache_collection, in_request_data, reply_data); + } 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); + } 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, in_request_data, reply_data); diff --git a/src/ccapi/server/ccs_ccache.h b/src/ccapi/server/ccs_ccache.h index ea1b03c07..ba32752ab 100644 --- a/src/ccapi/server/ccs_ccache.h +++ b/src/ccapi/server/ccs_ccache.h @@ -35,12 +35,14 @@ cc_int32 ccs_ccache_new (ccs_ccache_t *out_ccache, const char *in_principal, ccs_ccache_list_t io_ccache_list); -cc_int32 ccs_ccache_reset (ccs_ccache_t io_ccache, - cc_uint32 in_cred_vers, - const char *in_principal); +cc_int32 ccs_ccache_reset (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cc_uint32 in_cred_vers, + const char *in_principal); -cc_int32 ccs_ccache_swap_contents (ccs_ccache_t io_source_ccache, - ccs_ccache_t io_destination_ccache); +cc_int32 ccs_ccache_swap_contents (ccs_ccache_t io_source_ccache, + ccs_ccache_t io_destination_ccache, + ccs_cache_collection_t io_cache_collection); cc_int32 ccs_ccache_release (ccs_ccache_t io_ccache); diff --git a/src/ccapi/server/ccs_client.c b/src/ccapi/server/ccs_client.c index f23792a58..0cb19dae9 100644 --- a/src/ccapi/server/ccs_client.c +++ b/src/ccapi/server/ccs_client.c @@ -28,7 +28,7 @@ struct ccs_client_d { ccs_pipe_t client_pipe; - ccs_lockref_array_t lockrefs; + ccs_callbackref_array_t callbacks; /* references, not owner */ }; struct ccs_client_d ccs_client_initializer = { CCS_PIPE_NULL, NULL }; @@ -54,12 +54,14 @@ cc_int32 ccs_client_new (ccs_client_t *out_client, } if (!err) { - err = ccs_lockref_array_new (&client->lockrefs); + err = ccs_callbackref_array_new (&client->callbacks); } - + if (!err) { - client->client_pipe = in_client_pipe; + err = ccs_pipe_copy (&client->client_pipe, in_client_pipe); + } + if (!err) { *out_client = client; client = NULL; } @@ -78,7 +80,8 @@ cc_int32 ccs_client_release (ccs_client_t io_client) if (!io_client) { err = cci_check_error (ccErrBadParam); } if (!err) { - ccs_lockref_array_release (io_client->lockrefs); + ccs_callbackref_array_release (io_client->callbacks); + ccs_pipe_release (io_client->client_pipe); free (io_client); } @@ -87,25 +90,18 @@ cc_int32 ccs_client_release (ccs_client_t io_client) /* ------------------------------------------------------------------------ */ -cc_int32 ccs_client_add_lockref (ccs_client_t io_client, - ccs_lock_t in_lock) +cc_int32 ccs_client_add_callback (ccs_client_t io_client, + ccs_callback_t in_callback) { cc_int32 err = ccNoError; - ccs_lockref_t lockref = NULL; - - if (!io_client) { err = cci_check_error (ccErrBadParam); } - if (!err) { - err = ccs_lockref_new (&lockref, io_client, in_lock); - } - - if (!err) { - err = ccs_lockref_array_insert (io_client->lockrefs, lockref, - ccs_lockref_array_count (io_client->lockrefs)); - if (!err) { lockref = NULL; /* take ownership */ } - } + if (!io_client ) { err = cci_check_error (ccErrBadParam); } + if (!in_callback) { err = cci_check_error (ccErrBadParam); } - ccs_lockref_release (lockref); + if (!err) { + err = ccs_callbackref_array_insert (io_client->callbacks, in_callback, + ccs_callback_array_count (io_client->callbacks)); + } return cci_check_error (err); } @@ -113,8 +109,8 @@ cc_int32 ccs_client_add_lockref (ccs_client_t io_client, /* ------------------------------------------------------------------------ */ -cc_int32 ccs_client_remove_lockref (ccs_client_t io_client, - ccs_lock_t in_lock) +cc_int32 ccs_client_remove_callback (ccs_client_t io_client, + ccs_callback_t in_callback) { cc_int32 err = ccNoError; cc_uint32 found_lock = 0; @@ -123,19 +119,18 @@ cc_int32 ccs_client_remove_lockref (ccs_client_t io_client, if (!err) { cc_uint64 i; - cc_uint64 lock_count = ccs_lockref_array_count (io_client->lockrefs); + cc_uint64 lock_count = ccs_callbackref_array_count (io_client->callbacks); for (i = 0; !err && i < lock_count; i++) { - ccs_lockref_t lockref = ccs_lockref_array_object_at_index (io_client->lockrefs, i); - - err = ccs_lockref_is_for_lock (lockref, in_lock, &found_lock); + ccs_callback_t callback = ccs_callbackref_array_object_at_index (io_client->callbacks, i); - if (!err && found_lock) { - err = ccs_lockref_invalidate (lockref); + if (callback == in_callback) { + err = ccs_callback_invalidate (callback); if (!err) { - cci_debug_printf ("%s: Removing lockref %p.", __FUNCTION__, lockref); - err = ccs_lockref_array_remove (io_client->lockrefs, i); + cci_debug_printf ("%s: Removing callback reference %p.", + __FUNCTION__, callback); + err = ccs_callbackref_array_remove (io_client->callbacks, i); break; } } @@ -143,7 +138,7 @@ cc_int32 ccs_client_remove_lockref (ccs_client_t io_client, } if (!err && !found_lock) { - cci_debug_printf ("%s: WARNING! lockref not found.", __FUNCTION__); + cci_debug_printf ("%s: WARNING! callback not found.", __FUNCTION__); } return cci_check_error (err); diff --git a/src/ccapi/server/ccs_client.h b/src/ccapi/server/ccs_client.h index 3b6268247..fe3ea71b9 100644 --- a/src/ccapi/server/ccs_client.h +++ b/src/ccapi/server/ccs_client.h @@ -34,11 +34,11 @@ cc_int32 ccs_client_new (ccs_client_t *out_client, cc_int32 ccs_client_release (ccs_client_t io_client); -cc_int32 ccs_client_add_lockref (ccs_client_t io_client, - ccs_lock_t in_lock); +cc_int32 ccs_client_add_callback (ccs_client_t io_client, + ccs_callback_t in_lock); -cc_int32 ccs_client_remove_lockref (ccs_client_t io_client, - ccs_lock_t in_lock); +cc_int32 ccs_client_remove_callback (ccs_client_t io_client, + ccs_callback_t in_lock); cc_int32 ccs_client_uses_pipe (ccs_client_t in_client, ccs_pipe_t in_pipe, diff --git a/src/ccapi/server/ccs_common.h b/src/ccapi/server/ccs_common.h index 42a427c08..3710b11a3 100644 --- a/src/ccapi/server/ccs_common.h +++ b/src/ccapi/server/ccs_common.h @@ -42,7 +42,7 @@ #include "ccs_lock_state.h" #include "ccs_pipe.h" #include "ccs_client.h" -#include "ccs_lockref.h" +#include "ccs_callback.h" #include "ccs_server.h" #endif /* CCS_COMMON_H */ diff --git a/src/ccapi/server/ccs_credentials_iterator.c b/src/ccapi/server/ccs_credentials_iterator.c index f95dc4842..e36c7f500 100644 --- a/src/ccapi/server/ccs_credentials_iterator.c +++ b/src/ccapi/server/ccs_credentials_iterator.c @@ -28,10 +28,10 @@ /* ------------------------------------------------------------------------ */ -static cc_int32 ccs_credentials_iterator_release (ccs_credentials_iterator_t io_credentials_iterator, - ccs_ccache_t io_ccache, - cci_stream_t in_request_data, - cci_stream_t io_reply_data) +static cc_int32 ccs_credentials_iterator_release (ccs_credentials_iterator_t io_credentials_iterator, + ccs_ccache_t io_ccache, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) { cc_int32 err = ccNoError; @@ -49,10 +49,10 @@ static cc_int32 ccs_credentials_iterator_release (ccs_credentials_iterator_t io /* ------------------------------------------------------------------------ */ -static cc_int32 ccs_credentials_iterator_next (ccs_credentials_iterator_t io_credentials_iterator, - ccs_ccache_t io_ccache, - cci_stream_t in_request_data, - cci_stream_t io_reply_data) +static cc_int32 ccs_credentials_iterator_next (ccs_credentials_iterator_t io_credentials_iterator, + ccs_ccache_t io_ccache, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) { cc_int32 err = ccNoError; ccs_credentials_t credentials = NULL; diff --git a/src/ccapi/server/ccs_list.c b/src/ccapi/server/ccs_list.c index a8f7d96d6..2fd86da0f 100644 --- a/src/ccapi/server/ccs_list.c +++ b/src/ccapi/server/ccs_list.c @@ -29,14 +29,14 @@ /* ------------------------------------------------------------------------ */ -static cc_int32 ccs_cache_collection_list_object_release (void *io_object) +static cc_int32 ccs_cache_collection_list_object_release (ccs_list_object_t io_object) { return cci_check_error (ccs_cache_collection_release ((ccs_cache_collection_t) io_object)); } /* ------------------------------------------------------------------------ */ -static cc_int32 ccs_cache_collection_list_object_compare_identifier (void *in_cache_collection, +static cc_int32 ccs_cache_collection_list_object_compare_identifier (ccs_list_object_t in_cache_collection, cci_identifier_t in_identifier, cc_uint32 *out_equal) { @@ -70,7 +70,7 @@ cc_int32 ccs_cache_collection_list_find (ccs_cache_collection_list_t in_list, cci_identifier_t in_identifier, ccs_cache_collection_t *out_cache_collection) { - return ccs_list_find (in_list, in_identifier, (ccs_object_t *) out_cache_collection); + return ccs_list_find (in_list, in_identifier, (ccs_list_object_t *) out_cache_collection); } /* ------------------------------------------------------------------------ */ @@ -78,7 +78,7 @@ cc_int32 ccs_cache_collection_list_find (ccs_cache_collection_list_t in_list, cc_int32 ccs_cache_collection_list_add (ccs_cache_collection_list_t io_list, ccs_cache_collection_t in_cache_collection) { - return ccs_list_add (io_list, in_cache_collection); + return ccs_list_add (io_list, (ccs_list_object_t) in_cache_collection); } /* ------------------------------------------------------------------------ */ @@ -100,16 +100,16 @@ cc_int32 ccs_cache_collection_list_release (ccs_cache_collection_list_t io_list) /* ------------------------------------------------------------------------ */ -static cc_int32 ccs_ccache_list_object_release (void *io_ccache) +static cc_int32 ccs_ccache_list_object_release (ccs_list_object_t io_ccache) { return cci_check_error (ccs_ccache_release ((ccs_ccache_t) io_ccache)); } /* ------------------------------------------------------------------------ */ -static cc_int32 ccs_ccache_list_object_compare_identifier (void *in_ccache, - cci_identifier_t in_identifier, - cc_uint32 *out_equal) +static cc_int32 ccs_ccache_list_object_compare_identifier (ccs_list_object_t in_ccache, + cci_identifier_t in_identifier, + cc_uint32 *out_equal) { return ccs_ccache_compare_identifier ((ccs_ccache_t) in_ccache, in_identifier, @@ -149,7 +149,7 @@ cc_int32 ccs_ccache_list_find (ccs_ccache_list_t in_list, cci_identifier_t in_identifier, ccs_ccache_t *out_ccache) { - return ccs_list_find (in_list, in_identifier, (ccs_object_t *) out_ccache); + return ccs_list_find (in_list, in_identifier, (ccs_list_object_t *) out_ccache); } /* ------------------------------------------------------------------------ */ @@ -167,7 +167,7 @@ cc_int32 ccs_ccache_list_find_iterator (ccs_ccache_list_t in_list, cc_int32 ccs_ccache_list_add (ccs_ccache_list_t io_list, ccs_ccache_t in_ccache) { - return ccs_list_add (io_list, in_ccache); + return ccs_list_add (io_list, (ccs_list_object_t) in_ccache); } /* ------------------------------------------------------------------------ */ @@ -214,7 +214,7 @@ cc_int32 ccs_ccache_list_iterator_clone (ccs_ccache_list_iterator_t in_list_ite cc_int32 ccs_ccache_list_iterator_next (ccs_ccache_list_iterator_t io_list_iterator, ccs_ccache_t *out_ccache) { - return ccs_list_iterator_next (io_list_iterator, (ccs_object_t *) out_ccache); + return ccs_list_iterator_next (io_list_iterator, (ccs_list_object_t *) out_ccache); } /* ------------------------------------------------------------------------ */ @@ -228,16 +228,16 @@ cc_int32 ccs_ccache_list_iterator_release (ccs_ccache_list_iterator_t io_list_it /* ------------------------------------------------------------------------ */ -static cc_int32 ccs_credentials_list_object_release (void *io_object) +static cc_int32 ccs_credentials_list_object_release (ccs_list_object_t io_object) { return cci_check_error (ccs_credentials_release ((ccs_credentials_t) io_object)); } /* ------------------------------------------------------------------------ */ -static cc_int32 ccs_credentials_list_object_compare_identifier (void *in_credentials, - cci_identifier_t in_identifier, - cc_uint32 *out_equal) +static cc_int32 ccs_credentials_list_object_compare_identifier (ccs_list_object_t in_credentials, + cci_identifier_t in_identifier, + cc_uint32 *out_equal) { return ccs_credentials_compare_identifier ((ccs_credentials_t) in_credentials, in_identifier, @@ -277,7 +277,7 @@ cc_int32 ccs_credentials_list_find (ccs_credentials_list_t in_list, cci_identifier_t in_identifier, ccs_credentials_t *out_credentials) { - return ccs_list_find (in_list, in_identifier, (ccs_object_t *) out_credentials); + return ccs_list_find (in_list, in_identifier, (ccs_list_object_t *) out_credentials); } /* ------------------------------------------------------------------------ */ @@ -295,7 +295,7 @@ cc_int32 ccs_credentials_list_find_iterator (ccs_credentials_list_t in cc_int32 ccs_credentials_list_add (ccs_credentials_list_t io_list, ccs_credentials_t in_credential) { - return ccs_list_add (io_list, in_credential); + return ccs_list_add (io_list, (ccs_list_object_t) in_credential); } /* ------------------------------------------------------------------------ */ @@ -334,7 +334,7 @@ cc_int32 ccs_credentials_list_iterator_clone (ccs_credentials_list_iterator_t i cc_int32 ccs_credentials_list_iterator_next (ccs_credentials_list_iterator_t io_list_iterator, ccs_credentials_t *out_credential) { - return ccs_list_iterator_next (io_list_iterator, (ccs_object_t *) out_credential); + return ccs_list_iterator_next (io_list_iterator, (ccs_list_object_t *) out_credential); } /* ------------------------------------------------------------------------ */ diff --git a/src/ccapi/server/ccs_list_internal.c b/src/ccapi/server/ccs_list_internal.c index a930fba33..2b3e27f29 100644 --- a/src/ccapi/server/ccs_list_internal.c +++ b/src/ccapi/server/ccs_list_internal.c @@ -67,6 +67,7 @@ static cc_int32 ccs_list_iterator_object_release (cci_array_object_t io_list_ite static cc_int32 ccs_list_iterator_update (ccs_list_iterator_t io_list_iterator, ccs_list_action_enum in_action, cc_uint64 in_object_index); + #pragma mark - /* ------------------------------------------------------------------------ */ @@ -124,7 +125,7 @@ cc_int32 ccs_list_release (ccs_list_t io_list) cc_uint64 i; for (i = 0; i < cci_array_count (io_list->iterators); i++) { - ccs_list_iterator_release (cci_array_object_at_index (io_list->iterators, i)); + ccs_list_iterator_release ((ccs_list_iterator_t) cci_array_object_at_index (io_list->iterators, i)); } free (io_list->iterators); cci_array_release (io_list->objects); @@ -183,6 +184,14 @@ cc_int32 ccs_list_count (ccs_list_t in_list, /* ------------------------------------------------------------------------ */ +static ccs_list_iterator_t ccs_list_iterator_at_index (ccs_list_t in_list, + cc_uint64 in_index) +{ + return (ccs_list_iterator_t) cci_array_object_at_index (in_list->iterators, in_index); +} + +/* ------------------------------------------------------------------------ */ + static cc_int32 ccs_list_find_index (ccs_list_t in_list, cci_identifier_t in_identifier, cc_uint64 *out_object_index) @@ -218,9 +227,9 @@ static cc_int32 ccs_list_find_index (ccs_list_t in_list, } /* ------------------------------------------------------------------------ */ -cc_int32 ccs_list_find (ccs_list_t in_list, - cci_identifier_t in_identifier, - ccs_object_t *out_object) +cc_int32 ccs_list_find (ccs_list_t in_list, + cci_identifier_t in_identifier, + ccs_list_object_t *out_object) { cc_int32 err = ccNoError; cc_uint64 i; @@ -258,7 +267,7 @@ static cc_int32 ccs_list_find_iterator_index (ccs_list_t in_list, for (i = 0; !err && i < cci_array_count (in_list->iterators); i++) { cc_uint32 equal = 0; - ccs_list_iterator_t iterator = cci_array_object_at_index (in_list->iterators, i); + ccs_list_iterator_t iterator = ccs_list_iterator_at_index (in_list, i); err = cci_identifier_compare (iterator->identifier, in_identifier, &equal); @@ -294,7 +303,7 @@ cc_int32 ccs_list_find_iterator (ccs_list_t in_list, } if (!err) { - *out_list_iterator = cci_array_object_at_index (in_list->iterators, i); + *out_list_iterator = ccs_list_iterator_at_index (in_list, i); } return cci_check_error (err); @@ -302,8 +311,8 @@ cc_int32 ccs_list_find_iterator (ccs_list_t in_list, /* ------------------------------------------------------------------------ */ -cc_int32 ccs_list_add (ccs_list_t io_list, - ccs_object_t in_object) +cc_int32 ccs_list_add (ccs_list_t io_list, + ccs_list_object_t in_object) { cc_int32 err = ccNoError; cc_uint64 add_index; @@ -322,7 +331,7 @@ cc_int32 ccs_list_add (ccs_list_t io_list, cc_uint64 i; for (i = 0; !err && i < cci_array_count (io_list->iterators); i++) { - ccs_list_iterator_t iterator = cci_array_object_at_index (io_list->iterators, i); + ccs_list_iterator_t iterator = ccs_list_iterator_at_index (io_list, i); err = ccs_list_iterator_update (iterator, ccs_list_action_insert, add_index); } @@ -355,7 +364,7 @@ cc_int32 ccs_list_remove (ccs_list_t io_list, cc_uint64 i; for (i = 0; !err && i < cci_array_count (io_list->iterators); i++) { - ccs_list_iterator_t iterator = cci_array_object_at_index (io_list->iterators, i); + ccs_list_iterator_t iterator = ccs_list_iterator_at_index (io_list, i); err = ccs_list_iterator_update (iterator, ccs_list_action_remove, remove_index); } @@ -388,7 +397,7 @@ cc_int32 ccs_list_push_front (ccs_list_t io_list, cc_uint64 i; for (i = 0; !err && i < cci_array_count (io_list->iterators); i++) { - ccs_list_iterator_t iterator = cci_array_object_at_index (io_list->iterators, i); + ccs_list_iterator_t iterator = ccs_list_iterator_at_index (io_list, i); err = ccs_list_iterator_update (iterator, ccs_list_action_push_front, @@ -430,7 +439,8 @@ static cc_int32 ccs_list_iterator_new (ccs_list_iterator_t *out_list_iterator, list_iterator->current = 0; err = cci_array_insert (io_list->iterators, - list_iterator, cci_array_count (io_list->iterators)); + (cci_array_object_t) list_iterator, + cci_array_count (io_list->iterators)); } if (!err) { @@ -532,7 +542,7 @@ cc_int32 ccs_list_iterator_release (ccs_list_iterator_t io_list_iterator) /* ------------------------------------------------------------------------ */ cc_int32 ccs_list_iterator_current (ccs_list_iterator_t io_list_iterator, - ccs_object_t *out_object) + ccs_list_object_t *out_object) { cc_int32 err = ccNoError; @@ -554,7 +564,7 @@ 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_object_t *out_object) + ccs_list_object_t *out_object) { cc_int32 err = ccNoError; diff --git a/src/ccapi/server/ccs_list_internal.h b/src/ccapi/server/ccs_list_internal.h index 83320a5eb..5bb52d061 100644 --- a/src/ccapi/server/ccs_list_internal.h +++ b/src/ccapi/server/ccs_list_internal.h @@ -28,6 +28,7 @@ #define CCS_LIST_INTERNAL_H #include "cci_common.h" +#include "cci_array_internal.h" struct ccs_list_d; typedef struct ccs_list_d *ccs_list_t; @@ -35,9 +36,9 @@ typedef struct ccs_list_d *ccs_list_t; struct ccs_list_iterator_d; typedef struct ccs_list_iterator_d *ccs_list_iterator_t; -typedef void *ccs_object_t; -typedef cc_int32 (*ccs_object_release_t) (ccs_object_t); -typedef cc_int32 (*ccs_object_compare_identifier_t) (ccs_object_t, cci_identifier_t, cc_uint32 *); +typedef cci_array_object_t ccs_list_object_t; +typedef cc_int32 (*ccs_object_release_t) (ccs_list_object_t); +typedef cc_int32 (*ccs_object_compare_identifier_t) (ccs_list_object_t, cci_identifier_t, cc_uint32 *); cc_int32 ccs_list_new (ccs_list_t *out_list, cc_int32 in_object_not_found_err, @@ -56,16 +57,16 @@ cc_int32 ccs_list_release_iterator (ccs_list_t io_list, cc_int32 ccs_list_count (ccs_list_t in_list, cc_uint64 *out_count); -cc_int32 ccs_list_find (ccs_list_t in_list, - cci_identifier_t in_identifier, - ccs_object_t *out_object); +cc_int32 ccs_list_find (ccs_list_t in_list, + cci_identifier_t in_identifier, + ccs_list_object_t *out_object); cc_int32 ccs_list_find_iterator (ccs_list_t in_list, cci_identifier_t in_identifier, ccs_list_iterator_t *out_list_iterator); -cc_int32 ccs_list_add (ccs_list_t io_list, - ccs_object_t in_object); +cc_int32 ccs_list_add (ccs_list_t io_list, + ccs_list_object_t in_object); cc_int32 ccs_list_remove (ccs_list_t io_list, cci_identifier_t in_identifier); @@ -81,10 +82,10 @@ cc_int32 ccs_list_iterator_clone (ccs_list_iterator_t in_list_iterator, ccs_list_iterator_t *out_list_iterator); cc_int32 ccs_list_iterator_current (ccs_list_iterator_t io_list_iterator, - ccs_object_t *out_object); + ccs_list_object_t *out_object); cc_int32 ccs_list_iterator_next (ccs_list_iterator_t io_list_iterator, - ccs_object_t *out_object); + ccs_list_object_t *out_object); cc_int32 ccs_list_iterator_release (ccs_list_iterator_t io_list_iterator); diff --git a/src/ccapi/server/ccs_lock.c b/src/ccapi/server/ccs_lock.c index 3fa761efd..1934640fe 100644 --- a/src/ccapi/server/ccs_lock.c +++ b/src/ccapi/server/ccs_lock.c @@ -28,14 +28,14 @@ struct ccs_lock_d { cc_uint32 type; - cc_uint32 pending; - cc_int32 invalid_object_err; - ccs_pipe_t client_pipe; - ccs_pipe_t reply_pipe; - ccs_lock_state_t lock_state_owner; /* pointer to owner */ + ccs_lock_state_t lock_state_owner; + ccs_callback_t callback; }; -struct ccs_lock_d ccs_lock_initializer = { 0, 1, 1, CCS_PIPE_NULL, CCS_PIPE_NULL, NULL }; +struct ccs_lock_d ccs_lock_initializer = { 0, NULL, NULL }; + +static cc_int32 ccs_lock_invalidate_callback (ccs_callback_owner_t io_lock, + ccs_callback_t in_callback); /* ------------------------------------------------------------------------ */ @@ -48,7 +48,6 @@ cc_int32 ccs_lock_new (ccs_lock_t *out_lock, { cc_int32 err = ccNoError; ccs_lock_t lock = NULL; - ccs_client_t client = NULL; if (!out_lock ) { err = cci_check_error (ccErrBadParam); } if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } @@ -72,19 +71,17 @@ cc_int32 ccs_lock_new (ccs_lock_t *out_lock, } if (!err) { - err = ccs_server_client_for_pipe (in_client_pipe, &client); - } - - if (!err) { - lock->client_pipe = in_client_pipe; - lock->reply_pipe = in_reply_pipe; lock->type = in_type; - lock->invalid_object_err = in_invalid_object_err; lock->lock_state_owner = in_lock_state_owner; - - err = ccs_client_add_lockref (client, lock); + + err = ccs_callback_new (&lock->callback, + in_invalid_object_err, + in_client_pipe, + in_reply_pipe, + (ccs_callback_owner_t) lock, + ccs_lock_invalidate_callback); } - + if (!err) { *out_lock = lock; lock = NULL; @@ -100,26 +97,11 @@ cc_int32 ccs_lock_new (ccs_lock_t *out_lock, cc_int32 ccs_lock_release (ccs_lock_t io_lock) { cc_int32 err = ccNoError; - ccs_client_t client = NULL; if (!io_lock) { err = cci_check_error (ccErrBadParam); } - - if (!err && io_lock->pending) { - err = ccs_server_send_reply (io_lock->reply_pipe, - io_lock->invalid_object_err, NULL); - io_lock->pending = 0; - } - - if (!err) { - err = ccs_server_client_for_pipe (io_lock->client_pipe, &client); - } - - if (!err) { - err = ccs_client_remove_lockref (client, io_lock); - } - if (!err) { + free (io_lock->callback); free (io_lock); } @@ -128,18 +110,21 @@ cc_int32 ccs_lock_release (ccs_lock_t io_lock) /* ------------------------------------------------------------------------ */ -cc_int32 ccs_lock_invalidate (ccs_lock_t io_lock) +static cc_int32 ccs_lock_invalidate_callback (ccs_callback_owner_t io_lock, + ccs_callback_t in_callback) { cc_int32 err = ccNoError; - if (!io_lock) { err = cci_check_error (ccErrBadParam); } + if (!io_lock ) { err = cci_check_error (ccErrBadParam); } + if (!in_callback) { err = cci_check_error (ccErrBadParam); } if (!err) { - io_lock->pending = 0; /* client is dead, don't try to talk to it */ - err = ccs_lock_state_invalidate_lock (io_lock->lock_state_owner, io_lock); + ccs_lock_t lock = (ccs_lock_t) io_lock; + + err = ccs_lock_state_invalidate_lock (lock->lock_state_owner, lock); } - return cci_check_error (err); + return cci_check_error (err); } /* ------------------------------------------------------------------------ */ @@ -151,20 +136,7 @@ cc_int32 ccs_lock_grant_lock (ccs_lock_t io_lock) if (!io_lock) { err = cci_check_error (ccErrBadParam); } if (!err) { - if (io_lock->pending) { - err = ccs_server_send_reply (io_lock->reply_pipe, err, NULL); - - if (err) { - cci_debug_printf ("WARNING %s() called on a lock belonging to a dead client!", - __FUNCTION__); - } - - io_lock->pending = 0; - io_lock->reply_pipe = CCS_PIPE_NULL; - } else { - cci_debug_printf ("WARNING %s() called on non-pending lock!", - __FUNCTION__); - } + err = ccs_callback_reply_to_client (io_lock->callback, NULL); } return cci_check_error (err); @@ -181,7 +153,7 @@ cc_uint32 ccs_lock_is_pending (ccs_lock_t in_lock, if (!out_pending) { err = cci_check_error (ccErrBadParam); } if (!err) { - *out_pending = in_lock->pending; + err = ccs_callback_is_pending (in_lock->callback, out_pending); } return cci_check_error (err); @@ -253,7 +225,8 @@ cc_int32 ccs_lock_is_for_client_pipe (ccs_lock_t in_lock, if (!out_is_for_client_pipe ) { err = cci_check_error (ccErrBadParam); } if (!err) { - *out_is_for_client_pipe = (in_lock->client_pipe == in_client_pipe); + err = ccs_callback_is_for_client_pipe (in_lock->callback, in_client_pipe, + out_is_for_client_pipe); } return cci_check_error (err); @@ -271,7 +244,7 @@ cc_int32 ccs_lock_client_pipe (ccs_lock_t in_lock, if (!out_client_pipe) { err = cci_check_error (ccErrBadParam); } if (!err) { - *out_client_pipe = in_lock->client_pipe; + err = ccs_callback_client_pipe (in_lock->callback, out_client_pipe); } return cci_check_error (err); diff --git a/src/ccapi/server/ccs_lock.h b/src/ccapi/server/ccs_lock.h index bed0a9eab..d6f754860 100644 --- a/src/ccapi/server/ccs_lock.h +++ b/src/ccapi/server/ccs_lock.h @@ -38,8 +38,6 @@ cc_int32 ccs_lock_new (ccs_lock_t *out_lock, cc_int32 ccs_lock_release (ccs_lock_t io_lock); -cc_int32 ccs_lock_invalidate (ccs_lock_t io_lock); - cc_int32 ccs_lock_grant_lock (ccs_lock_t io_lock); cc_uint32 ccs_lock_is_pending (ccs_lock_t in_lock, diff --git a/src/ccapi/server/ccs_lockref.c b/src/ccapi/server/ccs_lockref.c deleted file mode 100644 index 78f80ae5d..000000000 --- a/src/ccapi/server/ccs_lockref.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * $Header$ - * - * Copyright 2006 Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. Furthermore if you modify this software you must label - * your software as modified software and not distribute it in such a - * fashion that it might be confused with the original M.I.T. software. - * M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -#include "ccs_common.h" - -struct ccs_lockref_d { - ccs_client_t client_owner; - ccs_lock_t lock; -}; - -struct ccs_lockref_d ccs_lockref_initializer = { NULL, NULL }; - -/* ------------------------------------------------------------------------ */ - -cc_int32 ccs_lockref_new (ccs_lockref_t *out_lockref, - ccs_client_t in_client_owner, - ccs_lock_t in_lock) -{ - cc_int32 err = ccNoError; - ccs_lockref_t lockref = NULL; - - if (!out_lockref ) { err = cci_check_error (ccErrBadParam); } - if (!in_client_owner) { err = cci_check_error (ccErrBadParam); } - if (!in_lock ) { err = cci_check_error (ccErrBadParam); } - - if (!err) { - lockref = malloc (sizeof (*lockref)); - if (lockref) { - *lockref = ccs_lockref_initializer; - } else { - err = cci_check_error (ccErrNoMem); - } - } - - if (!err) { - lockref->client_owner = in_client_owner; - lockref->lock = in_lock; - - *out_lockref = lockref; - lockref = NULL; - } - - ccs_lockref_release (lockref); - - return cci_check_error (err); -} - -/* ------------------------------------------------------------------------ */ - -cc_int32 ccs_lockref_release (ccs_lockref_t io_lockref) -{ - cc_int32 err = ccNoError; - - if (!io_lockref) { err = cci_check_error (ccErrBadParam); } - - if (!err) { - if (io_lockref->lock) { - ccs_lock_invalidate (io_lockref->lock); - } - free (io_lockref); - } - - return cci_check_error (err); -} - -/* ------------------------------------------------------------------------ */ - -cc_int32 ccs_lockref_invalidate (ccs_lockref_t io_lockref) -{ - cc_int32 err = ccNoError; - - if (!io_lockref) { err = cci_check_error (ccErrBadParam); } - - if (!err) { - io_lockref->lock = NULL; /* so we don't loop */ - } - - return cci_check_error (err); -} - -/* ------------------------------------------------------------------------ */ - -cc_int32 ccs_lockref_is_for_lock (ccs_lockref_t in_lockref, - ccs_lock_t in_lock, - cc_uint32 *out_is_for_lock) -{ - cc_int32 err = ccNoError; - - if (!in_lockref ) { err = cci_check_error (ccErrBadParam); } - if (!in_lock ) { err = cci_check_error (ccErrBadParam); } - if (!out_is_for_lock) { err = cci_check_error (ccErrBadParam); } - - if (!err) { - *out_is_for_lock = (in_lockref->lock == in_lock); - } - - return cci_check_error (err); -} diff --git a/src/ccapi/server/ccs_types.h b/src/ccapi/server/ccs_types.h index f1889aa2d..46767f02d 100644 --- a/src/ccapi/server/ccs_types.h +++ b/src/ccapi/server/ccs_types.h @@ -33,7 +33,9 @@ struct cci_array_d; typedef struct cci_array_d *ccs_client_array_t; -typedef struct cci_array_d *ccs_lockref_array_t; +typedef struct cci_array_d *ccs_callback_array_t; + +typedef struct cci_array_d *ccs_callbackref_array_t; typedef struct cci_array_d *ccs_lock_array_t; @@ -60,8 +62,8 @@ typedef int ccs_pipe_t; /* Unix domain socket */ #endif #pragma mark - -struct ccs_lockref_d; -typedef struct ccs_lockref_d *ccs_lockref_t; +struct ccs_callback_d; +typedef struct ccs_callback_d *ccs_callback_t; struct ccs_list_d; struct ccs_list_iterator_d; -- 2.26.2