diff options
author | gmcdonald | 2010-02-13 01:32:03 +0000 |
---|---|---|
committer | gmcdonald | 2010-02-13 01:32:03 +0000 |
commit | 0425aadc78680e53000fd0108b540d6eca048516 (patch) | |
tree | 8ec7ab8e015d454c5ec586dfc91e05a2dce1cfc0 /src/core/clientapi/listener_manager.c | |
download | axis2c-0425aadc78680e53000fd0108b540d6eca048516.tar.gz axis2c-0425aadc78680e53000fd0108b540d6eca048516.tar.bz2 |
Moving axis svn, part of TLP move INFRA-2441
git-svn-id: http://svn.apache.org/repos/asf/axis/axis2/c/core/trunk@909681 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/core/clientapi/listener_manager.c')
-rw-r--r-- | src/core/clientapi/listener_manager.c | 302 |
1 files changed, 302 insertions, 0 deletions
diff --git a/src/core/clientapi/listener_manager.c b/src/core/clientapi/listener_manager.c new file mode 100644 index 0000000..1e3e3f2 --- /dev/null +++ b/src/core/clientapi/listener_manager.c @@ -0,0 +1,302 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axis2_listener_manager.h> +#include <axis2_const.h> +#include <axutil_hash.h> +#include <axis2_transport_receiver.h> + +/** + * keep information about the listener for a given transport + */ +typedef struct axis2_transport_listener_state +{ + int waiting_calls; + + axis2_transport_receiver_t *listener; + +} axis2_transport_listener_state_t; + +struct axis2_listener_manager +{ + + /** hash map of listeners */ + axis2_transport_listener_state_t *listener_map[AXIS2_TRANSPORT_ENUM_MAX]; + axutil_thread_t *listener_thread[AXIS2_TRANSPORT_ENUM_MAX]; + + /** configuration context */ + axis2_conf_ctx_t *conf_ctx; +}; + +typedef struct axis2_listener_manager_worker_func_args +{ + const axutil_env_t *env; + axis2_listener_manager_t *listner_manager; + axis2_transport_receiver_t *listener; +} axis2_listener_manager_worker_func_args_t; + +void *AXIS2_THREAD_FUNC axis2_listener_manager_worker_func( + axutil_thread_t * thd, + void *data); + +AXIS2_EXTERN axis2_listener_manager_t *AXIS2_CALL +axis2_listener_manager_create( + const axutil_env_t * env) +{ + axis2_listener_manager_t *listener_manager = NULL; + int i = 0; + + AXIS2_ENV_CHECK(env, NULL); + + listener_manager = AXIS2_MALLOC(env->allocator, sizeof(axis2_listener_manager_t)); + + if(!listener_manager) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create listener manager."); + return NULL; + } + + listener_manager->conf_ctx = NULL; + + for(i = 0; i < AXIS2_TRANSPORT_ENUM_MAX; i++) + { + listener_manager->listener_map[i] = NULL; + listener_manager->listener_thread[i] = NULL; + } + + return listener_manager; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_listener_manager_make_sure_started( + axis2_listener_manager_t * listener_manager, + const axutil_env_t * env, + const AXIS2_TRANSPORT_ENUMS transport, + axis2_conf_ctx_t * conf_ctx) +{ + axis2_transport_listener_state_t *tl_state = NULL; + + AXIS2_PARAM_CHECK(env->error, conf_ctx, AXIS2_FAILURE); + + if(listener_manager->conf_ctx) + { + if(conf_ctx != listener_manager->conf_ctx) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_CLIENT_SIDE_SUPPORT_ONLY_ONE_CONF_CTX, + AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Only one configuration context is supported at client side."); + return AXIS2_FAILURE; + } + } + else + { + listener_manager->conf_ctx = conf_ctx; + } + + tl_state = listener_manager->listener_map[transport]; + + if(!tl_state) + { + /*means this transport not yet started, start the transport */ + axis2_transport_in_desc_t *transport_in = NULL; + axis2_conf_t *conf = NULL; + axis2_transport_receiver_t *listener = NULL; + + conf = axis2_conf_ctx_get_conf(conf_ctx, env); + if(conf) + { + transport_in = axis2_conf_get_transport_in(conf, env, transport); + if(transport_in) + { + listener = axis2_transport_in_desc_get_recv(transport_in, env); + if(listener) + { + axutil_thread_t *worker_thread = NULL; + axis2_listener_manager_worker_func_args_t *arg_list = NULL; + arg_list = AXIS2_MALLOC(env->allocator, + sizeof(axis2_listener_manager_worker_func_args_t)); + if(!arg_list) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create listener manager worker function arguments."); + return AXIS2_FAILURE; + } + arg_list->env = env; + arg_list->listner_manager = listener_manager; + arg_list->listener = listener; +#ifdef AXIS2_SVR_MULTI_THREADED + if (env->thread_pool) + { + worker_thread = + axutil_thread_pool_get_thread(env->thread_pool, + axis2_listener_manager_worker_func, + (void *) arg_list); + if (!worker_thread) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Thread creation failed" + "Invoke non blocking failed"); + } + else + { + /*axutil_thread_pool_thread_detach(env->thread_pool, + worker_thread);*/ + /* we should not detach this, because, in the dual channel case + we should be able to terminate the thread before deleting the listener */ + } + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Thread pool not set in environment." + " Cannot invoke call non blocking"); + } +#else + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Threading not enabled." + " Cannot start separate listener"); + return AXIS2_FAILURE; +#endif + + tl_state = AXIS2_MALLOC(env->allocator, + sizeof(axis2_transport_listener_state_t)); + + if(!tl_state) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "No memory. Cannot create transport listener state."); + } + else + { + tl_state->listener = listener; + tl_state->waiting_calls = 0; + listener_manager->listener_map[transport] = tl_state; + listener_manager->listener_thread[transport] = worker_thread; + } + } + } + } + } + + if(tl_state) + { + tl_state->waiting_calls++; + return AXIS2_SUCCESS; + } + else + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_listener_manager_stop( + axis2_listener_manager_t * listener_manager, + const axutil_env_t * env, + const AXIS2_TRANSPORT_ENUMS transport) +{ + axis2_transport_listener_state_t *tl_state = NULL; + axis2_status_t status = AXIS2_FAILURE; + axutil_thread_t *listener_thread = NULL; + + tl_state = listener_manager->listener_map[transport]; + listener_thread = listener_manager->listener_thread[transport]; + + if(tl_state) + { + tl_state->waiting_calls--; + if(tl_state->waiting_calls == 0) + { + status = axis2_transport_receiver_stop(tl_state->listener, env); + if(status == AXIS2_SUCCESS) + listener_manager->listener_map[transport] = NULL; + } + } + + if(listener_thread) + { + axutil_thread_pool_exit_thread(env->thread_pool, listener_thread); + listener_manager->listener_thread[transport] = NULL; + } + + return status; +} + +AXIS2_EXTERN axis2_endpoint_ref_t *AXIS2_CALL +axis2_listener_manager_get_reply_to_epr( + const axis2_listener_manager_t * listener_manager, + const axutil_env_t * env, + const axis2_char_t * svc_name, + const AXIS2_TRANSPORT_ENUMS transport) +{ + axis2_transport_listener_state_t *tl_state = NULL; + + tl_state = listener_manager->listener_map[transport]; + if(tl_state) + { + return axis2_transport_receiver_get_reply_to_epr(tl_state->listener, env, svc_name); + } + return NULL; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_listener_manager_free( + axis2_listener_manager_t * listener_manager, + const axutil_env_t * env) +{ + int i = 0; + + for(i = 0; i < AXIS2_TRANSPORT_ENUM_MAX; i++) + { + if(listener_manager->listener_map[i]) + AXIS2_FREE(env->allocator, listener_manager->listener_map[i]); + } + + AXIS2_FREE(env->allocator, listener_manager); +} + +AXIS2_EXTERN axis2_conf_ctx_t *AXIS2_CALL +axis2_listener_manager_get_conf_ctx( + const axis2_listener_manager_t * listener_manager, + const axutil_env_t * env) +{ + return listener_manager->conf_ctx; +} + +void *AXIS2_THREAD_FUNC +axis2_listener_manager_worker_func( + axutil_thread_t * thd, + void *data) +{ + axis2_listener_manager_worker_func_args_t *args_list = NULL; + const axutil_env_t *th_env = NULL; + + args_list = (axis2_listener_manager_worker_func_args_t *)data; + if(!args_list) + return NULL; + + th_env = axutil_init_thread_env(args_list->env); + /* Start the protocol server. For examlle if protocol is http axis2_http_server_start function + * of the axis2_http_receiver is called. + */ + if(args_list->listener) + { + axis2_transport_receiver_start(args_list->listener, th_env); + } + return NULL; +} |