diff options
Diffstat (limited to 'client')
-rw-r--r-- | client/mysqldump.c | 1 | ||||
-rw-r--r-- | client/mysqltest.cc | 192 |
2 files changed, 134 insertions, 59 deletions
diff --git a/client/mysqldump.c b/client/mysqldump.c index 68cfde864b5..ac704f152de 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -50,7 +50,6 @@ #include "mysql.h" #include "mysql_version.h" #include "mysqld_error.h" -#include "../sql/ha_ndbcluster_tables.h" /* Exit codes */ diff --git a/client/mysqltest.cc b/client/mysqltest.cc index b7861096aec..5f28c000ac3 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -250,13 +250,15 @@ 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; - pthread_t tid; + 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; - my_bool has_thread; #endif /*EMBEDDED_LIBRARY*/ }; @@ -450,7 +452,7 @@ struct st_command char *query, *query_buf,*first_argument,*last_argument,*end; DYNAMIC_STRING content; int first_word_len, query_len; - my_bool abort_on_error; + my_bool abort_on_error, used_replace; struct st_expected_errors expected_errors; char require_file[FN_REFLEN]; enum enum_commands type; @@ -710,71 +712,145 @@ 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) { - if (flags & QUERY_REAP_FLAG) - return mysql_send_query(&cn->mysql, q, q_len); + 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); + } +} - if (pthread_mutex_init(&cn->mutex, NULL) || - pthread_cond_init(&cn->cond, NULL)) - die("Error in the thread library"); - cn->cur_query= q; - cn->cur_query_len= q_len; +static void signal_connection_thd(struct st_connection *cn, int command) +{ + DBUG_ASSERT(cn->tid); cn->query_done= 0; - if (pthread_create(&cn->tid, &cn_thd_attrib, send_one_query, (void*)cn)) - die("Cannot start new thread for query"); + cn->command= command; + pthread_mutex_lock(&cn->query_mutex); + pthread_cond_signal(&cn->query_cond); + pthread_mutex_unlock(&cn->query_mutex); +} + - cn->has_thread= TRUE; +/* + 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; + 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); - } - if (con->has_thread) - { - pthread_join(con->tid, NULL); - con->has_thread= FALSE; - } + 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*/ @@ -1117,6 +1193,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; @@ -3358,7 +3437,7 @@ static int get_list_files(DYNAMIC_STRING *ds, const DYNAMIC_STRING *ds_dirname, if (ds_wild && ds_wild->length && wild_compare(file->name, ds_wild->str, 0)) continue; - dynstr_append(ds, file->name); + replace_dynstr_append(ds, file->name); dynstr_append(ds, "\n"); } set_wild_chars(0); @@ -3388,6 +3467,7 @@ static void do_list_files(struct st_command *command) {"file", ARG_STRING, FALSE, &ds_wild, "Filename (incl. wildcard)"} }; DBUG_ENTER("do_list_files"); + command->used_replace= 1; check_command_args(command, command->first_argument, list_files_args, @@ -3429,6 +3509,7 @@ static void do_list_files_write_file_command(struct st_command *command, {"file", ARG_STRING, FALSE, &ds_wild, "Filename (incl. wildcard)"} }; DBUG_ENTER("do_list_files_write_file"); + command->used_replace= 1; check_command_args(command, command->first_argument, list_files_args, @@ -4919,7 +5000,7 @@ void do_close_connection(struct st_command *command) 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); @@ -5286,9 +5367,9 @@ void do_connect(struct st_command *command) } #ifdef EMBEDDED_LIBRARY - con_slot->query_done= 1; - con_slot->has_thread= FALSE; -#endif + init_connection_thd(con_slot); +#endif /*EMBEDDED_LIBRARY*/ + if (!mysql_init(&con_slot->mysql)) die("Failed on mysql_init()"); @@ -6845,21 +6926,13 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, /* 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; @@ -6872,7 +6945,7 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, 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); @@ -8049,6 +8122,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) @@ -8470,7 +8546,7 @@ int main(int argc, char **argv) memset(&saved_expected_errors, 0, sizeof(saved_expected_errors)); } - if (command_executed != last_command_executed) + if (command_executed != last_command_executed || command->used_replace) { /* As soon as any command has been executed, |