Browse Source

multi-threaded DB connections.

mom040267 11 years ago
parent
commit
6b291a8238

+ 7 - 5
src/apps/relay/dbdrivers/dbd_mongo.c

@@ -82,7 +82,7 @@ static MONGO * get_mongodb_connection(void) {
 
 	persistent_users_db_t * pud = get_persistent_users_db();
 
-	MONGO * mydbconnection = (MONGO *) (pud->connection);
+	MONGO * mydbconnection = (MONGO *) pthread_getspecific(connection_key);
 
 	if (!mydbconnection) {
 		mongoc_init();
@@ -111,7 +111,9 @@ static MONGO * get_mongodb_connection(void) {
 						mydbconnection->uri);
 				if (!mydbconnection->database)
 					mydbconnection->database = MONGO_DEFAULT_DB;
-				pud->connection = mydbconnection;
+				if(mydbconnection) {
+					(void) pthread_setspecific(connection_key, mydbconnection);
+				}
 				TURN_LOG_FUNC(
 					TURN_LOG_LEVEL_INFO,
 					"Opened MongoDB URI <%s>\n",
@@ -1172,7 +1174,7 @@ static void mongo_reread_realms(secrets_list_t * realms_list) {
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-static turn_dbdriver_t driver = {
+static const turn_dbdriver_t driver = {
   &mongo_get_auth_secrets,
   &mongo_get_user_key,
   &mongo_get_user_pwd,
@@ -1197,7 +1199,7 @@ static turn_dbdriver_t driver = {
   &mongo_list_oauth_keys
 };
 
-turn_dbdriver_t * get_mongo_dbdriver(void) {
+const turn_dbdriver_t * get_mongo_dbdriver(void) {
   return &driver;
 }
 
@@ -1205,7 +1207,7 @@ turn_dbdriver_t * get_mongo_dbdriver(void) {
 
 #else
 
-turn_dbdriver_t * get_mongo_dbdriver(void) {
+const turn_dbdriver_t * get_mongo_dbdriver(void) {
   return NULL;
 }
 

+ 1 - 1
src/apps/relay/dbdrivers/dbd_mongo.h

@@ -38,7 +38,7 @@
 extern "C" {
 #endif
 
-turn_dbdriver_t * get_mongo_dbdriver(void);
+const turn_dbdriver_t * get_mongo_dbdriver(void);
 
 #ifdef __cplusplus
 }

+ 9 - 5
src/apps/relay/dbdrivers/dbd_mysql.c

@@ -189,14 +189,16 @@ static Myconninfo *MyconninfoParse(char *userdb, char **errmsg) {
 }
 
 static MYSQL *get_mydb_connection(void) {
+
 	persistent_users_db_t *pud = get_persistent_users_db();
 
-	MYSQL *mydbconnection = (MYSQL*)(pud->connection);
+	MYSQL *mydbconnection = (MYSQL*)pthread_getspecific(connection_key);
 
 	if(mydbconnection) {
 		if(mysql_ping(mydbconnection)) {
 			mysql_close(mydbconnection);
 			mydbconnection=NULL;
+			(void) pthread_setspecific(connection_key, mydbconnection);
 		}
 	}
 
@@ -242,7 +244,9 @@ static MYSQL *get_mydb_connection(void) {
 			}
 			MyconninfoFree(co);
 		}
-		pud->connection = mydbconnection;
+		if(mydbconnection) {
+			(void) pthread_setspecific(connection_key, mydbconnection);
+		}
 	}
 	return mydbconnection;
 }
@@ -1063,7 +1067,7 @@ static void mysql_reread_realms(secrets_list_t * realms_list) {
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-static turn_dbdriver_t driver = {
+static const turn_dbdriver_t driver = {
   &mysql_get_auth_secrets,
   &mysql_get_user_key,
   &mysql_get_user_pwd,
@@ -1088,7 +1092,7 @@ static turn_dbdriver_t driver = {
   &mysql_list_oauth_keys
 };
 
-turn_dbdriver_t * get_mysql_dbdriver(void) {
+const turn_dbdriver_t * get_mysql_dbdriver(void) {
   return &driver;
 }
 
@@ -1096,7 +1100,7 @@ turn_dbdriver_t * get_mysql_dbdriver(void) {
 
 #else
 
-turn_dbdriver_t * get_mysql_dbdriver(void) {
+const turn_dbdriver_t * get_mysql_dbdriver(void) {
   return NULL;
 }
 

+ 1 - 1
src/apps/relay/dbdrivers/dbd_mysql.h

@@ -38,7 +38,7 @@
 extern "C" {
 #endif
 
-turn_dbdriver_t * get_mysql_dbdriver(void);
+const turn_dbdriver_t * get_mysql_dbdriver(void);
 
 #ifdef __cplusplus
 }

+ 10 - 5
src/apps/relay/dbdrivers/dbd_pgsql.c

@@ -40,14 +40,16 @@
 static int donot_print_connection_success = 0;
 
 static PGconn *get_pqdb_connection(void) {
+
 	persistent_users_db_t *pud = get_persistent_users_db();
 
-	PGconn *pqdbconnection = (PGconn*)(pud->connection);
+	PGconn *pqdbconnection = (PGconn*)pthread_getspecific(connection_key);
 	if(pqdbconnection) {
 		ConnStatusType status = PQstatus(pqdbconnection);
 		if(status != CONNECTION_OK) {
 			PQfinish(pqdbconnection);
 			pqdbconnection = NULL;
+			(void) pthread_setspecific(connection_key, pqdbconnection);
 		}
 	}
 	if(!pqdbconnection) {
@@ -78,7 +80,10 @@ static PGconn *get_pqdb_connection(void) {
 				}
 			}
 		}
-		pud->connection = pqdbconnection;
+
+		if(pqdbconnection) {
+			(void) pthread_setspecific(connection_key, pqdbconnection);
+		}
 	}
 	return pqdbconnection;
 }
@@ -782,7 +787,7 @@ static void pgsql_reread_realms(secrets_list_t * realms_list) {
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-static turn_dbdriver_t driver = {
+static const turn_dbdriver_t driver = {
   &pgsql_get_auth_secrets,
   &pgsql_get_user_key,
   &pgsql_get_user_pwd,
@@ -807,7 +812,7 @@ static turn_dbdriver_t driver = {
   &pgsql_list_oauth_keys
 };
 
-turn_dbdriver_t * get_pgsql_dbdriver(void) {
+const turn_dbdriver_t * get_pgsql_dbdriver(void) {
   return &driver;
 }
 
@@ -815,7 +820,7 @@ turn_dbdriver_t * get_pgsql_dbdriver(void) {
 
 #else
 
-turn_dbdriver_t * get_pgsql_dbdriver(void) {
+const turn_dbdriver_t * get_pgsql_dbdriver(void) {
   return NULL;
 }
 

+ 1 - 1
src/apps/relay/dbdrivers/dbd_pgsql.h

@@ -38,7 +38,7 @@
 extern "C" {
 #endif
 
-turn_dbdriver_t * get_pgsql_dbdriver(void);
+const turn_dbdriver_t * get_pgsql_dbdriver(void);
 
 #ifdef __cplusplus
 }

+ 8 - 10
src/apps/relay/dbdrivers/dbd_redis.c

@@ -264,14 +264,14 @@ redis_context_handle get_redis_async_connection(struct event_base *base, const c
 static redisContext *get_redis_connection(void) {
 	persistent_users_db_t *pud = get_persistent_users_db();
 
-	redisContext *redisconnection = (redisContext*)(pud->connection);
+	redisContext *redisconnection = (redisContext*)pthread_getspecific(connection_key);
 
 	if(redisconnection) {
 		if(redisconnection->err) {
 			TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Cannot connect to redis, err=%d, flags=0x%lx\n", __FUNCTION__,(int)redisconnection->err,(unsigned long)redisconnection->flags);
 			redisFree(redisconnection);
-			pud->connection = NULL;
 			redisconnection = NULL;
+			(void) pthread_setspecific(connection_key, redisconnection);
 		}
 	}
 
@@ -351,11 +351,9 @@ static redisContext *get_redis_connection(void) {
 
 			RyconninfoFree(co);
 		}
-		pud->connection = redisconnection;
-
-		pud = get_persistent_users_db();
-
-		redisconnection = (redisContext*)(pud->connection);
+		if(redisconnection) {
+			(void) pthread_setspecific(connection_key, redisconnection);
+		}
 	}
 
 	return redisconnection;
@@ -1205,7 +1203,7 @@ static void redis_reread_realms(secrets_list_t * realms_list) {
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-static turn_dbdriver_t driver = {
+static const turn_dbdriver_t driver = {
   &redis_get_auth_secrets,
   &redis_get_user_key,
   &redis_get_user_pwd,
@@ -1230,7 +1228,7 @@ static turn_dbdriver_t driver = {
   &redis_list_oauth_keys
 };
 
-turn_dbdriver_t * get_redis_dbdriver(void) {
+const turn_dbdriver_t * get_redis_dbdriver(void) {
   return &driver;
 }
 
@@ -1238,7 +1236,7 @@ turn_dbdriver_t * get_redis_dbdriver(void) {
 
 #else
 
-turn_dbdriver_t * get_redis_dbdriver(void) {
+const turn_dbdriver_t * get_redis_dbdriver(void) {
   return NULL;
 }
 

+ 1 - 1
src/apps/relay/dbdrivers/dbd_redis.h

@@ -38,7 +38,7 @@
 extern "C" {
 #endif
 
-turn_dbdriver_t * get_redis_dbdriver(void);
+const turn_dbdriver_t * get_redis_dbdriver(void);
 
 #ifdef __cplusplus
 }

+ 12 - 4
src/apps/relay/dbdrivers/dbd_sqlite.c

@@ -119,7 +119,7 @@ static sqlite3 * get_sqlite_connection(void) {
 
 	persistent_users_db_t *pud = get_persistent_users_db();
 
-	sqlite3 *sqliteconnection = (sqlite3 *)(pud->connection);
+	sqlite3 *sqliteconnection = (sqlite3 *)pthread_getspecific(connection_key);
 	if(!sqliteconnection) {
 		fix_user_directory(pud->userdb);
 		sqlite_init_multithreaded();
@@ -136,7 +136,9 @@ static sqlite3 * get_sqlite_connection(void) {
 			init_sqlite_database(sqliteconnection);
 			TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SQLite DB connection success: %s\n",pud->userdb);
 		}
-		pud->connection = sqliteconnection;
+		if(sqliteconnection) {
+			(void) pthread_setspecific(connection_key, sqliteconnection);
+		}
 	}
 	return sqliteconnection;
 }
@@ -936,7 +938,7 @@ static void sqlite_reread_realms(secrets_list_t * realms_list)
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-static turn_dbdriver_t driver = {
+static const turn_dbdriver_t driver = {
   &sqlite_get_auth_secrets,
   &sqlite_get_user_key,
   &sqlite_get_user_pwd,
@@ -963,10 +965,16 @@ static turn_dbdriver_t driver = {
 
 //////////////////////////////////////////////////
 
-turn_dbdriver_t * get_sqlite_dbdriver(void) {
+const turn_dbdriver_t * get_sqlite_dbdriver(void) {
 	return &driver;
 }
 
 //////////////////////////////////////////////////
 
+#else
+
+const turn_dbdriver_t * get_sqlite_dbdriver(void) {
+	return NULL;
+}
+
 #endif

+ 1 - 1
src/apps/relay/dbdrivers/dbd_sqlite.h

@@ -38,7 +38,7 @@
 extern "C" {
 #endif
 
-turn_dbdriver_t * get_sqlite_dbdriver(void);
+const turn_dbdriver_t * get_sqlite_dbdriver(void);
 
 #ifdef __cplusplus
 }

+ 15 - 4
src/apps/relay/dbdrivers/dbdriver.c

@@ -40,7 +40,14 @@
 #include "dbd_mongo.h"
 #include "dbd_redis.h"
 
-static turn_dbdriver_t * _driver;
+static void make_connection_key(void)
+{
+    (void) pthread_key_create(&connection_key, NULL);
+}
+
+
+pthread_key_t connection_key;
+pthread_once_t connection_key_once = PTHREAD_ONCE_INIT;
 
 int convert_string_key_to_binary(char* keysource, hmackey_t key, size_t sz) {
 	char is[3];
@@ -60,13 +67,17 @@ persistent_users_db_t * get_persistent_users_db(void) {
 	return &(turn_params.default_users_db.persistent_users_db);
 }
 
-turn_dbdriver_t * get_dbdriver()
+const turn_dbdriver_t * get_dbdriver()
 {
-
 	if (turn_params.default_users_db.userdb_type == TURN_USERDB_TYPE_UNKNOWN)
 		return NULL;
 
-	if (!_driver) {
+	(void) pthread_once(&connection_key_once, make_connection_key);
+
+	static const turn_dbdriver_t * _driver = NULL;
+
+	if (_driver == NULL) {
+
 		switch (turn_params.default_users_db.userdb_type){
 #if !defined(TURN_NO_SQLITE)
 		case TURN_USERDB_TYPE_SQLITE:

+ 6 - 1
src/apps/relay/dbdrivers/dbdriver.h

@@ -36,12 +36,17 @@
 
 #include "ns_turn_msg_defs_new.h"
 
+#include <pthread.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 ////////////////////////////////////////////
 
+extern pthread_key_t connection_key;
+extern pthread_once_t connection_key_once;
+
 typedef struct _turn_dbdriver_t {
   int (*get_auth_secrets)(secrets_list_t *sl, u08bits *realm);
   int (*get_user_key)(u08bits *usname, u08bits *realm, hmackey_t key);
@@ -71,7 +76,7 @@ typedef struct _turn_dbdriver_t {
 
 int convert_string_key_to_binary(char* keysource, hmackey_t key, size_t sz);
 persistent_users_db_t * get_persistent_users_db(void);
-turn_dbdriver_t * get_dbdriver(void);
+const turn_dbdriver_t * get_dbdriver(void);
 
 ////////////////////////////////////////////
 

+ 1 - 1
src/apps/relay/mainrelay.c

@@ -121,7 +121,7 @@ LOW_DEFAULT_PORTS_BOUNDARY,HIGH_DEFAULT_PORTS_BOUNDARY,0,0,0,"",
 /////////////// MISC PARAMS ////////////////
 0,0,0,0,0,SHATYPE_SHA1,':',0,0,TURN_CREDENTIALS_NONE,0,0,0,0,0,0,
 ///////////// Users DB //////////////
-{ (TURN_USERDB_TYPE)0, {"\0",NULL}, {0,NULL,NULL, {NULL,0}} }
+{ (TURN_USERDB_TYPE)0, {"\0"}, {0,NULL,NULL, {NULL,0}} }
 
 };
 

+ 17 - 17
src/apps/relay/userdb.c

@@ -302,7 +302,7 @@ void add_to_secrets_list(secrets_list_t *sl, const char* elem)
 static int get_auth_secrets(secrets_list_t *sl, u08bits *realm)
 {
 	int ret = -1;
-  turn_dbdriver_t * dbd = get_dbdriver();
+  const turn_dbdriver_t * dbd = get_dbdriver();
 
 	clean_secrets_list(sl);
 
@@ -419,7 +419,7 @@ int get_user_key(int in_oauth, int *out_oauth, int *max_session_time, u08bits *u
 
 			if(len>0 && value) {
 
-				turn_dbdriver_t * dbd = get_dbdriver();
+				const turn_dbdriver_t * dbd = get_dbdriver();
 
 				if (dbd && dbd->get_oauth_key) {
 
@@ -635,7 +635,7 @@ int get_user_key(int in_oauth, int *out_oauth, int *max_session_time, u08bits *u
 		return 0;
 	}
 
-  turn_dbdriver_t * dbd = get_dbdriver();
+  const turn_dbdriver_t * dbd = get_dbdriver();
   if (dbd && dbd->get_user_key) {
     ret = (*(dbd->get_user_key))(usname, realm, key);
   }
@@ -650,7 +650,7 @@ int get_user_pwd(u08bits *usname, st_password_t pwd)
 {
 	int ret = -1;
 
-  turn_dbdriver_t * dbd = get_dbdriver();
+  const turn_dbdriver_t * dbd = get_dbdriver();
   if (dbd && dbd->get_user_pwd) {
     ret = (*dbd->get_user_pwd)(usname, pwd);
   }
@@ -792,7 +792,7 @@ int add_user_account(char *user, int dynamic)
 
 static int list_users(int is_st, u08bits *realm)
 {
-  turn_dbdriver_t * dbd = get_dbdriver();
+  const turn_dbdriver_t * dbd = get_dbdriver();
   if (dbd && dbd->list_users) {
     (*dbd->list_users)(is_st, realm);
   }
@@ -804,7 +804,7 @@ static int show_secret(u08bits *realm)
 {
 	must_set_admin_realm(realm);
 
-  turn_dbdriver_t * dbd = get_dbdriver();
+  const turn_dbdriver_t * dbd = get_dbdriver();
   if (dbd && dbd->show_secret) {
     (*dbd->show_secret)(realm);
 	}
@@ -816,7 +816,7 @@ static int del_secret(u08bits *secret, u08bits *realm) {
 
 	must_set_admin_realm(realm);
 
-  turn_dbdriver_t * dbd = get_dbdriver();
+  const turn_dbdriver_t * dbd = get_dbdriver();
   if (dbd && dbd->del_secret) {
     (*dbd->del_secret)(secret, realm);
 	}
@@ -833,7 +833,7 @@ static int set_secret(u08bits *secret, u08bits *realm) {
 
 	del_secret(secret, realm);
 
-  turn_dbdriver_t * dbd = get_dbdriver();
+  const turn_dbdriver_t * dbd = get_dbdriver();
   if (dbd && dbd->set_secret) {
     (*dbd->set_secret)(secret, realm);
 	}
@@ -847,7 +847,7 @@ static int add_origin(u08bits *origin0, u08bits *realm)
 
 	get_canonic_origin((const char *)origin0, (char *)origin, sizeof(origin)-1);
 
-  turn_dbdriver_t * dbd = get_dbdriver();
+  const turn_dbdriver_t * dbd = get_dbdriver();
   if (dbd && dbd->add_origin) {
     (*dbd->add_origin)(origin, realm);
 	}
@@ -861,7 +861,7 @@ static int del_origin(u08bits *origin0)
 
 	get_canonic_origin((const char *)origin0, (char *)origin, sizeof(origin)-1);
 
-  turn_dbdriver_t * dbd = get_dbdriver();
+  const turn_dbdriver_t * dbd = get_dbdriver();
   if (dbd && dbd->del_origin) {
     (*dbd->del_origin)(origin);
 	}
@@ -871,7 +871,7 @@ static int del_origin(u08bits *origin0)
 
 static int list_origins(u08bits *realm)
 {
-  turn_dbdriver_t * dbd = get_dbdriver();
+  const turn_dbdriver_t * dbd = get_dbdriver();
   if (dbd && dbd->list_origins) {
     (*dbd->list_origins)(realm);
 	}
@@ -884,7 +884,7 @@ static int set_realm_option_one(u08bits *realm, unsigned long value, const char*
 	if(value == (unsigned long)-1)
 		return 0;
 
-  turn_dbdriver_t * dbd = get_dbdriver();
+  const turn_dbdriver_t * dbd = get_dbdriver();
   if (dbd && dbd->set_realm_option_one) {
     (*dbd->set_realm_option_one)(realm, value, opt);
 	}
@@ -902,7 +902,7 @@ static int set_realm_option(u08bits *realm, perf_options_t *po)
 
 static int list_realm_options(u08bits *realm)
 {
-  turn_dbdriver_t * dbd = get_dbdriver();
+  const turn_dbdriver_t * dbd = get_dbdriver();
   if (dbd && dbd->list_realm_options) {
     (*dbd->list_realm_options)(realm);
 	}
@@ -984,7 +984,7 @@ int adminuser(u08bits *user, u08bits *realm, u08bits *pwd, u08bits *secret, u08b
 		}
 	}
 
-	turn_dbdriver_t * dbd = get_dbdriver();
+	const turn_dbdriver_t * dbd = get_dbdriver();
 
 	if (ct == TA_PRINT_KEY) {
 
@@ -1020,7 +1020,7 @@ int adminuser(u08bits *user, u08bits *realm, u08bits *pwd, u08bits *secret, u08b
 
 void auth_ping(redis_context_handle rch)
 {
-  turn_dbdriver_t * dbd = get_dbdriver();
+  const turn_dbdriver_t * dbd = get_dbdriver();
   if (dbd && dbd->auth_ping) {
     (*dbd->auth_ping)(rch);
 	}
@@ -1193,7 +1193,7 @@ ip_range_list_t* get_ip_list(const char *kind)
 	ip_range_list_t *ret = (ip_range_list_t*) turn_malloc(sizeof(ip_range_list_t));
 	ns_bzero(ret,sizeof(ip_range_list_t));
 
-	turn_dbdriver_t * dbd = get_dbdriver();
+	const turn_dbdriver_t * dbd = get_dbdriver();
 	if (dbd && dbd->get_ip_list) {
 		(*dbd->get_ip_list)(kind, ret);
 	}
@@ -1292,7 +1292,7 @@ void reread_realms(void)
 		ur_string_map_unlock(realms);
 	}
 
-  turn_dbdriver_t * dbd = get_dbdriver();
+  const turn_dbdriver_t * dbd = get_dbdriver();
   if (dbd && dbd->reread_realms) {
     (*dbd->reread_realms)(&realms_list);
 	}

+ 0 - 3
src/apps/relay/userdb.h

@@ -158,10 +158,7 @@ typedef struct _ram_users_db_t {
 } ram_users_db_t;
 
 typedef struct _persistent_users_db_t {
-
 	char userdb[TURN_LONG_STRING_SIZE];
-	void *connection;
-
 } persistent_users_db_t;
 
 typedef struct _default_users_db_t