mysql: Ensure connections are properly released in multi-threaded environments
This commit is contained in:
@@ -101,9 +101,11 @@ struct conn_t {
|
|||||||
/**
|
/**
|
||||||
* Release a mysql connection
|
* Release a mysql connection
|
||||||
*/
|
*/
|
||||||
static void conn_release(conn_t *conn)
|
static void conn_release(private_mysql_database_t *this, conn_t *conn)
|
||||||
{
|
{
|
||||||
|
this->mutex->lock(this->mutex);
|
||||||
conn->in_use = FALSE;
|
conn->in_use = FALSE;
|
||||||
|
this->mutex->unlock(this->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -197,9 +199,10 @@ static conn_t *conn_get(private_mysql_database_t *this)
|
|||||||
}
|
}
|
||||||
if (found == NULL)
|
if (found == NULL)
|
||||||
{
|
{
|
||||||
found = malloc_thing(conn_t);
|
INIT(found,
|
||||||
found->in_use = TRUE;
|
.in_use = TRUE,
|
||||||
found->mysql = mysql_init(NULL);
|
.mysql = mysql_init(NULL),
|
||||||
|
);
|
||||||
if (!mysql_real_connect(found->mysql, this->host, this->username,
|
if (!mysql_real_connect(found->mysql, this->host, this->username,
|
||||||
this->password, this->database, this->port,
|
this->password, this->database, this->port,
|
||||||
NULL, 0))
|
NULL, 0))
|
||||||
@@ -332,6 +335,8 @@ static MYSQL_STMT* run(MYSQL *mysql, char *sql, va_list *args)
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
/** implements enumerator_t */
|
/** implements enumerator_t */
|
||||||
enumerator_t public;
|
enumerator_t public;
|
||||||
|
/** mysql database */
|
||||||
|
private_mysql_database_t *db;
|
||||||
/** associated MySQL statement */
|
/** associated MySQL statement */
|
||||||
MYSQL_STMT *stmt;
|
MYSQL_STMT *stmt;
|
||||||
/** result bindings */
|
/** result bindings */
|
||||||
@@ -373,7 +378,7 @@ static void mysql_enumerator_destroy(mysql_enumerator_t *this)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
mysql_stmt_close(this->stmt);
|
mysql_stmt_close(this->stmt);
|
||||||
conn_release(this->conn);
|
conn_release(this->db, this->conn);
|
||||||
free(this->bind);
|
free(this->bind);
|
||||||
free(this->val.p_void);
|
free(this->val.p_void);
|
||||||
free(this->length);
|
free(this->length);
|
||||||
@@ -496,11 +501,16 @@ METHOD(database_t, query, enumerator_t*,
|
|||||||
{
|
{
|
||||||
int columns, i;
|
int columns, i;
|
||||||
|
|
||||||
enumerator = malloc_thing(mysql_enumerator_t);
|
INIT(enumerator,
|
||||||
enumerator->public.enumerate = (void*)mysql_enumerator_enumerate;
|
.public = {
|
||||||
enumerator->public.destroy = (void*)mysql_enumerator_destroy;
|
.enumerate = (void*)mysql_enumerator_enumerate,
|
||||||
enumerator->stmt = stmt;
|
.destroy = (void*)mysql_enumerator_destroy,
|
||||||
enumerator->conn = conn;
|
|
||||||
|
},
|
||||||
|
.db = this,
|
||||||
|
.stmt = stmt,
|
||||||
|
.conn = conn,
|
||||||
|
);
|
||||||
columns = mysql_stmt_field_count(stmt);
|
columns = mysql_stmt_field_count(stmt);
|
||||||
enumerator->bind = calloc(columns, sizeof(MYSQL_BIND));
|
enumerator->bind = calloc(columns, sizeof(MYSQL_BIND));
|
||||||
enumerator->length = calloc(columns, sizeof(unsigned long));
|
enumerator->length = calloc(columns, sizeof(unsigned long));
|
||||||
@@ -557,7 +567,7 @@ METHOD(database_t, query, enumerator_t*,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
conn_release(conn);
|
conn_release(this, conn);
|
||||||
}
|
}
|
||||||
va_end(args);
|
va_end(args);
|
||||||
return (enumerator_t*)enumerator;
|
return (enumerator_t*)enumerator;
|
||||||
@@ -588,7 +598,7 @@ METHOD(database_t, execute, int,
|
|||||||
mysql_stmt_close(stmt);
|
mysql_stmt_close(stmt);
|
||||||
}
|
}
|
||||||
va_end(args);
|
va_end(args);
|
||||||
conn_release(conn);
|
conn_release(this, conn);
|
||||||
return affected;
|
return affected;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -697,7 +707,6 @@ mysql_database_t *mysql_database_create(char *uri)
|
|||||||
destroy(this);
|
destroy(this);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
conn_release(conn);
|
conn_release(this, conn);
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user