Added callback support for wait_for_change functions
authorAlexandra Ellwood <lxs@mit.edu>
Wed, 25 Jul 2007 19:29:39 +0000 (19:29 +0000)
committerAlexandra Ellwood <lxs@mit.edu>
Wed, 25 Jul 2007 19:29:39 +0000 (19:29 +0000)
ticket: 4644
status: open

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

13 files changed:
src/ccapi/common/cci_array_internal.c
src/ccapi/common/cci_identifier.c
src/ccapi/common/cci_stream.c
src/ccapi/lib/ccapi_ccache.c
src/ccapi/lib/ccapi_context.c
src/ccapi/server/ccs_cache_collection.c
src/ccapi/server/ccs_callback.c
src/ccapi/server/ccs_ccache.c
src/ccapi/server/ccs_client.c
src/ccapi/server/ccs_credentials.c
src/ccapi/server/ccs_list_internal.c
src/ccapi/server/ccs_lock.c
src/ccapi/server/ccs_lock_state.c

index 85578c2b1bc0da1d36070f5718264e4b522021fd..3d1e35ef3d4cad73eb01df1dcaefc8837e4ba0e4 100644 (file)
@@ -128,9 +128,7 @@ cc_int32 cci_array_release (cci_array_t io_array)
 {
     cc_int32 err = ccNoError;
     
-    if (!io_array) { err = ccErrBadParam; }
-    
-    if (!err) {
+    if (!err && io_array) {
         cc_uint64 i;
         
         if (io_array->object_release) {
index 8695d2171b50f18289ca73f571f2909118f1aeee..b6e9188920a0095cfbf942536cc457be80dec0b6 100644 (file)
@@ -141,16 +141,14 @@ cc_int32 cci_identifier_release (cci_identifier_t in_identifier)
 {
     cc_int32 err = ccNoError;
     
-    if (!in_identifier) { err = ccErrBadParam; }
-    
     /* Do not free the static "uninitialized" identifier */
-    if (!err && in_identifier != cci_identifier_uninitialized) {
+    if (!err && in_identifier && in_identifier != cci_identifier_uninitialized) {
         free (in_identifier->server_id);
         free (in_identifier->object_id);
         free (in_identifier);
     }
     
-    return err;
+    return cci_check_error (err);
 }
 
 #pragma mark -
index 1532f1ed8e30fcd4bf86ab38ff99f020ddb1a433..b19e7bbfb508af57b8c40c317202ef604e99e5f9 100644 (file)
@@ -134,9 +134,7 @@ cc_uint32 cci_stream_release (cci_stream_t io_stream)
 {      
     cc_int32 err = ccNoError;
     
-    if (!io_stream) { err = ccErrBadParam; }
-    
-    if (!err) {
+    if (!err && io_stream) {
         free (io_stream->data);
         free (io_stream);
     }
index 5a975810c2ac49522221c87abc64ae7fa616726a..485e6ceea804316a746435fd407327265e037bbb 100644 (file)
@@ -44,6 +44,7 @@ typedef struct cci_ccache_d {
     cc_ccache_f *vector_functions;
 #endif
     cci_identifier_t identifier;
+    cc_time_t last_wait_for_change_time;
 } *cci_ccache_t;
 
 /* ------------------------------------------------------------------------ */
@@ -52,6 +53,7 @@ struct cci_ccache_d cci_ccache_initializer = {
     NULL 
     VECTOR_FUNCTIONS_INITIALIZER, 
     NULL,
+    0
 };
 
 cc_ccache_f cci_ccache_f_initializer = { 
@@ -594,15 +596,33 @@ cc_int32 ccapi_ccache_wait_for_change (cc_ccache_t  in_ccache)
 {
     cc_int32 err = ccNoError;
     cci_ccache_t ccache = (cci_ccache_t) in_ccache;
+    cci_stream_t request = NULL;
+    cci_stream_t reply = NULL;
     
     if (!in_ccache) { err = cci_check_error (ccErrBadParam); }
     
+    if (!err) {
+        err = cci_stream_new (&request);
+    }
+    
+    if (!err) {
+        err = cci_stream_write_time (request, ccache->last_wait_for_change_time);
+    }
+    
     if (!err) {
         err =  cci_ipc_send (cci_ccache_wait_for_change_msg_id,
                              ccache->identifier,
-                             NULL, NULL);
+                             request, 
+                            &reply);
     }
+    
+    if (!err) {
+        err = cci_stream_read_time (reply, &ccache->last_wait_for_change_time);
+    }    
         
+    cci_stream_release (request);
+    cci_stream_release (reply);
+    
     return cci_check_error (err);
 }
 
index 7a24f2248b886f65ad26c59f879482a79190cda0..feccc85a411f0672a577b69e1a2f80116189fcea 100644 (file)
@@ -43,6 +43,7 @@ typedef struct cci_context_d {
 #endif
     cci_identifier_t identifier;
     cc_uint32 synchronized;
+    cc_time_t last_wait_for_change_time;
 } *cci_context_t;
 
 /* ------------------------------------------------------------------------ */
@@ -51,6 +52,7 @@ struct cci_context_d cci_context_initializer = {
     NULL 
     VECTOR_FUNCTIONS_INITIALIZER,
     NULL,
+    0,
     0
 };
 
@@ -249,19 +251,37 @@ cc_int32 ccapi_context_wait_for_change (cc_context_t  in_context)
 {
     cc_int32 err = ccNoError;
     cci_context_t context = (cci_context_t) in_context;
+    cci_stream_t request = NULL;
+    cci_stream_t reply = NULL;
     
     if (!in_context) { err = cci_check_error (ccErrBadParam); }
     
     if (!err) {
-        err = cci_context_sync (context, 0);
+        err = cci_stream_new (&request);
     }
     
     if (!err) {
-        err =  cci_ipc_send_no_launch (cci_context_wait_for_change_msg_id,
-                                       context->identifier,
-                                       NULL, NULL);
+        err = cci_stream_write_time (request, context->last_wait_for_change_time);
+    }
+
+    if (!err) {
+        err = cci_context_sync (context, 1);
     }
     
+    if (!err) {
+        err = cci_ipc_send (cci_context_wait_for_change_msg_id,
+                           context->identifier,
+                           request, 
+                           &reply);
+    }
+
+    if (!err) {
+        err = cci_stream_read_time (reply, &context->last_wait_for_change_time);
+    }
+    
+    cci_stream_release (request);
+    cci_stream_release (reply);
+
     return cci_check_error (err);
 }
 
index 1356bc5748a6ac4aa27c5dd4145f5ddd78ba787f..543f99c2079fdaa790216a8203b7ae0b1195dc66 100644 (file)
@@ -94,9 +94,7 @@ cc_int32 ccs_cache_collection_release (ccs_cache_collection_t io_cache_collectio
 {
     cc_int32 err = ccNoError;
     
-    if (!io_cache_collection) { err = ccErrBadParam; }
-    
-    if (!err) {
+    if (!err && io_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);
@@ -135,6 +133,7 @@ cc_int32 ccs_cache_collection_compare_identifier (ccs_cache_collection_t  in_cac
 cc_int32 ccs_cache_collection_changed (ccs_cache_collection_t io_cache_collection)
 {
     cc_int32 err = ccNoError;
+    cci_stream_t reply_data = NULL;
     
     if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
 
@@ -148,6 +147,14 @@ cc_int32 ccs_cache_collection_changed (ccs_cache_collection_t io_cache_collectio
         }
     }
     
+    if (!err) {
+        err = cci_stream_new (&reply_data);
+    }
+
+    if (!err) {
+       err = cci_stream_write_time (reply_data, io_cache_collection->last_changed_time);
+    }
+    
     if (!err) {
        /* Loop over callbacks sending messages to them */
        cc_uint64 i;
@@ -156,7 +163,7 @@ cc_int32 ccs_cache_collection_changed (ccs_cache_collection_t io_cache_collectio
         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);
+           err = ccs_callback_reply_to_client (callback, reply_data);
            
            if (!err) {
                cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback);
@@ -164,9 +171,10 @@ cc_int32 ccs_cache_collection_changed (ccs_cache_collection_t io_cache_collectio
                break;
            }
         }
-       
     }
     
+    cci_stream_release (reply_data);
+    
     return cci_check_error (err);
 }
 
@@ -580,10 +588,12 @@ static cc_int32 ccs_cache_collection_wait_for_change (ccs_pipe_t              in
                                                      ccs_pipe_t              in_reply_pipe,
                                                      ccs_cache_collection_t  io_cache_collection,
                                                      cci_stream_t            in_request_data,
+                                                     cci_stream_t            io_reply_data,
                                                      cc_uint32              *out_will_block)
 {
     cc_int32 err = ccNoError;
-    ccs_callback_t callback = NULL;
+    cc_time_t last_wait_for_change_time = 0;
+    cc_uint32 will_block = 0;
     
     if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
     if (!ccs_pipe_valid (in_reply_pipe )) { err = cci_check_error (ccErrBadParam); }
@@ -592,25 +602,38 @@ static cc_int32 ccs_cache_collection_wait_for_change (ccs_pipe_t              in
     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);
+        err = cci_stream_read_time (in_request_data, &last_wait_for_change_time);
     }
     
     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 (last_wait_for_change_time < io_cache_collection->last_changed_time) {
+           err = cci_stream_write_time (io_reply_data, io_cache_collection->last_changed_time);
+       
+       } else {
+           ccs_callback_t callback = NULL;
 
-    if (!err) {
-       *out_will_block = 1;
+           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 */ }
+               
+               will_block = 1;
+           }
+
+           ccs_callback_release (callback);
+       }
     }
     
-    ccs_callback_release (callback);
+    if (!err) {
+       *out_will_block = will_block;
+    }
     
     return cci_check_error (err);    
 }
@@ -995,7 +1018,8 @@ static cc_int32 ccs_cache_collection_unlock (ccs_pipe_t             in_client_pi
         } 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);
+                                                        in_request_data, reply_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,
index 8035e5af1753f73755d9fc0cad7981ba872197bb..1076d9025c69f5c386fe8e73ce1b7c4fbff229c0 100644 (file)
@@ -102,29 +102,30 @@ cc_int32 ccs_callback_new (ccs_callback_t                  *out_callback,
 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);
+    if (!err && io_callback) {
+       ccs_client_t client = NULL;
+
+       if (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);    
@@ -157,6 +158,8 @@ cc_int32 ccs_callback_reply_to_client (ccs_callback_t io_callback,
     
     if (!err) {
         if (io_callback->pending) {
+           cci_debug_printf ("%s: callback %p replying to client.", __FUNCTION__, io_callback);
+
             err = ccs_server_send_reply (io_callback->reply_pipe, err, in_stream);
             
             if (err) {
index da6a8318f1f70536c14d9d9557a3e9ffcb927bc3..3eab42fa7a4286a8939336335f97d1a2c9423a20 100644 (file)
@@ -229,9 +229,7 @@ cc_int32 ccs_ccache_release (ccs_ccache_t io_ccache)
 {
     cc_int32 err = ccNoError;
     
-    if (!io_ccache) { err = ccErrBadParam; }
-    
-    if (!err) {
+    if (!err && io_ccache) {
         cci_identifier_release (io_ccache->identifier);
         ccs_lock_state_release (io_ccache->lock_state);
         free (io_ccache->name);
@@ -294,6 +292,7 @@ static cc_int32 ccs_ccache_changed (ccs_ccache_t           io_ccache,
                                     ccs_cache_collection_t io_cache_collection)
 {
     cc_int32 err = ccNoError;
+    cci_stream_t reply_data = NULL;
     
     if (!io_ccache          ) { err = cci_check_error (ccErrBadParam); }
     if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
@@ -312,6 +311,14 @@ static cc_int32 ccs_ccache_changed (ccs_ccache_t           io_ccache,
         err = ccs_cache_collection_changed (io_cache_collection);
     }
     
+    if (!err) {
+        err = cci_stream_new (&reply_data);
+    }
+    
+    if (!err) {
+       err = cci_stream_write_time (reply_data, io_ccache->last_changed_time);
+    }
+
     if (!err) {
        /* Loop over callbacks sending messages to them */
        cc_uint64 i;
@@ -320,7 +327,7 @@ static cc_int32 ccs_ccache_changed (ccs_ccache_t           io_ccache,
         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);
+           err = ccs_callback_reply_to_client (callback, reply_data);
            
            if (!err) {
                cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback);
@@ -328,9 +335,10 @@ static cc_int32 ccs_ccache_changed (ccs_ccache_t           io_ccache,
                break;
            }
         }
-       
     }
 
+    cci_stream_release (reply_data);
+    
     return cci_check_error (err);
 }
 
@@ -834,10 +842,12 @@ static cc_int32 ccs_ccache_wait_for_change (ccs_pipe_t              in_client_pi
                                            ccs_ccache_t            io_ccache,
                                            ccs_cache_collection_t  io_cache_collection,
                                            cci_stream_t            in_request_data,
+                                           cci_stream_t            io_reply_data,
                                            cc_uint32              *out_will_block)
 {
     cc_int32 err = ccNoError;
-    ccs_callback_t callback = NULL;
+    cc_time_t last_wait_for_change_time = 0;
+    cc_uint32 will_block = 0;
     
     if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
     if (!ccs_pipe_valid (in_reply_pipe )) { err = cci_check_error (ccErrBadParam); }
@@ -847,26 +857,39 @@ static cc_int32 ccs_ccache_wait_for_change (ccs_pipe_t              in_client_pi
     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);
+        err = cci_stream_read_time (in_request_data, &last_wait_for_change_time);
     }
     
     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 (last_wait_for_change_time < io_ccache->last_changed_time) {
+           err = cci_stream_write_time (io_reply_data, io_ccache->last_changed_time);
+           
+       } else {
+           ccs_callback_t callback = NULL;
+
+           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 */ }
+               
+               will_block = 1;
+           }
+           
+           ccs_callback_release (callback);
+       }
     }
-    
+       
     if (!err) {
-       *out_will_block = 1;
+       *out_will_block = will_block;
     }
     
-    ccs_callback_release (callback);
-    
     return cci_check_error (err);    
 }
 
@@ -1087,7 +1110,8 @@ cc_int32 ccs_ccache_handle_message (ccs_pipe_t              in_client_pipe,
         } 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);
+                                             in_request_data, reply_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,
index 0cb19dae9c01a3a784061c1b5e21c6471e351372..9e8a81c8bdc6274bce115545a6aa55fa06244b6d 100644 (file)
@@ -77,12 +77,20 @@ cc_int32 ccs_client_release (ccs_client_t io_client)
 {
     cc_int32 err = ccNoError;
     
-    if (!io_client) { err = cci_check_error (ccErrBadParam); }
-    
-    if (!err) {
-        ccs_callbackref_array_release (io_client->callbacks);
+    if (!err && io_client) {
+       cc_uint64 i;
+       cc_uint64 lock_count = ccs_callbackref_array_count (io_client->callbacks);
+       
+       for (i = 0; !err && i < lock_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);
+           ccs_callback_invalidate (callback);
+       }
+       
+       ccs_callbackref_array_release (io_client->callbacks);
        ccs_pipe_release (io_client->client_pipe);
-        free (io_client);
+       free (io_client);
     }
     
     return cci_check_error (err);    
@@ -125,14 +133,9 @@ cc_int32 ccs_client_remove_callback (ccs_client_t   io_client,
             ccs_callback_t callback = ccs_callbackref_array_object_at_index (io_client->callbacks, i);
             
             if (callback == in_callback) {
-                err = ccs_callback_invalidate (callback);
-                
-                if (!err) {
-                    cci_debug_printf ("%s: Removing callback reference %p.", 
-                                     __FUNCTION__, callback);
-                    err = ccs_callbackref_array_remove (io_client->callbacks, i);
-                    break;
-                }
+               cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback);
+               err = ccs_callbackref_array_remove (io_client->callbacks, i);
+               break;
             }
         }
     }
@@ -152,9 +155,9 @@ cc_int32 ccs_client_uses_pipe (ccs_client_t  in_client,
 {
     cc_int32 err = ccNoError;
     
-    if (in_client    ) { err = cci_check_error (ccErrBadParam); }
-    if (in_pipe      ) { err = cci_check_error (ccErrBadParam); }
-    if (out_uses_pipe) { err = cci_check_error (ccErrBadParam); }
+    if (!in_client    ) { err = cci_check_error (ccErrBadParam); }
+    if (!in_pipe      ) { err = cci_check_error (ccErrBadParam); }
+    if (!out_uses_pipe) { err = cci_check_error (ccErrBadParam); }
     
     if (!err) {
         *out_uses_pipe = (in_client->client_pipe == in_pipe);
index a5bc70c9acdc554852ac3fe888695d0dcc8744f7..f30479946fb9ace6b4b55754e758c841c203ce77 100644 (file)
@@ -82,9 +82,7 @@ cc_int32 ccs_credentials_release (ccs_credentials_t io_credentials)
 {
     cc_int32 err = ccNoError;
     
-    if (!io_credentials) { err = ccErrBadParam; }
-    
-    if (!err) {
+    if (!err && io_credentials) {
         cci_cred_union_release (io_credentials->cred_union);
         cci_identifier_release (io_credentials->identifier);
         free (io_credentials);
index 2b3e27f2925bffa45ac6b8ec895603f878c6c567..2f99ebdb89c5b6fc6efce0d1c67b1f58d5ae6f03 100644 (file)
@@ -119,9 +119,7 @@ cc_int32 ccs_list_release (ccs_list_t io_list)
 {
     cc_int32 err = ccNoError;
     
-    if (!io_list) { err = ccErrBadParam; }
-    
-    if (!err) {
+    if (!err && io_list) {
         cc_uint64 i;
         
         for (i = 0; i < cci_array_count (io_list->iterators); i++) {
@@ -521,9 +519,7 @@ cc_int32 ccs_list_iterator_release (ccs_list_iterator_t io_list_iterator)
 {
     cc_int32 err = ccNoError;
     
-    if (!io_list_iterator) { err = ccErrBadParam; }
-    
-    if (!err) {
+    if (!err && io_list_iterator) {
         cc_uint64 i = 0;
         
         if (ccs_list_find_iterator_index (io_list_iterator->list, 
index 1934640fee114087e0cfe9d6ae3862b9dfa1200b..1fc54db789dccbbce4beb20b723e1ea8abe89cb2 100644 (file)
@@ -98,9 +98,7 @@ cc_int32 ccs_lock_release (ccs_lock_t io_lock)
 {
     cc_int32 err = ccNoError;
     
-    if (!io_lock) { err = cci_check_error (ccErrBadParam); }
-        
-    if (!err) {
+    if (!err && io_lock) {
        free (io_lock->callback);
         free (io_lock);
     }
index b8dc5debf4a043895d72c988013e5555b68df52d..0d8dcdadf3a3ad8729f99472c8fa04a579df7c0c 100644 (file)
@@ -81,9 +81,7 @@ cc_int32 ccs_lock_state_release (ccs_lock_state_t io_lock_state)
 {
     cc_int32 err = ccNoError;
     
-    if (!io_lock_state) { err = ccErrBadParam; }
-
-    if (!err) {
+    if (!err && io_lock_state) {
         ccs_lock_array_release (io_lock_state->locks);
         free (io_lock_state);
     }