summaryrefslogtreecommitdiffstats
path: root/src/ccapi/server/ccs_cache_collection.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ccapi/server/ccs_cache_collection.c')
-rw-r--r--src/ccapi/server/ccs_cache_collection.c111
1 files changed, 107 insertions, 4 deletions
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 };
/* ------------------------------------------------------------------------ */
@@ -70,6 +71,10 @@ cc_int32 ccs_cache_collection_new (ccs_cache_collection_t *out_cache_collection)
}
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);