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