]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add limits to simo open sql handles
authorAnthony Minessale <anthm@freeswitch.org>
Fri, 4 Mar 2011 19:52:30 +0000 (13:52 -0600)
committerAnthony Minessale <anthm@freeswitch.org>
Fri, 4 Mar 2011 19:52:30 +0000 (13:52 -0600)
conf/autoload_configs/switch.conf.xml
src/include/private/switch_core_pvt.h
src/switch_core.c
src/switch_core_sqldb.c

index 4f72c6a65d91d016be54a6e4d2dcbb7381052dcf..d2500a6463146a682f98d9e4f3d3942dddc3a103 100644 (file)
     <!--Colorize the Console -->
     <param name="colorize-console" value="true"/>
 
+    <!-- maximum number of simo db handles open -->
+    <param name="max-db-handles" value="50"/>
+    <!-- maximum number of seconds to wait for a new db handle before failing -->
+    <param name="db-handle-timeout" value="10"/>
+
     <!-- minimum idle CPU before refusing calls -->
     <!--<param name="min-idle-cpu" value="25"/>-->
 
index ab0777ed3b864302839663342b2fb8f9c3870ac8..0ef64d10798a20b983f960d0feacca520ed297ec 100644 (file)
@@ -249,6 +249,8 @@ struct switch_runtime {
        switch_dbtype_t odbc_dbtype;
        char hostname[256];
        int multiple_registrations;
+       uint32_t max_db_handles;
+       uint32_t db_handle_timeout;
 };
 
 extern struct switch_runtime runtime;
index 50fe313f828c4eb2f103fda238316e1cab26e8cb..96e4b4ae276b1d8b21bc275b28d18be3e3ee4092 100644 (file)
@@ -1283,7 +1283,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc
        memset(&runtime, 0, sizeof(runtime));
        gethostname(runtime.hostname, sizeof(runtime.hostname));
 
-
+       runtime.max_db_handles = 50;
+       runtime.db_handle_timeout = 5000000;;
+       
        runtime.runlevel++;
        runtime.sql_buffer_len = 1024 * 32;
        runtime.max_sql_buffer_len = 1024 * 1024;
@@ -1550,6 +1552,23 @@ static void switch_load_core_config(const char *file)
                                        if (tmp > -1 && tmp < 11) {
                                                switch_core_session_ctl(SCSC_DEBUG_LEVEL, &tmp);
                                        }
+                               } else if (!strcasecmp(var, "max-db-handles")) {
+                                       long tmp = atol(val);
+
+                                       if (tmp > 4 && tmp < 5001) {
+                                               runtime.max_db_handles = (uint32_t) tmp;
+                                       } else {
+                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "max-db-handles must be between 5 and 5000\n");
+                                       }
+                               } else if (!strcasecmp(var, "db-handle-timeout")) {
+                                       long tmp = atol(val);
+                                       
+                                       if (tmp > 0 && tmp < 5001) {
+                                               runtime.db_handle_timeout = (uint32_t) tmp * 1000000;
+                                       } else {
+                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "db-handle-timeout must be between 1 and 5000\n");
+                                       }
+                                       
                                } else if (!strcasecmp(var, "multiple-registrations")) {
                                        runtime.multiple_registrations = switch_true(val);
                                } else if (!strcasecmp(var, "sql-buffer-len")) {
index 8dbdd44895a1c6527bd3182f4a03b3026ae9fe77..a4ed5ca83c4d5df5264c0da7db62db4184bf30af 100644 (file)
@@ -66,8 +66,8 @@ static struct {
        switch_cache_db_handle_t *handle_pool;
        switch_thread_cond_t *cond;
        switch_mutex_t *cond_mutex;
-       int total_handles;
-       int total_used_handles;
+       uint32_t total_handles;
+       uint32_t total_used_handles;
 } sql_manager;
 
 
@@ -273,11 +273,29 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h
        char db_callsite_str[CACHE_DB_LEN] = "";
        switch_cache_db_handle_t *new_dbh = NULL;
        switch_ssize_t hlen = -1;
+       int waiting = 0;
+       uint32_t yield_len = 100000, total_yield = 0;
 
        const char *db_name = NULL;
        const char *db_user = NULL;
        const char *db_pass = NULL;
 
+       while(runtime.max_db_handles && sql_manager.total_handles >= runtime.max_db_handles && sql_manager.total_used_handles >= sql_manager.total_handles) {
+               if (!waiting++) {
+                       switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_WARNING, "Max handles %u exceeded, blocking....\n", 
+                                                         runtime.max_db_handles);
+               }
+
+               switch_yield(yield_len);
+               total_yield += yield_len;
+               
+               if (runtime.db_handle_timeout && total_yield > runtime.db_handle_timeout) {
+                       switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "Error connecting\n");
+                       *dbh = NULL;
+                       return SWITCH_STATUS_FALSE;
+               }
+       }
+
        switch (type) {
        case SCDB_TYPE_ODBC:
                {