Skip to content

Commit

Permalink
make async querying work.
Browse files Browse the repository at this point in the history
From mysql 5.1 documentation:

http://dev.mysql.com/doc/refman/5.1/en/threaded-clients.html

* Two threads can't send a query to the MySQL server at the same time on the same connection. In particular, you have to ensure that between calls to mysql_query() and mysql_store_result() no other thread is using the same connection.
* Many threads can access different result sets that are retrieved with mysql_store_result().

* If you use mysql_use_result(), you must ensure that no other thread is using the same connection until the result set is closed. However, it really is best for threaded clients that share the same connection to use mysql_store_result()

So, create a pthread mutex around  calls to mysql_real_query. Only support mysql_store_result for async mode.
  • Loading branch information
ssinghi authored and Sannis committed Aug 17, 2010
1 parent 0d1e9a5 commit 02c35e0
Showing 1 changed file with 21 additions and 36 deletions.
57 changes: 21 additions & 36 deletions src/mysql_bindings_connection.cc
Expand Up @@ -136,10 +136,12 @@ MysqlConn::MysqlConnInfo MysqlConn::GetInfo() {
MysqlConn::MysqlConn(): EventEmitter() { MysqlConn::MysqlConn(): EventEmitter() {
_conn = NULL; _conn = NULL;
multi_query = false; multi_query = false;
pthread_mutex_init(&query_lock, NULL);
} }


MysqlConn::~MysqlConn() { MysqlConn::~MysqlConn() {
this->Close(); this->Close();
pthread_mutex_destroy(&query_lock);
} }


Handle<Value> MysqlConn::New(const Arguments& args) { Handle<Value> MysqlConn::New(const Arguments& args) {
Expand Down Expand Up @@ -826,6 +828,7 @@ int MysqlConn::EIO_After_Query(eio_req *req) {


int argc = 0; int argc = 0;
Local<Value> argv[2]; Local<Value> argv[2];
HandleScope scope;


if (req->result) { if (req->result) {
argv[0] = Exception::Error(String::New("Error on query execution")); argv[0] = Exception::Error(String::New("Error on query execution"));
Expand All @@ -837,7 +840,7 @@ int MysqlConn::EIO_After_Query(eio_req *req) {
Persistent<Object> js_result(MysqlResult::constructor_template-> Persistent<Object> js_result(MysqlResult::constructor_template->
GetFunction()->NewInstance(2, argv)); GetFunction()->NewInstance(2, argv));


argv[0] = Local<Value>::New(js_result); argv[0] = Local<Value>::New(scope.Close(js_result));
argc = 1; argc = 1;
} else { } else {
/* no result set - not a SELECT, SHOW, DESCRIBE or EXPLAIN */ /* no result set - not a SELECT, SHOW, DESCRIBE or EXPLAIN */
Expand Down Expand Up @@ -873,44 +876,32 @@ int MysqlConn::EIO_Query(eio_req *req) {


MYSQLSYNC_DISABLE_MQ; MYSQLSYNC_DISABLE_MQ;


pthread_mutex_lock(&conn->query_lock);
int r = mysql_real_query( int r = mysql_real_query(
conn->_conn, conn->_conn,
query_req->query, query_req->query,
query_req->query_length); query_req->query_length);

if (r) { if (r) {
req->result = 1; req->result = 1;
return 0;
} }

else {
req->int1 = 1; req->int1 = 1;
query_req->field_count = mysql_field_count(conn->_conn);
if (!query_req->field_count) {
/* no result set - not a SELECT, SHOW, DESCRIBE or EXPLAIN */
req->int1 = 0;
req->result = 0; req->result = 0;
return 0; query_req->field_count = mysql_field_count(conn->_conn);
} if (!query_req->field_count) { /* no result set - not a SELECT, SHOW, DESCRIBE or EXPLAIN */

req->int1 = 0;
MYSQL_RES *my_result; }

else {
switch (query_req->result_mode) { MYSQL_RES *my_result = mysql_store_result(conn->_conn);
case MYSQLSYNC_STORE_RESULT: if (my_result) {
my_result = mysql_store_result(conn->_conn); query_req->my_result = my_result;
break; }
case MYSQLSYNC_USE_RESULT: else {
my_result = mysql_use_result(conn->_conn); req->result = 1;
break; }
} }

if (!my_result) {
req->result = 1;
return 0;
} }

pthread_mutex_unlock(&conn->query_lock);
query_req->my_result = my_result;
req->result = 0;

return 0; return 0;
} }


Expand All @@ -934,12 +925,6 @@ Handle<Value> MysqlConn::QueryAsync(const Arguments& args) {
return THREXC("Could not allocate enough memory"); return THREXC("Could not allocate enough memory");
} }


query_req->result_mode = MYSQLSYNC_STORE_RESULT;

if (args.Length() == 2) {
query_req->result_mode = MYSQLSYNC_USE_RESULT;
}

query_req->query_length = query.length(); query_req->query_length = query.length();
query_req->query = query_req->query =
reinterpret_cast<char *>(calloc(query_req->query_length + 1, reinterpret_cast<char *>(calloc(query_req->query_length + 1,
Expand Down

0 comments on commit 02c35e0

Please sign in to comment.