{
cc_int32 err = ccNoError;
cc_uint64 new_max_count = 0;
- cci_array_object_t *objects = NULL;
if (!io_array) { err = cci_check_error (ccErrBadParam); }
}
}
- if (!err) {
- objects = io_array->objects;
+ if (!err && io_array->max_count != new_max_count) {
+ cci_array_object_t *objects = io_array->objects;
if (!objects) {
objects = malloc (new_max_count * sizeof (*objects));
objects = realloc (objects, new_max_count * sizeof (*objects));
}
if (!objects) { err = cci_check_error (ccErrNoMem); }
- }
-
- if (!err) {
- io_array->objects = objects;
- io_array->max_count = new_max_count;
+
+ if (!err) {
+ io_array->objects = objects;
+ io_array->max_count = new_max_count;
+ }
}
return cci_check_error (err);
memmove (&io_array->objects[in_position], &io_array->objects[in_position + 1],
move_count * sizeof (*io_array->objects));
}
+ io_array->count--;
if (io_array->object_release) { io_array->object_release (object); }
- io_array->count--;
cci_array_resize (io_array, io_array->count);
- }
+ }
return cci_check_error (err);
}
cc_int32 ccs_callbackref_array_new (ccs_callbackref_array_t *out_array)
{
- return cci_array_new (out_array, NULL /* Just a reference, not owner */ );
+ /* Ref arrays do not own their contents; pass NULL for release function */
+ return cci_array_new (out_array, NULL);
}
/* ------------------------------------------------------------------------ */
{
return cci_array_remove (io_array, in_position);
}
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_iteratorref_array_new (ccs_iteratorref_array_t *out_array)
+{
+ /* Ref arrays do not own their contents; pass NULL for release function */
+ return cci_array_new (out_array, NULL);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_iteratorref_array_release (ccs_iteratorref_array_t io_array)
+{
+ return cci_array_release (io_array);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_uint64 ccs_iteratorref_array_count (ccs_iteratorref_array_t in_array)
+{
+ return cci_array_count (in_array);
+}
+
+/* ------------------------------------------------------------------------ */
+
+ccs_generic_list_iterator_t ccs_iteratorref_array_object_at_index (ccs_iteratorref_array_t io_array,
+ cc_uint64 in_position)
+{
+ return (ccs_generic_list_iterator_t) cci_array_object_at_index (io_array,
+ in_position);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_iteratorref_array_insert (ccs_iteratorref_array_t io_array,
+ ccs_generic_list_iterator_t in_iterator,
+ cc_uint64 in_position)
+{
+ return cci_array_insert (io_array,
+ (cci_array_object_t) in_iterator,
+ in_position);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_iteratorref_array_remove (ccs_iteratorref_array_t io_array,
+ cc_uint64 in_position)
+{
+ return cci_array_remove (io_array, in_position);
+}
cc_int32 ccs_callbackref_array_remove (ccs_callbackref_array_t io_array,
cc_uint64 in_position);
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+cc_int32 ccs_iteratorref_array_new (ccs_iteratorref_array_t *out_array);
+
+cc_int32 ccs_iteratorref_array_release (ccs_iteratorref_array_t io_array);
+
+cc_uint64 ccs_iteratorref_array_count (ccs_iteratorref_array_t in_array);
+
+ccs_generic_list_iterator_t ccs_iteratorref_array_object_at_index (ccs_iteratorref_array_t io_array,
+ cc_uint64 in_position);
+
+cc_int32 ccs_iteratorref_array_insert (ccs_iteratorref_array_t io_array,
+ ccs_generic_list_iterator_t in_iterator,
+ cc_uint64 in_position);
+
+cc_int32 ccs_iteratorref_array_remove (ccs_iteratorref_array_t io_array,
+ cc_uint64 in_position);
+
#endif /* CCS_ARRAY_H */
if (!out_ccache ) { err = cci_check_error (ccErrBadParam); }
if (!err) {
- err = ccs_ccache_list_new_iterator (in_cache_collection->ccaches, &iterator);
+ err = ccs_ccache_list_new_iterator (in_cache_collection->ccaches,
+ CCS_PIPE_NULL,
+ &iterator);
}
while (!err) {
if (!out_credentials_iterator) { err = cci_check_error (ccErrBadParam); }
if (!err) {
- err = ccs_ccache_list_new_iterator (in_cache_collection->ccaches, &iterator);
+ err = ccs_ccache_list_new_iterator (in_cache_collection->ccaches,
+ CCS_PIPE_NULL,
+ &iterator);
}
while (!err) {
ccs_ccache_list_iterator_t iterator = NULL;
err = ccs_ccache_list_new_iterator (in_cache_collection->ccaches,
+ CCS_PIPE_NULL,
&iterator);
if (!err) {
/* ------------------------------------------------------------------------ */
static cc_int32 ccs_cache_collection_new_ccache_iterator (ccs_cache_collection_t io_cache_collection,
+ ccs_pipe_t in_client_pipe,
cci_stream_t in_request_data,
cci_stream_t io_reply_data)
{
if (!err) {
err = ccs_ccache_list_new_iterator (io_cache_collection->ccaches,
+ in_client_pipe,
&ccache_iterator);
}
} else if (in_request_name == cci_context_new_ccache_iterator_msg_id) {
err = ccs_cache_collection_new_ccache_iterator (io_cache_collection,
- in_request_data, reply_data);
+ in_client_pipe,
+ in_request_data,
+ reply_data);
} else if (in_request_name == cci_context_lock_msg_id) {
err = ccs_cache_collection_lock (in_client_pipe, in_reply_pipe,
static cc_int32 ccs_ccache_new_credentials_iterator (ccs_ccache_t io_ccache,
ccs_cache_collection_t io_cache_collection,
+ ccs_pipe_t in_client_pipe,
cci_stream_t in_request_data,
cci_stream_t io_reply_data)
{
if (!err) {
err = ccs_credentials_list_new_iterator (io_ccache->credentials,
+ in_client_pipe,
&credentials_iterator);
}
in_request_data, reply_data);
} else if (in_request_name == cci_ccache_new_credentials_iterator_msg_id) {
- err = ccs_ccache_new_credentials_iterator (io_ccache, io_cache_collection,
- in_request_data, reply_data);
+ err = ccs_ccache_new_credentials_iterator (io_ccache,
+ io_cache_collection,
+ in_client_pipe,
+ in_request_data,
+ reply_data);
} else if (in_request_name == cci_ccache_move_msg_id) {
err = ccs_ccache_move (io_ccache, io_cache_collection,
struct ccs_client_d {
ccs_pipe_t client_pipe;
- ccs_callbackref_array_t callbacks; /* references, not owner */
+
+ /* The following arrays do not own their contents */
+ ccs_callbackref_array_t callbacks;
+ ccs_iteratorref_array_t iterators;
};
-struct ccs_client_d ccs_client_initializer = { CCS_PIPE_NULL, NULL };
+struct ccs_client_d ccs_client_initializer = { CCS_PIPE_NULL, NULL, NULL };
/* ------------------------------------------------------------------------ */
err = ccs_callbackref_array_new (&client->callbacks);
}
+ if (!err) {
+ err = ccs_iteratorref_array_new (&client->iterators);
+ }
+
if (!err) {
err = ccs_pipe_copy (&client->client_pipe, in_client_pipe);
}
if (!err && io_client) {
cc_uint64 i;
- cc_uint64 lock_count = ccs_callbackref_array_count (io_client->callbacks);
+ cc_uint64 callback_count = ccs_callbackref_array_count (io_client->callbacks);
+ cc_uint64 iterator_count = ccs_iteratorref_array_count (io_client->iterators);
- for (i = 0; !err && i < lock_count; i++) {
+ for (i = 0; !err && i < callback_count; i++) {
ccs_callback_t callback = ccs_callbackref_array_object_at_index (io_client->callbacks, i);
- cci_debug_printf ("%s: Invalidating callback reference %p.", __FUNCTION__, callback);
+ cci_debug_printf ("%s: Invalidating callback reference %p.",
+ __FUNCTION__, callback);
ccs_callback_invalidate (callback);
}
+ for (i = 0; !err && i < iterator_count; i++) {
+ ccs_generic_list_iterator_t iterator = ccs_iteratorref_array_object_at_index (io_client->iterators, i);
+
+ cci_debug_printf ("%s: Invalidating iterator reference %p.",
+ __FUNCTION__, iterator);
+ ccs_generic_list_iterator_invalidate (iterator);
+ }
+
ccs_callbackref_array_release (io_client->callbacks);
+ ccs_iteratorref_array_release (io_client->iterators);
ccs_pipe_release (io_client->client_pipe);
free (io_client);
}
if (!err) {
err = ccs_callbackref_array_insert (io_client->callbacks, in_callback,
- ccs_callback_array_count (io_client->callbacks));
+ ccs_callbackref_array_count (io_client->callbacks));
}
return cci_check_error (err);
/* ------------------------------------------------------------------------ */
+cc_int32 ccs_client_add_iterator (ccs_client_t io_client,
+ ccs_generic_list_iterator_t in_iterator)
+{
+ cc_int32 err = ccNoError;
+
+ if (!io_client ) { err = cci_check_error (ccErrBadParam); }
+ if (!in_iterator) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ err = ccs_iteratorref_array_insert (io_client->iterators, in_iterator,
+ ccs_iteratorref_array_count (io_client->iterators));
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_client_remove_iterator (ccs_client_t io_client,
+ ccs_generic_list_iterator_t in_iterator)
+{
+ cc_int32 err = ccNoError;
+ cc_uint32 found_iterator = 0;
+
+ if (!io_client) { err = cci_check_error (ccErrBadParam); }
+
+ if (!err) {
+ cc_uint64 i;
+ cc_uint64 lock_count = ccs_iteratorref_array_count (io_client->iterators);
+
+ for (i = 0; !err && i < lock_count; i++) {
+ ccs_generic_list_iterator_t iterator = ccs_iteratorref_array_object_at_index (io_client->iterators, i);
+
+ if (iterator == in_iterator) {
+ cci_debug_printf ("%s: Removing iterator reference %p.", __FUNCTION__, iterator);
+ found_iterator = 1;
+ err = ccs_iteratorref_array_remove (io_client->iterators, i);
+ break;
+ }
+ }
+ }
+
+ if (!err && !found_iterator) {
+ cci_debug_printf ("%s: WARNING! iterator not found.", __FUNCTION__);
+ }
+
+ return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
cc_int32 ccs_client_uses_pipe (ccs_client_t in_client,
ccs_pipe_t in_pipe,
cc_uint32 *out_uses_pipe)
cc_int32 ccs_client_remove_callback (ccs_client_t io_client,
ccs_callback_t in_lock);
+cc_int32 ccs_client_add_iterator (ccs_client_t io_client,
+ ccs_generic_list_iterator_t in_iterator);
+
+cc_int32 ccs_client_remove_iterator (ccs_client_t io_client,
+ ccs_generic_list_iterator_t in_iterator);
+
cc_int32 ccs_client_uses_pipe (ccs_client_t in_client,
ccs_pipe_t in_pipe,
cc_uint32 *out_uses_pipe);
/* ------------------------------------------------------------------------ */
cc_int32 ccs_ccache_list_new_iterator (ccs_ccache_list_t in_list,
+ ccs_pipe_t in_client_pipe,
ccs_ccache_list_iterator_t *out_list_iterator)
{
- return ccs_list_new_iterator (in_list, out_list_iterator);
+ return ccs_list_new_iterator (in_list, in_client_pipe, out_list_iterator);
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
cc_int32 ccs_credentials_list_new_iterator (ccs_credentials_list_t in_list,
+ ccs_pipe_t in_client_pipe,
ccs_credentials_list_iterator_t *out_list_iterator)
{
- return ccs_list_new_iterator (in_list, out_list_iterator);
+ return ccs_list_new_iterator (in_list, in_client_pipe, out_list_iterator);
}
/* ------------------------------------------------------------------------ */
{
return ccs_list_iterator_release (io_list_iterator);
}
+
+#ifdef TARGET_OS_MAC
+#pragma mark-
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_generic_list_iterator_invalidate (ccs_generic_list_iterator_t io_list_iterator)
+{
+ return ccs_list_iterator_invalidate (io_list_iterator);
+}
cc_int32 ccs_ccache_list_new (ccs_ccache_list_t *out_list);
cc_int32 ccs_ccache_list_new_iterator (ccs_ccache_list_t in_list,
+ ccs_pipe_t in_client_pipe,
ccs_ccache_list_iterator_t *out_list_iterator);
cc_int32 ccs_ccache_list_count (ccs_ccache_list_t in_list,
cc_int32 ccs_credentials_list_new (ccs_credentials_list_t *out_list);
cc_int32 ccs_credentials_list_new_iterator (ccs_credentials_list_t in_list,
+ ccs_pipe_t in_client_pipe,
ccs_credentials_list_iterator_t *out_list_iterator);
cc_int32 ccs_credentials_list_count (ccs_credentials_list_t in_list,
cc_int32 ccs_credentials_list_iterator_release (ccs_credentials_list_iterator_t io_list_iterator);
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+cc_int32 ccs_generic_list_iterator_invalidate (ccs_generic_list_iterator_t io_list_iterator);
+
#endif /* CCS_LIST_H */
struct ccs_list_iterator_d {
cci_identifier_t identifier;
+ ccs_pipe_t client_pipe;
ccs_list_t list;
cc_uint64 current;
};
-struct ccs_list_iterator_d ccs_list_iterator_initializer = { NULL, NULL, 0 };
+struct ccs_list_iterator_d ccs_list_iterator_initializer = { NULL, CCS_PIPE_NULL, NULL, 0 };
static cc_int32 ccs_list_iterator_new (ccs_list_iterator_t *out_list_iterator,
- ccs_list_t in_list);
+ ccs_list_t in_list,
+ ccs_pipe_t in_client_pipe);
static cc_int32 ccs_list_iterator_object_release (cci_array_object_t io_list_iterator);
/* ------------------------------------------------------------------------ */
cc_int32 ccs_list_new_iterator (ccs_list_t io_list,
+ ccs_pipe_t in_client_pipe,
ccs_list_iterator_t *out_list_iterator)
{
- return cci_check_error (ccs_list_iterator_new (out_list_iterator, io_list));
+ return cci_check_error (ccs_list_iterator_new (out_list_iterator,
+ io_list,
+ in_client_pipe));
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
static cc_int32 ccs_list_iterator_new (ccs_list_iterator_t *out_list_iterator,
- ccs_list_t io_list)
+ ccs_list_t io_list,
+ ccs_pipe_t in_client_pipe)
{
cc_int32 err = ccNoError;
ccs_list_iterator_t list_iterator = NULL;
if (!out_list_iterator) { err = cci_check_error (ccErrBadParam); }
if (!io_list ) { err = cci_check_error (ccErrBadParam); }
+ /* client_pipe may be NULL if the iterator exists for internal server use */
if (!err) {
list_iterator = malloc (sizeof (*list_iterator));
(cci_array_object_t) list_iterator,
cci_array_count (io_list->iterators));
}
+
+ if (!err && ccs_pipe_valid (in_client_pipe)) {
+ ccs_client_t client = NULL;
+
+ err = ccs_pipe_copy (&list_iterator->client_pipe, in_client_pipe);
+
+ if (!err) {
+ err = ccs_server_client_for_pipe (in_client_pipe, &client);
+ }
+
+ if (!err) {
+ err = ccs_client_add_iterator (client, list_iterator);
+ }
+ }
if (!err) {
*out_list_iterator = list_iterator;
if (!out_list_iterator) { err = cci_check_error (ccErrBadParam); }
if (!err) {
- err = ccs_list_iterator_new (&list_iterator, in_list_iterator->list);
+ err = ccs_list_iterator_new (&list_iterator,
+ in_list_iterator->list,
+ in_list_iterator->client_pipe);
}
if (!err) {
if (!io_list_iterator) { err = ccErrBadParam; }
+ if (!err && ccs_pipe_valid (list_iterator->client_pipe)) {
+ ccs_client_t client = NULL;
+
+ err = ccs_server_client_for_pipe (list_iterator->client_pipe, &client);
+
+ if (!err && client) {
+ /* if client object still has a reference to us, remove it */
+ err = ccs_client_remove_iterator (client, list_iterator);
+ }
+ }
+
if (!err) {
+ ccs_pipe_release (list_iterator->client_pipe);
cci_identifier_release (list_iterator->identifier);
free (io_list_iterator);
}
/* ------------------------------------------------------------------------ */
+cc_int32 ccs_list_iterator_invalidate (ccs_list_iterator_t io_list_iterator)
+{
+ cc_int32 err = ccNoError;
+ ccs_list_iterator_t list_iterator = (ccs_list_iterator_t) io_list_iterator;
+
+ if (!io_list_iterator) { err = ccErrBadParam; }
+
+ if (!err) {
+ /* Client owner died. Remove client reference and then the iterator. */
+ if (ccs_pipe_valid (list_iterator->client_pipe)) {
+ ccs_pipe_release (list_iterator->client_pipe);
+ list_iterator->client_pipe = CCS_PIPE_NULL;
+ }
+
+ err = ccs_list_iterator_release (io_list_iterator);
+ }
+
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
cc_int32 ccs_list_iterator_current (ccs_list_iterator_t io_list_iterator,
ccs_list_object_t *out_object)
{
#ifndef CCS_LIST_INTERNAL_H
#define CCS_LIST_INTERNAL_H
-#include "cci_common.h"
+#include "ccs_common.h"
#include "cci_array_internal.h"
struct ccs_list_d;
cc_int32 ccs_list_release (ccs_list_t io_list);
cc_int32 ccs_list_new_iterator (ccs_list_t io_list,
+ ccs_pipe_t in_client_pipe,
ccs_list_iterator_t *out_list_iterator);
cc_int32 ccs_list_release_iterator (ccs_list_t io_list,
cc_int32 ccs_list_iterator_next (ccs_list_iterator_t io_list_iterator,
ccs_list_object_t *out_object);
-cc_int32 ccs_list_iterator_release (ccs_list_iterator_t io_list_iterator);
+cc_int32 ccs_list_iterator_invalidate (ccs_list_iterator_t io_list_iterator);
+cc_int32 ccs_list_iterator_release (ccs_list_iterator_t io_list_iterator);
#endif /* CCS_LIST_INTERNAL_H */
typedef struct cci_array_d *ccs_callbackref_array_t;
+typedef struct cci_array_d *ccs_iteratorref_array_t;
+
typedef struct cci_array_d *ccs_lock_array_t;
#ifdef TARGET_OS_MAC
struct ccs_list_d;
struct ccs_list_iterator_d;
+/* Used for iterator array invalidate function */
+typedef struct ccs_list_iterator_d *ccs_generic_list_iterator_t;
+
typedef struct ccs_list_d *ccs_cache_collection_list_t;
typedef struct ccs_list_d *ccs_ccache_list_t;