#At file:///home/hf/work/tb-mrg/ based on revid:mats.kindahl@stripped
3259 Alexey Botchkov 2010-09-08 [merge]
merging.
modified:
client/mysqltest.cc
libmysqld/lib_sql.cc
sql/derror.cc
sql/mysqld.cc
sql/set_var.cc
sql/set_var.h
sql/sys_vars.h
=== modified file 'client/mysqltest.cc'
--- a/client/mysqltest.cc 2010-08-27 12:17:32 +0000
+++ b/client/mysqltest.cc 2010-09-08 07:09:13 +0000
@@ -248,10 +248,14 @@ struct st_connection
my_bool pending;
#ifdef EMBEDDED_LIBRARY
+ pthread_t tid;
const char *cur_query;
int cur_query_len;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
+ int command, result;
+ pthread_mutex_t query_mutex;
+ pthread_cond_t query_cond;
+ pthread_mutex_t result_mutex;
+ pthread_cond_t result_cond;
int query_done;
#endif /*EMBEDDED_LIBRARY*/
};
@@ -703,67 +707,148 @@ void handle_no_error(struct st_command*)
#ifdef EMBEDDED_LIBRARY
+#define EMB_SEND_QUERY 1
+#define EMB_READ_QUERY_RESULT 2
+#define EMB_END_CONNECTION 3
+
/* attributes of the query thread */
pthread_attr_t cn_thd_attrib;
+
/*
- send_one_query executes query in separate thread, which is
- necessary in embedded library to run 'send' in proper way.
- This implementation doesn't handle errors returned
- by mysql_send_query. It's technically possible, though
- I don't see where it is needed.
+ This procedure represents the connection and actually
+ runs queries when in the EMBEDDED-SERVER mode.
+ The run_query_normal() just sends request for running
+ mysql_send_query and mysql_read_query_result() here.
*/
-pthread_handler_t send_one_query(void *arg)
+
+pthread_handler_t connection_thread(void *arg)
{
struct st_connection *cn= (struct st_connection*)arg;
mysql_thread_init();
- (void) mysql_send_query(&cn->mysql, cn->cur_query, cn->cur_query_len);
+ while (cn->command != EMB_END_CONNECTION)
+ {
+ if (!cn->command)
+ {
+ pthread_mutex_lock(&cn->query_mutex);
+ while (!cn->command)
+ pthread_cond_wait(&cn->query_cond, &cn->query_mutex);
+ pthread_mutex_unlock(&cn->query_mutex);
+ }
+ switch (cn->command)
+ {
+ case EMB_END_CONNECTION:
+ goto end_thread;
+ case EMB_SEND_QUERY:
+ cn->result= mysql_send_query(&cn->mysql, cn->cur_query, cn->cur_query_len);
+ break;
+ case EMB_READ_QUERY_RESULT:
+ cn->result= mysql_read_query_result(&cn->mysql);
+ break;
+ default:
+ DBUG_ASSERT(0);
+ }
+ cn->command= 0;
+ pthread_mutex_lock(&cn->result_mutex);
+ cn->query_done= 1;
+ pthread_cond_signal(&cn->result_cond);
+ pthread_mutex_unlock(&cn->result_mutex);
+ }
- mysql_thread_end();
- pthread_mutex_lock(&cn->mutex);
+end_thread:
cn->query_done= 1;
- pthread_cond_signal(&cn->cond);
- pthread_mutex_unlock(&cn->mutex);
+ mysql_thread_end();
pthread_exit(0);
return 0;
}
-static int do_send_query(struct st_connection *cn, const char *q, int q_len,
- int flags)
+
+static void wait_query_thread_done(struct st_connection *con)
+{
+ DBUG_ASSERT(con->tid);
+ if (!con->query_done)
+ {
+ pthread_mutex_lock(&con->result_mutex);
+ while (!con->query_done)
+ pthread_cond_wait(&con->result_cond, &con->result_mutex);
+ pthread_mutex_unlock(&con->result_mutex);
+ }
+}
+
+
+static void signal_connection_thd(struct st_connection *cn, int command)
{
- pthread_t tid;
+ DBUG_ASSERT(cn->tid);
+ cn->query_done= 0;
+ cn->command= command;
+ pthread_mutex_lock(&cn->query_mutex);
+ pthread_cond_signal(&cn->query_cond);
+ pthread_mutex_unlock(&cn->query_mutex);
+}
- if (flags & QUERY_REAP_FLAG)
- return mysql_send_query(&cn->mysql, q, q_len);
- if (pthread_mutex_init(&cn->mutex, NULL) ||
- pthread_cond_init(&cn->cond, NULL))
- die("Error in the thread library");
+/*
+ Sometimes we try to execute queries when the connection is closed.
+ It's done to make sure it was closed completely.
+ So that if our connection is closed (cn->tid == 0), we just return
+ the mysql_send_query() result which is an error in this case.
+*/
+static int do_send_query(struct st_connection *cn, const char *q, int q_len)
+{
+ if (!cn->tid)
+ return mysql_send_query(&cn->mysql, q, q_len);
cn->cur_query= q;
cn->cur_query_len= q_len;
- cn->query_done= 0;
- if (pthread_create(&tid, &cn_thd_attrib, send_one_query, (void*)cn))
- die("Cannot start new thread for query");
-
+ signal_connection_thd(cn, EMB_SEND_QUERY);
return 0;
}
-static void wait_query_thread_end(struct st_connection *con)
+
+static int do_read_query_result(struct st_connection *cn)
{
- if (!con->query_done)
- {
- pthread_mutex_lock(&con->mutex);
- while (!con->query_done)
- pthread_cond_wait(&con->cond, &con->mutex);
- pthread_mutex_unlock(&con->mutex);
- }
+ DBUG_ASSERT(cn->tid);
+ wait_query_thread_done(cn);
+ signal_connection_thd(cn, EMB_READ_QUERY_RESULT);
+ wait_query_thread_done(cn);
+
+ return cn->result;
+}
+
+
+static void emb_close_connection(struct st_connection *cn)
+{
+ if (!cn->tid)
+ return;
+ wait_query_thread_done(cn);
+ signal_connection_thd(cn, EMB_END_CONNECTION);
+ pthread_join(cn->tid, NULL);
+ cn->tid= 0;
+ pthread_mutex_destroy(&cn->query_mutex);
+ pthread_cond_destroy(&cn->query_cond);
+ pthread_mutex_destroy(&cn->result_mutex);
+ pthread_cond_destroy(&cn->result_cond);
}
+
+static void init_connection_thd(struct st_connection *cn)
+{
+ cn->query_done= 1;
+ cn->command= 0;
+ if (pthread_mutex_init(&cn->query_mutex, NULL) ||
+ pthread_cond_init(&cn->query_cond, NULL) ||
+ pthread_mutex_init(&cn->result_mutex, NULL) ||
+ pthread_cond_init(&cn->result_cond, NULL) ||
+ pthread_create(&cn->tid, &cn_thd_attrib, connection_thread, (void*)cn))
+ die("Error in the thread library");
+}
+
+
#else /*EMBEDDED_LIBRARY*/
-#define do_send_query(cn,q,q_len,flags) mysql_send_query(&cn->mysql, q, q_len)
+#define do_send_query(cn,q,q_len) mysql_send_query(&cn->mysql, q, q_len)
+#define do_read_query_result(cn) mysql_read_query_result(&cn->mysql)
#endif /*EMBEDDED_LIBRARY*/
@@ -1106,6 +1191,9 @@ void close_connections()
DBUG_ENTER("close_connections");
for (--next_con; next_con >= connections; --next_con)
{
+#ifdef EMBEDDED_LIBRARY
+ emb_close_connection(next_con);
+#endif
if (next_con->stmt)
mysql_stmt_close(next_con->stmt);
next_con->stmt= 0;
@@ -4868,7 +4956,7 @@ void do_close_connection(struct st_comma
we need to check if the query's thread was finished and probably wait
(embedded-server specific)
*/
- wait_query_thread_end(con);
+ emb_close_connection(con);
#endif /*EMBEDDED_LIBRARY*/
if (con->stmt)
mysql_stmt_close(con->stmt);
@@ -5218,8 +5306,9 @@ void do_connect(struct st_command *comma
}
#ifdef EMBEDDED_LIBRARY
- con_slot->query_done= 1;
-#endif
+ init_connection_thd(con_slot);
+#endif /*EMBEDDED_LIBRARY*/
+
if (!mysql_init(&con_slot->mysql))
die("Failed on mysql_init()");
@@ -6770,21 +6859,13 @@ void run_query_normal(struct st_connecti
/*
Send the query
*/
- if (do_send_query(cn, query, query_len, flags))
+ if (do_send_query(cn, query, query_len))
{
handle_error(command, mysql_errno(mysql), mysql_error(mysql),
mysql_sqlstate(mysql), ds);
goto end;
}
}
-#ifdef EMBEDDED_LIBRARY
- /*
- Here we handle 'reap' command, so we need to check if the
- query's thread was finished and probably wait
- */
- else if (flags & QUERY_REAP_FLAG)
- wait_query_thread_end(cn);
-#endif /*EMBEDDED_LIBRARY*/
if (!(flags & QUERY_REAP_FLAG))
{
cn->pending= TRUE;
@@ -6797,7 +6878,7 @@ void run_query_normal(struct st_connecti
When on first result set, call mysql_read_query_result to retrieve
answer to the query sent earlier
*/
- if ((counter==0) && mysql_read_query_result(mysql))
+ if ((counter==0) && do_read_query_result(cn))
{
handle_error(command, mysql_errno(mysql), mysql_error(mysql),
mysql_sqlstate(mysql), ds);
@@ -7975,6 +8056,9 @@ int main(int argc, char **argv)
ps_protocol_enabled= 1;
st_connection *con= connections;
+#ifdef EMBEDDED_LIBRARY
+ init_connection_thd(con);
+#endif /*EMBEDDED_LIBRARY*/
if (!( mysql_init(&con->mysql)))
die("Failed in mysql_init()");
if (opt_connect_timeout)
=== modified file 'libmysqld/lib_sql.cc'
--- a/libmysqld/lib_sql.cc 2010-07-19 16:09:51 +0000
+++ b/libmysqld/lib_sql.cc 2010-09-08 07:09:13 +0000
@@ -481,6 +481,10 @@ int init_embedded_server(int argc, char
char *fake_argv[] = { (char *)"", 0 };
const char *fake_groups[] = { "server", "embedded", 0 };
my_bool acl_error;
+
+ if (my_thread_init())
+ return 1;
+
if (argc)
{
argcp= &argc;
=== modified file 'sql/derror.cc'
--- a/sql/derror.cc 2010-07-08 21:42:23 +0000
+++ b/sql/derror.cc 2010-09-08 07:09:13 +0000
@@ -35,6 +35,8 @@ static void init_myfunc_errs(void);
C_MODE_START
static const char **get_server_errmsgs()
{
+ if (!current_thd)
+ return DEFAULT_ERRMSGS;
return CURRENT_THD_ERRMSGS;
}
C_MODE_END
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2010-09-01 13:05:01 +0000
+++ b/sql/mysqld.cc 2010-09-08 07:09:13 +0000
@@ -1486,6 +1486,7 @@ void clean_up(bool print_message)
cleanup_errmsgs();
MYSQL_CALLBACK(thread_scheduler, end, ());
finish_client_errs();
+ (void) my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST); // finish server errs
DBUG_PRINT("quit", ("Error messages freed"));
/* Tell main we are ready */
logger.cleanup_end();
=== modified file 'sql/set_var.cc'
--- a/sql/set_var.cc 2010-08-26 14:54:39 +0000
+++ b/sql/set_var.cc 2010-09-08 07:09:13 +0000
@@ -108,7 +108,7 @@ void sys_var_end()
my_hash_free(&system_variable_hash);
for (sys_var *var=all_sys_vars.first; var; var= var->next)
- var->~sys_var();
+ var->cleanup();
DBUG_VOID_RETURN;
}
=== modified file 'sql/set_var.h'
--- a/sql/set_var.h 2010-07-23 20:59:42 +0000
+++ b/sql/set_var.h 2010-09-08 07:09:13 +0000
@@ -92,10 +92,9 @@ public:
on_check_function on_check_func, on_update_function on_update_func,
uint deprecated_version, const char *substitute, int parse_flag);
/**
- The instance should only be destroyed on shutdown, as it doesn't unlink
- itself from the chain.
+ All the cleanup procedures should be performed here
*/
- virtual ~sys_var() {}
+ virtual void cleanup() {}
/**
downcast for sys_var_pluginvar. Returns this if it's an instance
of sys_var_pluginvar, and 0 otherwise.
=== modified file 'sql/sys_vars.h'
--- a/sql/sys_vars.h 2010-08-12 14:08:21 +0000
+++ b/sql/sys_vars.h 2010-09-08 07:09:13 +0000
@@ -385,7 +385,7 @@ public:
DBUG_ASSERT(scope() == GLOBAL);
DBUG_ASSERT(size == sizeof(char *));
}
- ~Sys_var_charptr()
+ void cleanup()
{
if (flags & ALLOCATED)
my_free(global_var(char*));
Attachment: [text/bzr-bundle] bzr/holyfoot@mysql.com-20100908070913-qlzfbfaabz3jcxqh.bundle
| Thread |
|---|
| • bzr commit into mysql-trunk-bugfixing branch (holyfoot:3259) | Alexey Botchkov | 9 Sep |