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);
}
}
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++;
}
}
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);
}
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;
#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;
/* ------------------------------------------------------------------------ */
-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));
}
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);
}
/* ------------------------------------------------------------------------ */
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);
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
-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));
}
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);
}
/* ------------------------------------------------------------------------ */
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);
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
-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);
}
#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 */
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 };
/* ------------------------------------------------------------------------ */
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);
}
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);
}
}
}
+ 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);
}
}
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) {
/* ------------------------------------------------------------------------ */
+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)
&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,
&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;
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);
--- /dev/null
+/*
+ * $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);
+}
* 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 */
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);
/* ------------------------------------------------------------------------ */
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;
/* ------------------------------------------------------------------------ */
-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;
io_ccache->credentials = credentials;
credentials = NULL; /* take ownership */
+ err = ccs_ccache_changed (io_ccache, io_cache_collection);
}
free (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 err = ccNoError;
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);
}
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);
}
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);
}
/* ------------------------------------------------------------------------ */
+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,
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);
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);
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 };
}
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;
}
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);
}
/* ------------------------------------------------------------------------ */
-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);
}
/* ------------------------------------------------------------------------ */
-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;
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;
}
}
}
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);
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,
#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 */
/* ------------------------------------------------------------------------ */
-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;
/* ------------------------------------------------------------------------ */
-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;
/* ------------------------------------------------------------------------ */
-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)
{
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);
}
/* ------------------------------------------------------------------------ */
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);
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
-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,
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);
}
/* ------------------------------------------------------------------------ */
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);
}
/* ------------------------------------------------------------------------ */
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);
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
-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,
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);
}
/* ------------------------------------------------------------------------ */
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);
}
/* ------------------------------------------------------------------------ */
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);
}
/* ------------------------------------------------------------------------ */
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 -
/* ------------------------------------------------------------------------ */
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);
/* ------------------------------------------------------------------------ */
+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)
}
/* ------------------------------------------------------------------------ */
-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;
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);
}
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);
/* ------------------------------------------------------------------------ */
-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;
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);
}
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);
}
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,
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) {
/* ------------------------------------------------------------------------ */
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;
/* ------------------------------------------------------------------------ */
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;
#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;
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,
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);
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);
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);
/* ------------------------------------------------------------------------ */
{
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); }
}
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;
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);
}
/* ------------------------------------------------------------------------ */
-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);
}
/* ------------------------------------------------------------------------ */
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);
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);
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);
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);
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,
+++ /dev/null
-/*
- * $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);
-}
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;
#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;