Dear Axis2/C devs,

I've started developing an application using axis2/C asynchronous
calls and I found several bugs...  After a lot of diving trough the
axis code I think I found some of the problems, and implemented simple
fixes for them...

I would like to send those patches to you to see if the bug fixes are
correct or is there a better solution for those issues? I've runned
the project tests and did some memory leak check and the patch fixes
the memory leaks from asynchronous calls...

Also it seems that axis2/c crashes in several places while creating
and using multiple svc_clients, mostly due the saturation of file
descriptors, and because in some cases the use of files isn't
validated... I've tried to find a solution to that as well but there
were many places that needed to be modified, I found some but I need
to cleanup my code before sending a patch...

If the bug fixes are correct I would love to create a jira ticket in
order to incorporate the code to trunk...

Thank you all for your great work,
Best regards


PS: I'm sorry if this mail arrives to you twice, but I keep getting an
"Undelivered Mail Returned to Sender"
--
--
Mantaut Alex
Intraway Corp.

+54 (11) 6040-4000
MSN: alex.mant...@intraway.com

Visit our website at http://www.intraway.com
Proud to be an ISO 9001:2008 certified company
Index: src/core/clientapi/svc_client.c
===================================================================
--- src/core/clientapi/svc_client.c	(revision 1236776)
+++ src/core/clientapi/svc_client.c	(working copy)
@@ -805,6 +805,7 @@
     const axiom_node_t * payload,
     axis2_callback_t * callback)
 {
+    axis2_callback_increment_ref(callback,env);
     axis2_msg_ctx_t *msg_ctx = NULL;
     AXIS2_TRANSPORT_ENUMS transport_in_protocol;
     axis2_bool_t qname_free_flag = AXIS2_FALSE;
@@ -842,6 +843,7 @@
         return;
     }
 
+
     axis2_op_client_set_callback(svc_client->op_client, env, callback);
     axis2_op_client_add_out_msg_ctx(svc_client->op_client, env, msg_ctx);
 
@@ -870,7 +872,9 @@
         axis2_op_client_set_callback_recv(svc_client->op_client, env, svc_client->callback_recv);
     }
 
-    axis2_op_client_execute(svc_client->op_client, env, AXIS2_FALSE);
+    if(axis2_op_client_execute(svc_client->op_client, env, AXIS2_FALSE) != AXIS2_SUCCESS)
+    	return;
+
     axis2_svc_client_set_http_info(svc_client, env, msg_ctx);
     svc_client->auth_failed = axis2_msg_ctx_get_auth_failed(msg_ctx, env);
     svc_client->required_auth_is_http = axis2_msg_ctx_get_required_auth_is_http(msg_ctx, env);
@@ -884,6 +888,7 @@
         axutil_qname_free((axutil_qname_t *)op_qname, env);
         op_qname = NULL;
     }
+    axis2_callback_free(callback, env);
 }
 
 AXIS2_EXTERN void AXIS2_CALL
Index: src/core/clientapi/op_client.c
===================================================================
--- src/core/clientapi/op_client.c	(revision 1236776)
+++ src/core/clientapi/op_client.c	(working copy)
@@ -43,7 +43,7 @@
     axis2_bool_t completed;
 
     /* to hold the locally created async result */
-    axis2_async_result_t *async_result;
+    /*axis2_async_result_t *async_result;*/
 
     axis2_callback_recv_t *callback_recv;
 
@@ -101,7 +101,7 @@
     op_client->callback = NULL;
     op_client->completed = AXIS2_FALSE;
     op_client->reuse = AXIS2_FALSE;
-    op_client->async_result = NULL;
+    /*op_client->async_result = NULL;*/
     op_client->callback_recv = NULL;
 
     op_client->options = options;
@@ -501,7 +501,10 @@
                 "Op client execute failed due to engine creation failure.");
             return AXIS2_FAILURE;
         }
-        axis2_engine_send(engine, env, msg_ctx);
+
+        if(axis2_engine_send(engine, env, msg_ctx) != AXIS2_SUCCESS)
+        	return AXIS2_FAILURE;
+
         axis2_engine_free(engine, env);
     }
     else /* Same channel will be used irrespective of message exchange pattern. */
@@ -641,10 +644,10 @@
     if(!op_client)
         return;
 
-    /*if(op_client->callback)
+    if(op_client->callback)
     {
         axis2_callback_free(op_client->callback, env);
-    }*/
+    }
 
     if(op_client->op_ctx)
     {
@@ -688,8 +691,8 @@
     {
         return NULL;
     }
-
     th_env = axutil_init_thread_env(args_list->env);
+    axis2_callback_increment_ref(args_list->callback,th_env);
 
     op_ctx = axis2_op_ctx_create(th_env, args_list->op, args_list->op_client->svc_ctx);
     if(!op_ctx)
@@ -706,25 +709,38 @@
      * in the single channel non blocking case which, imply this is two way message by design.
      */
 
-    /* Here after the code is a subset of what callback receiver do in dual channel case.*/
-    axis2_op_client_add_msg_ctx(args_list->op_client, th_env, response);
-    args_list->op_client->async_result = axis2_async_result_create(th_env, response);
-
-    if(args_list->callback)
+    if(response)
     {
-        axis2_callback_invoke_on_complete(args_list->callback, th_env,
-            args_list->op_client->async_result);
+		/* Here after the code is a subset of what callback receiver do in dual channel case.*/
+		axis2_op_client_add_msg_ctx(args_list->op_client, th_env, response);
 
-        axis2_callback_set_complete(args_list->callback, th_env, AXIS2_TRUE);
+		axis2_async_result_t * async_result = axis2_async_result_create(th_env, response);
+
+		if(args_list->callback)
+		{
+			axis2_callback_invoke_on_complete(args_list->callback, th_env,
+				async_result);
+
+			axis2_callback_set_complete(args_list->callback, th_env, AXIS2_TRUE);
+		}
+	    /* Clean up memory */
+	    axis2_async_result_free(async_result, th_env);
+
     }
+    else
+    {
+    	if(args_list->callback)
+    	{
+    		/*TODO seek exception code*/
+    		axis2_callback_report_error(args_list->callback, th_env,1);
+    	}
+    }
 
-    /* Clean up memory */
-    axis2_async_result_free(args_list->op_client->async_result, th_env);
-
     axis2_op_ctx_free(op_ctx, th_env);
 
     th_pool = th_env->thread_pool;
 
+    axis2_callback_free(args_list->callback, th_env);
     AXIS2_FREE(th_env->allocator, args_list);
 
     if(th_env)
@@ -1450,4 +1466,4 @@
     axis2_bool_t reuse)
 {
     op_client->reuse = reuse;
-}
\ No newline at end of file
+}
Index: src/core/clientapi/callback.c
===================================================================
--- src/core/clientapi/callback.c	(revision 1236776)
+++ src/core/clientapi/callback.c	(working copy)
@@ -22,6 +22,8 @@
 struct axis2_callback
 {
 
+    int ref;
+
     /** callback complete? */
     axis2_bool_t complete;
 
@@ -105,6 +107,7 @@
     callback->on_error = axis2_callback_on_error;
 
     callback->mutex = axutil_thread_mutex_create(env->allocator, AXIS2_THREAD_MUTEX_DEFAULT);
+    callback->ref = 1;
     return callback;
 }
 
@@ -208,11 +211,40 @@
     return AXIS2_SUCCESS;
 }
 
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_callback_increment_ref(
+	axis2_callback_t * callback,
+    const axutil_env_t * env)
+{
+	axutil_thread_mutex_lock(callback->mutex);
+	callback->ref++;
+	axutil_thread_mutex_unlock(callback->mutex);
+
+    return AXIS2_SUCCESS;
+}
+
 AXIS2_EXTERN void AXIS2_CALL
 axis2_callback_free(
     axis2_callback_t * callback,
     const axutil_env_t * env)
 {
+	axutil_thread_mutex_lock(callback->mutex);
+	callback->ref--;
+
+
+    if(callback->ref > 0)
+    {
+    	axutil_thread_mutex_unlock(callback->mutex);
+        return;
+    }
+
+	axutil_thread_mutex_unlock(callback->mutex);
+
+    if(callback->msg_ctx)
+    {
+    	axis2_msg_ctx_free(callback->msg_ctx, env);
+    }
+
     if(callback->mutex)
     {
         axutil_thread_mutex_destroy(callback->mutex);
---------------------------------------------------------------------
To unsubscribe, e-mail: c-dev-unsubscr...@axis.apache.org
For additional commands, e-mail: c-dev-h...@axis.apache.org

Reply via email to