]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
fix some races and alter core (do a full rebuild)
authorAnthony Minessale <anthony.minessale@gmail.com>
Mon, 24 Sep 2007 19:34:25 +0000 (19:34 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Mon, 24 Sep 2007 19:34:25 +0000 (19:34 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5751 d0543943-73ff-0310-b7d9-9358b9ac24b2

17 files changed:
src/include/switch_channel.h
src/include/switch_loadable_module.h
src/mod/applications/mod_conference/mod_conference.c
src/mod/applications/mod_enum/mod_enum.c
src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c
src/mod/endpoints/mod_dingaling/mod_dingaling.c
src/mod/endpoints/mod_iax/mod_iax.c
src/mod/endpoints/mod_sofia/mod_sofia.c
src/mod/endpoints/mod_sofia/sofia_glue.c
src/mod/endpoints/mod_sofia/sofia_presence.c
src/mod/formats/mod_native_file/mod_native_file.c
src/mod/languages/mod_mono/mod_mono.c
src/switch_channel.c
src/switch_core_session.c
src/switch_ivr.c
src/switch_ivr_originate.c
src/switch_loadable_module.c

index 70acd812ec6be39f49c1d5aa7555f78bad80615d..69dbdbc84719a0db30506ab6dcf57c8c5b1da0e2 100644 (file)
@@ -227,7 +227,7 @@ SWITCH_DECLARE(char *) switch_channel_get_variable(switch_channel_t *channel, co
  *          pool is NULL, then an internal, non-thread-safe iterator is used.
  * @remark  Use switch_hash_next and switch_hash_this with this function to iterate all the channel variables
  */
-SWITCH_DECLARE(switch_hash_index_t *) switch_channel_variable_first(switch_channel_t *channel, switch_memory_pool_t *pool);
+SWITCH_DECLARE(switch_hash_index_t *) switch_channel_variable_first(switch_channel_t *channel);
 SWITCH_DECLARE(void) switch_channel_variable_last(switch_channel_t *channel);
 
 /*!
index 2d2b1fde0b9372250162af69576e57a599f98831..a38446fac4808680b413f70864b0ef8ee438307f 100644 (file)
@@ -200,12 +200,11 @@ SWITCH_DECLARE(switch_management_interface_t *) switch_loadable_module_get_manag
 
 /*!
   \brief Retrieve the list of loaded codecs into an array
-  \param pool the memory pool to use for the hash index
   \param array the array to populate
   \param arraylen the max size in elements of the array
   \return the number of elements added to the array
  */
-SWITCH_DECLARE(int) switch_loadable_module_get_codecs(switch_memory_pool_t *pool, const switch_codec_implementation_t **array, int arraylen);
+SWITCH_DECLARE(int) switch_loadable_module_get_codecs(const switch_codec_implementation_t **array, int arraylen);
 
 
 /*!
index cc806a75c0fc807e03b5273df74b240ec49af98e..f5a78ecaa9b693939b282b311bd0cbf3a9a925fa 100644 (file)
@@ -2822,7 +2822,7 @@ static switch_status_t conf_api_sub_list(conference_obj_t * conference, switch_s
        }
 
        if (conference == NULL) {
-               for (hi = switch_hash_first(globals.conference_pool, globals.conference_hash); hi; hi = switch_hash_next(hi)) {
+               for (hi = switch_hash_first(NULL, globals.conference_hash); hi; hi = switch_hash_next(hi)) {
                        switch_hash_this(hi, NULL, NULL, &val);
                        conference = (conference_obj_t *) val;
 
index 72fd62b0f3f1e4bec7ac384da8151015891abd95..b03783a9a995130f262c1c6e53fe37ed1629bbf2 100644 (file)
@@ -586,7 +586,7 @@ SWITCH_STANDARD_APP(enum_app_function)
                        void *vval;
                        const void *vvar;
 
-                       if ((hi = switch_channel_variable_first(channel, switch_core_session_get_pool(session)))) {
+                       if ((hi = switch_channel_variable_first(channel))) {
                                for (; hi; hi = switch_hash_next(hi)) {
                                        switch_hash_this(hi, &vvar, NULL, &vval);
                                        if (vvar && !strncmp(vvar, "enum_", 5)) {
index b36a7be0a149738dd76dfcfeb9d09fdd290dfb7c..f2a957afe070ff1ea64b415f602cfe95b979d208 100644 (file)
@@ -252,7 +252,7 @@ static switch_status_t dialplan_xml_locate(switch_core_session_t *session, switc
                stream.write_function(&stream, "%s=%s&", prof_names[x], encode_buf);
        }
 
-       if ((hi = switch_channel_variable_first(channel, switch_core_session_get_pool(session)))) {
+       if ((hi = switch_channel_variable_first(channel))) {
                for (; hi; hi = switch_hash_next(hi)) {
                        void *val;
                        const void *var;
index 534e0f2bd29330698ccd683cd83c737755e8d06c..7ecb7f868b853bdb4940d49ff8340e565fefe8a0 100644 (file)
@@ -477,7 +477,7 @@ static void pres_event_handler(switch_event_t *event)
        sql = switch_mprintf("select sub_from, sub_to,'%q','%q','%q','%q' from jabber_subscriptions where sub_to like '%%%q'", type, rpid, status, proto, from);
 
 
-       for (hi = switch_hash_first(switch_hash_pool_get(globals.profile_hash), globals.profile_hash); hi; hi = switch_hash_next(hi)) {
+       for (hi = switch_hash_first(NULL, globals.profile_hash); hi; hi = switch_hash_next(hi)) {
                switch_hash_this(hi, NULL, NULL, &val);
                profile = (mdl_profile_t *) val;
 
@@ -572,7 +572,7 @@ static void roster_event_handler(switch_event_t *event)
                sql = switch_mprintf("select *,'%q' from jabber_subscriptions", status ? status : "");
        }
 
-       for (hi = switch_hash_first(switch_hash_pool_get(globals.profile_hash), globals.profile_hash); hi; hi = switch_hash_next(hi)) {
+       for (hi = switch_hash_first(NULL, globals.profile_hash); hi; hi = switch_hash_next(hi)) {
                switch_hash_this(hi, NULL, NULL, &val);
                profile = (mdl_profile_t *) val;
 
@@ -642,7 +642,7 @@ static void sign_off(void)
        sql = switch_mprintf("select * from jabber_subscriptions");
 
 
-       for (hi = switch_hash_first(switch_hash_pool_get(globals.profile_hash), globals.profile_hash); hi; hi = switch_hash_next(hi)) {
+       for (hi = switch_hash_first(NULL, globals.profile_hash); hi; hi = switch_hash_next(hi)) {
                switch_hash_this(hi, NULL, NULL, &val);
                profile = (mdl_profile_t *) val;
 
@@ -760,7 +760,7 @@ static int get_codecs(struct private_object *tech_pvt)
                                return 0;
                        }
                } else if (((tech_pvt->num_codecs =
-                                        switch_loadable_module_get_codecs(switch_core_session_get_pool(tech_pvt->session), tech_pvt->codecs, SWITCH_MAX_CODECS))) <= 0) {
+                                        switch_loadable_module_get_codecs(tech_pvt->codecs, SWITCH_MAX_CODECS))) <= 0) {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NO codecs?\n");
                        return 0;
                }
index 7e5020851277422a0f401f443b8e74b09634603f..7c1ea5d16f3c9ecbe4a725d6da00d511bd49e38f 100644 (file)
@@ -230,7 +230,7 @@ static switch_status_t iax_set_codec(private_t * tech_pvt, struct iax_session *i
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NO codecs?\n");
                        return SWITCH_STATUS_GENERR;
                }
-       } else if (((num_codecs = switch_loadable_module_get_codecs(switch_core_session_get_pool(tech_pvt->session), codecs, SWITCH_MAX_CODECS))) <= 0) {
+       } else if (((num_codecs = switch_loadable_module_get_codecs(codecs, SWITCH_MAX_CODECS))) <= 0) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NO codecs?\n");
                return SWITCH_STATUS_GENERR;
        }
index ab5b2d1b47c4b16396e1e53a9ffe35ed33b811d8..09b061db9064f88ff571e59bcaa5ca850d49a653 100644 (file)
@@ -1090,7 +1090,7 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t
        stream->write_function(stream, "%25s\t%s\t  %32s\t%s\n", "Name", "   Type", "Data", "State");
        stream->write_function(stream, "%s\n", line);
        switch_mutex_lock(mod_sofia_globals.hash_mutex);
-       for (hi = switch_hash_first(switch_hash_pool_get(mod_sofia_globals.profile_hash), mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
+       for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
                switch_hash_this(hi, &vvar, NULL, &val);
                profile = (sofia_profile_t *) val;
                if (sofia_test_pflag(profile, PFLAG_RUNNING)) {
index 1474a3a3b4b64125e40a4b07f8f7e2e96ee5d260..117743ad44b32242bc52edb918cc72a7c9a9c104 100644 (file)
@@ -264,7 +264,7 @@ void sofia_glue_tech_prepare_codecs(private_object_t *tech_pvt)
                }
        } else {
                tech_pvt->num_codecs =
-                       switch_loadable_module_get_codecs(switch_core_session_get_pool(tech_pvt->session), tech_pvt->codecs,
+                       switch_loadable_module_get_codecs(tech_pvt->codecs,
                                                                                          sizeof(tech_pvt->codecs) / sizeof(tech_pvt->codecs[0]));
        }
 
@@ -574,7 +574,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
        }
 
        SWITCH_STANDARD_STREAM(stream);
-       if ((hi = switch_channel_variable_first(channel, switch_core_session_get_pool(tech_pvt->session)))) {
+       if ((hi = switch_channel_variable_first(channel))) {
                for (; hi; hi = switch_hash_next(hi)) {
                        switch_hash_this(hi, &vvar, NULL, &vval);
                        if (vvar && vval) {
@@ -1540,14 +1540,14 @@ void sofia_glue_del_profile(sofia_profile_t *profile)
 
 
        switch_mutex_lock(mod_sofia_globals.hash_mutex);
-       for (hi = switch_hash_first(switch_hash_pool_get(mod_sofia_globals.profile_hash), mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
+       for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
                switch_hash_this(hi, &vvar, NULL, &vval);
                this_profile = (sofia_profile_t *) vval;
                if (this_profile == profile) {
                        switch_core_hash_delete(mod_sofia_globals.profile_hash, vvar);
                }
        }
-       for (hi = switch_hash_first(switch_hash_pool_get(mod_sofia_globals.gateway_hash), mod_sofia_globals.gateway_hash); hi; hi = switch_hash_next(hi)) {
+       for (hi = switch_hash_first(NULL, mod_sofia_globals.gateway_hash); hi; hi = switch_hash_next(hi)) {
                switch_hash_this(hi, &vvar, NULL, &vval);
         this_gateway = (sofia_gateway_t *) vval;
 
index 7133c9a8736bc21fe4d0a856540812c3ab721ddb..f0691cca15c5b7d14c57354a6c82756d9751361c 100644 (file)
@@ -116,7 +116,7 @@ void sofia_presence_cancel(void)
 
        if ((sql = switch_mprintf("select 0,'unavailable','unavailable',* from sip_subscriptions where event='presence'"))) {
                switch_mutex_lock(mod_sofia_globals.hash_mutex);
-               for (hi = switch_hash_first(switch_hash_pool_get(mod_sofia_globals.profile_hash), mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
+               for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
                        switch_hash_this(hi, NULL, NULL, &val);
                        profile = (sofia_profile_t *) val;
                        if (!(profile->pflags & PFLAG_PRESENCE)) {
@@ -294,7 +294,7 @@ void sofia_presence_event_handler(switch_event_t *event)
                
                assert(sql != NULL);
                switch_mutex_lock(mod_sofia_globals.hash_mutex);
-               for (hi = switch_hash_first(switch_hash_pool_get(mod_sofia_globals.profile_hash), mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
+               for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
                        switch_hash_this(hi, NULL, NULL, &val);
                        profile = (sofia_profile_t *) val;
                        if (!(profile->pflags & PFLAG_PRESENCE)) {
@@ -396,7 +396,7 @@ void sofia_presence_event_handler(switch_event_t *event)
        }
 
        switch_mutex_lock(mod_sofia_globals.hash_mutex);
-       for (hi = switch_hash_first(switch_hash_pool_get(mod_sofia_globals.profile_hash), mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
+       for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
                switch_hash_this(hi, NULL, NULL, &val);
                profile = (sofia_profile_t *) val;
                if (!(profile->pflags & PFLAG_PRESENCE)) {
index db22600e4f7fcc0dfe9b8a363569e12ad8196647..280c054386423ed389e0c75b1f29384422f61a52 100644 (file)
@@ -144,7 +144,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_native_file_load)
        switch_file_interface_t *file_interface;
 
        const switch_codec_implementation_t *codecs[SWITCH_MAX_CODECS];
-       uint32_t num_codecs = switch_loadable_module_get_codecs(NULL, codecs, sizeof(codecs) / sizeof(codecs[0]));
+       uint32_t num_codecs = switch_loadable_module_get_codecs(codecs, sizeof(codecs) / sizeof(codecs[0]));
        uint32_t x;
 
        for (x = 0; x < num_codecs; x++) {
index 95943320dc1726a207beb4f765f630ae27b4efad..0468d074c54a0dad54d488688bfb4a14fa9926be 100644 (file)
@@ -142,7 +142,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_mono_load)
        /* Finally, go through and initialise each plugin before returning SUCCESS */
        switch_hash_index_t *p = NULL;
 
-       for (p = switch_hash_first(mono_pool, globals.plugins); p; p = switch_hash_next(p)) {
+       for (p = switch_hash_first(NULL, globals.plugins); p; p = switch_hash_next(p)) {
                mono_plugin *plugin = (mono_plugin *) switch_core_alloc(mono_pool, sizeof(*plugin));
                switch_ssize_t *key_length = NULL;
                const void *key = NULL;
index 700cc264638acacebcb6e64a1694db9df59b7fff..b787fdfd7a85f7bdc7fa343b62719b38d518ebf2 100644 (file)
@@ -342,15 +342,17 @@ SWITCH_DECLARE(void) switch_channel_variable_last(switch_channel_t *channel)
        }
 }
 
-SWITCH_DECLARE(switch_hash_index_t *) switch_channel_variable_first(switch_channel_t *channel, switch_memory_pool_t *pool)
+SWITCH_DECLARE(switch_hash_index_t *) switch_channel_variable_first(switch_channel_t *channel)
 {
        switch_hash_index_t *hi;
 
        assert(channel != NULL);
 
-       if ((hi = switch_hash_first(pool, channel->variables))) {
-               switch_mutex_lock(channel->profile_mutex);
+       switch_mutex_lock(channel->profile_mutex);
+       if ((hi = switch_hash_first(NULL, channel->variables))) {
                channel->vi = 1;
+       } else {
+               switch_mutex_unlock(channel->profile_mutex);
        }
 
        return hi;
@@ -818,7 +820,7 @@ SWITCH_DECLARE(void) switch_channel_event_set_data(switch_channel_t *channel, sw
        }
 
        /* Index Variables */
-       for (hi = switch_hash_first(switch_core_session_get_pool(channel->session), channel->variables); hi; hi = switch_hash_next(hi)) {
+       for (hi = switch_hash_first(NULL, channel->variables); hi; hi = switch_hash_next(hi)) {
                char buf[1024];
                switch_hash_this(hi, &var, NULL, &val);
                if (var && val) {
index 799de84c8c62a623a0b554c31217fbea1cd73fc1..2f40faa921070a343ed36d6796d0558a071f5387 100644 (file)
@@ -81,7 +81,7 @@ SWITCH_DECLARE(void) switch_core_session_hupall(switch_call_cause_t cause)
        uint32_t loops = 0;
 
        switch_mutex_lock(session_manager.session_table_mutex);
-       for (hi = switch_hash_first(session_manager.memory_pool, session_manager.session_table); hi; hi = switch_hash_next(hi)) {
+       for (hi = switch_hash_first(NULL, session_manager.session_table); hi; hi = switch_hash_next(hi)) {
                switch_hash_this(hi, NULL, NULL, &val);
                if (val) {
                        session = (switch_core_session_t *) val;
@@ -388,10 +388,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_queue_message(switch_core_se
 
        assert(session != NULL);
 
-       if (!session->message_queue) {
-               switch_queue_create(&session->message_queue, SWITCH_MESSAGE_QUEUE_LEN, session->pool);
-       }
-
        if (session->message_queue) {
                if (switch_queue_trypush(session->message_queue, message) == SWITCH_STATUS_SUCCESS) {
                        status = SWITCH_STATUS_SUCCESS;
@@ -477,10 +473,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_queue_event(switch_core_sess
 
        assert(session != NULL);
 
-       if (!session->event_queue) {
-               switch_queue_create(&session->event_queue, SWITCH_EVENT_QUEUE_LEN, session->pool);
-       }
-
        if (session->event_queue) {
                if (switch_queue_trypush(session->event_queue, *event) == SWITCH_STATUS_SUCCESS) {
                        *event = NULL;
@@ -522,10 +514,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_queue_private_event(switch_c
 
        assert(session != NULL);
 
-       if (!session->private_event_queue) {
-               switch_queue_create(&session->private_event_queue, SWITCH_EVENT_QUEUE_LEN, session->pool);
-       }
-
        if (session->private_event_queue) {
                (*event)->event_id = SWITCH_EVENT_PRIVATE_COMMAND;
                if (switch_queue_trypush(session->private_event_queue, *event) == SWITCH_STATUS_SUCCESS) {
@@ -818,6 +806,9 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request(const switch
        switch_thread_rwlock_create(&session->bug_rwlock, session->pool);
        switch_thread_cond_create(&session->cond, session->pool);
        switch_thread_rwlock_create(&session->rwlock, session->pool);
+       switch_queue_create(&session->message_queue, SWITCH_MESSAGE_QUEUE_LEN, session->pool);
+       switch_queue_create(&session->event_queue, SWITCH_EVENT_QUEUE_LEN, session->pool);
+       switch_queue_create(&session->private_event_queue, SWITCH_EVENT_QUEUE_LEN, session->pool);
 
        snprintf(session->name, sizeof(session->name), "%"SWITCH_SIZE_T_FMT, session->id);
        switch_mutex_lock(session_manager.session_table_mutex);
index 8f4ad2e7fdd157040a944a212d7af1cc54734cbe..eae808c822f1b8df4aaefd4e71b2c65ca0ebdd10 100644 (file)
@@ -967,7 +967,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_transfer_variable(switch_core_session
                void *vval;
                const void *vvar;
 
-               if ((hi = switch_channel_variable_first(chana, switch_core_session_get_pool(sessa)))) {
+               if ((hi = switch_channel_variable_first(chana))) {
                        for (; hi; hi = switch_hash_next(hi)) {
                                switch_hash_this(hi, &vvar, NULL, &vval);
                                if (vvar && vval && (!prefix || (var && !strncmp((char *) vvar, var, strlen(var))))) {
@@ -1330,7 +1330,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_generate_xml_cdr(switch_core_session_
                }
        }
 
-       if (((hi = switch_channel_variable_first(channel, switch_core_session_get_pool(session))))) {
+       if (((hi = switch_channel_variable_first(channel)))) {
                for (; hi; hi = switch_hash_next(hi)) {
                        switch_hash_this(hi, &vvar, NULL, &vval);
                        if (vvar && vval) {
index de32ce367a9cfc6d23ff8d05dd3278b67ce0a797..f7d017cc70cd71c7f7fc9fbdec2beac50398784a 100644 (file)
@@ -323,7 +323,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
                assert(caller_channel != NULL);
 
                /* Copy all the channel variables into the event */
-               if ((hi = switch_channel_variable_first(caller_channel, switch_core_session_get_pool(session)))) {
+               if ((hi = switch_channel_variable_first(caller_channel))) {
                        for (; hi; hi = switch_hash_next(hi)) {
                                switch_hash_this(hi, &vvar, NULL, &vval);
                                if (vvar && vval) {
index 3aea3b1a0cbf1a52ab67c6cbf4c3daef78e2f422..4a9ce82a3144cc16261e12a5feea80a319401a43 100644 (file)
@@ -108,7 +108,7 @@ static void switch_loadable_module_runtime(void)
        switch_loadable_module_t *module;
 
        switch_mutex_lock(loadable_modules.mutex);
-       for (hi = switch_hash_first(loadable_modules.pool, loadable_modules.module_hash); hi; hi = switch_hash_next(hi)) {
+       for (hi = switch_hash_first(NULL, loadable_modules.module_hash); hi; hi = switch_hash_next(hi)) {
                switch_hash_this(hi, NULL, NULL, &val);
                module = (switch_loadable_module_t *) val;
 
@@ -1078,7 +1078,7 @@ SWITCH_DECLARE(void) switch_loadable_module_shutdown(void)
        void *val;
        switch_loadable_module_t *module;
        
-       for (hi = switch_hash_first(loadable_modules.pool, loadable_modules.module_hash); hi; hi = switch_hash_next(hi)) {
+       for (hi = switch_hash_first(NULL, loadable_modules.module_hash); hi; hi = switch_hash_next(hi)) {
                switch_hash_this(hi, NULL, NULL, &val);
                module = (switch_loadable_module_t *) val;
                do_shutdown(module);
@@ -1174,7 +1174,7 @@ SWITCH_DECLARE(switch_management_interface_t *) switch_loadable_module_get_manag
        return switch_core_hash_find_locked(loadable_modules.management_hash, relative_oid, loadable_modules.mutex);
 }
 
-SWITCH_DECLARE(int) switch_loadable_module_get_codecs(switch_memory_pool_t *pool, const switch_codec_implementation_t **array, int arraylen)
+SWITCH_DECLARE(int) switch_loadable_module_get_codecs(const switch_codec_implementation_t **array, int arraylen)
 {
        switch_hash_index_t *hi;
        void *val;
@@ -1183,7 +1183,7 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs(switch_memory_pool_t *pool
        const switch_codec_implementation_t *imp;
 
        switch_mutex_lock(loadable_modules.mutex);
-       for (hi = switch_hash_first(pool, loadable_modules.codec_hash); hi; hi = switch_hash_next(hi)) {
+       for (hi = switch_hash_first(NULL, loadable_modules.codec_hash); hi; hi = switch_hash_next(hi)) {
                switch_hash_this(hi, NULL, NULL, &val);
                codec_interface = (switch_codec_interface_t *) val;
                /* Look for a 20ms implementation because it's the safest choice */