]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
CCacheServer should track client iterators
authorAlexandra Ellwood <lxs@mit.edu>
Tue, 18 Mar 2008 19:25:16 +0000 (19:25 +0000)
committerAlexandra Ellwood <lxs@mit.edu>
Tue, 18 Mar 2008 19:25:16 +0000 (19:25 +0000)
The CCacheServer needs to track client iterators so that if
a client crashes while iterating the resources on the server
for that iterator are freed.

ticket: new

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20279 dc483132-0cff-0310-8789-dd5450dbe970

12 files changed:
src/ccapi/common/cci_array_internal.c
src/ccapi/server/ccs_array.c
src/ccapi/server/ccs_array.h
src/ccapi/server/ccs_cache_collection.c
src/ccapi/server/ccs_ccache.c
src/ccapi/server/ccs_client.c
src/ccapi/server/ccs_client.h
src/ccapi/server/ccs_list.c
src/ccapi/server/ccs_list.h
src/ccapi/server/ccs_list_internal.c
src/ccapi/server/ccs_list_internal.h
src/ccapi/server/ccs_types.h

index bdd939dbcd993b7667b391bda04b1ba360e2fe63..b5a0f693bd9d12d2749572190894de66bb405f57 100644 (file)
@@ -52,7 +52,6 @@ static cc_int32 cci_array_resize (cci_array_t io_array,
 {
     cc_int32 err = ccNoError;
     cc_uint64 new_max_count = 0;
-    cci_array_object_t *objects = NULL;
     
     if (!io_array) { err = cci_check_error (ccErrBadParam); }
     
@@ -75,8 +74,8 @@ static cc_int32 cci_array_resize (cci_array_t io_array,
         }
     }
     
-    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));
@@ -84,11 +83,11 @@ static cc_int32 cci_array_resize (cci_array_t io_array,
             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); 
@@ -236,12 +235,12 @@ cc_int32 cci_array_remove (cci_array_t io_array,
             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);    
 }
index 82aa0245433cb9373d43bd4bf060ee42a9c740f8..d5dd4adb2a7f0da5687052c2081ec799c13fc9f2 100644 (file)
@@ -212,7 +212,8 @@ cc_int32 ccs_callback_array_remove (ccs_callback_array_t io_array,
 
 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);
 }
 
 /* ------------------------------------------------------------------------ */
@@ -253,3 +254,57 @@ cc_int32 ccs_callbackref_array_remove (ccs_callbackref_array_t io_array,
 {
     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);
+}
index 800e15de8182e4214d771cfd10cfdeb4fba1fc03..93dc9d8c2cf7f54a56cdcd70ff51cbbf6b756cdc 100644 (file)
@@ -110,4 +110,24 @@ cc_int32 ccs_callbackref_array_insert (ccs_callbackref_array_t io_array,
 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 */
index 2500c297495db4996fa844961fb27486d4ed9a60..02d4d8f7daa3ae078d2bd0c0e89b7c816fd07b1f 100644 (file)
@@ -229,7 +229,9 @@ static cc_int32 ccs_cache_collection_find_ccache_by_name (ccs_cache_collection_t
     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) {
@@ -374,7 +376,9 @@ cc_int32 ccs_cache_collection_find_credentials_iterator (ccs_cache_collection_t
     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) {
@@ -473,6 +477,7 @@ static cc_int32 ccs_cache_collection_get_default_ccache (ccs_cache_collection_t
             ccs_ccache_list_iterator_t iterator = NULL;
             
             err = ccs_ccache_list_new_iterator (in_cache_collection->ccaches,
+                                                CCS_PIPE_NULL, 
                                                 &iterator);
             
             if (!err) {
@@ -916,6 +921,7 @@ static cc_int32 ccs_cache_collection_create_new_ccache (ccs_cache_collection_t i
 /* ------------------------------------------------------------------------ */
 
 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)
 {
@@ -928,6 +934,7 @@ static  cc_int32 ccs_cache_collection_new_ccache_iterator (ccs_cache_collection_
     
     if (!err) {
         err = ccs_ccache_list_new_iterator (io_cache_collection->ccaches,
+                                            in_client_pipe,
                                             &ccache_iterator);
     }
     
@@ -1070,7 +1077,9 @@ static cc_int32 ccs_cache_collection_unlock (ccs_pipe_t             in_client_pi
             
         } 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, 
index 2f7d45d8b6ba62254c69160d02a7c541a10fbabd..b35081feb5f03b3d6baeba699f469457f1b1132a 100644 (file)
@@ -747,6 +747,7 @@ static cc_int32 ccs_ccache_remove_credentials (ccs_ccache_t           io_ccache,
 
 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)
 {
@@ -760,6 +761,7 @@ static cc_int32 ccs_ccache_new_credentials_iterator (ccs_ccache_t           io_c
     
     if (!err) {
         err = ccs_credentials_list_new_iterator (io_ccache->credentials,
+                                                 in_client_pipe,
                                                  &credentials_iterator);
     }
     
@@ -1163,8 +1165,11 @@ cc_int32 ccs_ccache_handle_message (ccs_pipe_t              in_client_pipe,
                                                  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,
index 5ec5de33d78789da6195e102e9452fea922c4ad5..31ed14ff4766488c7d070cfdbc70668802d28004 100644 (file)
 
 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 };
 
 /* ------------------------------------------------------------------------ */
 
@@ -57,6 +60,10 @@ cc_int32 ccs_client_new (ccs_client_t *out_client,
         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);
     }
@@ -79,16 +86,27 @@ cc_int32 ccs_client_release (ccs_client_t io_client)
     
     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);
     }
@@ -108,7 +126,7 @@ cc_int32 ccs_client_add_callback (ccs_client_t   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);    
@@ -150,6 +168,57 @@ cc_int32 ccs_client_remove_callback (ccs_client_t   io_client,
 
 /* ------------------------------------------------------------------------ */
 
+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)
index fe3ea71b99f5e3d6f591dc363410fd24fb1cfd40..58c963707b380b5c4b6a3c26c274c30634bd5c0e 100644 (file)
@@ -40,6 +40,12 @@ cc_int32 ccs_client_add_callback (ccs_client_t   io_client,
 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);
index bc34fa25775fcd14485361d6362021b93872739d..2743994a147145c6e51e46ad5a120612e32fe106 100644 (file)
@@ -132,9 +132,10 @@ 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)
 {
-    return ccs_list_new_iterator (in_list, out_list_iterator);
+    return ccs_list_new_iterator (in_list, in_client_pipe, out_list_iterator);
 }
 
 /* ------------------------------------------------------------------------ */
@@ -262,9 +263,10 @@ 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)
 {
-    return ccs_list_new_iterator (in_list, out_list_iterator);
+    return ccs_list_new_iterator (in_list, in_client_pipe, out_list_iterator);
 }
 
 /* ------------------------------------------------------------------------ */
@@ -347,3 +349,14 @@ cc_int32 ccs_credentials_list_iterator_release (ccs_credentials_list_iterator_t
 {
     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);
+}
index 7346216974289563d45ec30e43a0d84eef2fb2c1..fff2f5421e8ba5a4156863ea0f0064648d9f75a6 100644 (file)
@@ -54,6 +54,7 @@ cc_int32 ccs_cache_collection_list_release (ccs_cache_collection_list_t io_list)
 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,
@@ -97,6 +98,7 @@ cc_int32 ccs_ccache_list_iterator_release (ccs_ccache_list_iterator_t io_list_it
 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,
@@ -130,4 +132,10 @@ cc_int32 ccs_credentials_list_iterator_next (ccs_credentials_list_iterator_t  io
 
 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 */
index d74a0ff9ef52cdcb0da102c6edcc4b2a9b42f369..0066f36fd8f9349c2cc925a8fb4c019cba615044 100644 (file)
@@ -53,14 +53,16 @@ struct ccs_list_d ccs_list_initializer = { NULL, NULL, -1, -1, NULL };
 
 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);
 
@@ -138,9 +140,12 @@ 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)
 {
-    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));
 }
 
 /* ------------------------------------------------------------------------ */
@@ -415,13 +420,15 @@ cc_int32 ccs_list_push_front (ccs_list_t       io_list,
 /* ------------------------------------------------------------------------ */
 
 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));
@@ -444,6 +451,20 @@ static cc_int32 ccs_list_iterator_new (ccs_list_iterator_t *out_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;
@@ -485,7 +506,9 @@ cc_int32 ccs_list_iterator_clone (ccs_list_iterator_t  in_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) {
@@ -509,7 +532,19 @@ static cc_int32 ccs_list_iterator_object_release (cci_array_object_t io_list_ite
     
     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);
     }
@@ -541,6 +576,28 @@ 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 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)
 {
index 5bb52d0612bff082cee74857f5f51aef6e76dfc9..1ab6aa4c107e32d00de467787bb98c9fb6773102 100644 (file)
@@ -27,7 +27,7 @@
 #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;
@@ -49,6 +49,7 @@ cc_int32 ccs_list_new (ccs_list_t                      *out_list,
 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,
@@ -87,7 +88,8 @@ 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_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 */
index a1e65a2515b64c05817fea082b31640a8d444d8d..aaea0336c6f3788680d995031952cd038bed1122 100644 (file)
@@ -41,6 +41,8 @@ typedef struct cci_array_d *ccs_callback_array_t;
 
 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
@@ -79,6 +81,9 @@ typedef struct ccs_callback_d *ccs_callback_t;
 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;