From e4a513f0732824ec1148a85d1ef3e7b5e3d3f99a Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 10 Apr 2009 21:29:09 +0000 Subject: [PATCH] keep new conference locked the whole time during transfer git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@12988 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- .../mod_conference/mod_conference.c | 136 +++++++++--------- 1 file changed, 71 insertions(+), 65 deletions(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 1b524495c5..61bd810f3d 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -3635,6 +3635,8 @@ static switch_status_t conf_api_sub_transfer(conference_obj_t *conference, switc switch_status_t ret_status = SWITCH_STATUS_SUCCESS; char *conf_name = NULL, *profile_name; switch_event_t *params = NULL; + conference_obj_t *new_conference = NULL; + switch_assert(conference != NULL); switch_assert(stream != NULL); @@ -3652,7 +3654,6 @@ static switch_status_t conf_api_sub_transfer(conference_obj_t *conference, switc for (x = 3; x < argc; x++) { conference_member_t *member = NULL; uint32_t id = atoi(argv[x]); - conference_obj_t *new_conference = NULL; switch_channel_t *channel; switch_event_t *event; switch_xml_t cxml = NULL, cfg = NULL, profiles = NULL; @@ -3664,71 +3665,73 @@ static switch_status_t conf_api_sub_transfer(conference_obj_t *conference, switc channel = switch_core_session_get_channel(member->session); - /* build a new conference if it doesn't exist */ - if (!(new_conference = (conference_obj_t *) switch_core_hash_find(globals.conference_hash, conf_name))) { - switch_memory_pool_t *pool = NULL; - conf_xml_cfg_t xml_cfg = { 0 }; + if (!new_conference) { + if (!(new_conference = (conference_obj_t *) switch_core_hash_find(globals.conference_hash, conf_name))) { + /* build a new conference if it doesn't exist */ + switch_memory_pool_t *pool = NULL; + conf_xml_cfg_t xml_cfg = { 0 }; - /* Setup a memory pool to use. */ - if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Pool Failure\n"); - goto done; - } - - switch_event_create(¶ms, SWITCH_EVENT_REQUEST_PARAMS); - switch_assert(params); - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "conf_name", conf_name); - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "profile_name", profile_name); - switch_channel_event_set_data(channel, params); - - /* Open the config from the xml registry */ - if (!(cxml = switch_xml_open_cfg(global_cf_name, &cfg, params))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf_name); - goto done; - } - - if ((profiles = switch_xml_child(cfg, "profiles"))) { - xml_cfg.profile = switch_xml_find_child(profiles, "profile", "name", profile_name); - } - - if (!xml_cfg.profile) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find profile: %s\n", profile_name); - switch_xml_free(cxml); - cxml = NULL; - goto done; - } - - xml_cfg.controls = switch_xml_child(cfg, "caller-controls"); - - /* Release the config registry handle */ - if (cxml) { - switch_xml_free(cxml); - cxml = NULL; - } - - /* Create the conference object. */ - new_conference = conference_new(conf_name, xml_cfg, pool); - - if (!new_conference) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n"); - if (pool != NULL) { - switch_core_destroy_memory_pool(&pool); + /* Setup a memory pool to use. */ + if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Pool Failure\n"); + goto done; } - goto done; + + switch_event_create(¶ms, SWITCH_EVENT_REQUEST_PARAMS); + switch_assert(params); + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "conf_name", conf_name); + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "profile_name", profile_name); + switch_channel_event_set_data(channel, params); + + /* Open the config from the xml registry */ + if (!(cxml = switch_xml_open_cfg(global_cf_name, &cfg, params))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf_name); + goto done; + } + + if ((profiles = switch_xml_child(cfg, "profiles"))) { + xml_cfg.profile = switch_xml_find_child(profiles, "profile", "name", profile_name); + } + + if (!xml_cfg.profile) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find profile: %s\n", profile_name); + switch_xml_free(cxml); + cxml = NULL; + goto done; + } + + xml_cfg.controls = switch_xml_child(cfg, "caller-controls"); + + /* Release the config registry handle */ + if (cxml) { + switch_xml_free(cxml); + cxml = NULL; + } + + /* Create the conference object. */ + new_conference = conference_new(conf_name, xml_cfg, pool); + + if (!new_conference) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n"); + if (pool != NULL) { + switch_core_destroy_memory_pool(&pool); + } + goto done; + } + + /* Set the minimum number of members (once you go above it you cannot go below it) */ + new_conference->min = 1; + + /* Indicate the conference is dynamic */ + switch_set_flag_locked(new_conference, CFLAG_DYNAMIC); + + switch_mutex_lock(new_conference->mutex); + + /* Start the conference thread for this conference */ + launch_conference_thread(new_conference); + } else { + switch_mutex_lock(new_conference->mutex); } - - /* Set the minimum number of members (once you go above it you cannot go below it) */ - new_conference->min = 1; - - /* Indicate the conference is dynamic */ - switch_set_flag_locked(new_conference, CFLAG_DYNAMIC); - - switch_mutex_lock(new_conference->mutex); - - /* Start the conference thread for this conference */ - launch_conference_thread(new_conference); - } else { - switch_mutex_lock(new_conference->mutex); } /* move the member from the old conference to the new one */ @@ -3745,9 +3748,7 @@ static switch_status_t conf_api_sub_transfer(conference_obj_t *conference, switc } } - switch_mutex_unlock(new_conference->mutex); switch_mutex_unlock(member->control_mutex); - stream->write_function(stream, "OK Member '%d' sent to conference %s.\n", member->id, argv[2]); @@ -3761,6 +3762,11 @@ static switch_status_t conf_api_sub_transfer(conference_obj_t *conference, switc switch_event_fire(&event); } } + + if (new_conference) { + switch_mutex_unlock(new_conference->mutex); + } + } else { ret_status = SWITCH_STATUS_GENERR; }