|
36 | 36 | #include <stdio.h> |
37 | 37 | #include <stdlib.h> |
38 | 38 | #include <sys/types.h> |
| 39 | +#include <condition_variable> |
39 | 40 | #include <memory> |
| 41 | +#include <mutex> |
| 42 | +#include <thread> |
40 | 43 |
|
41 | 44 | #include "my_byteorder.h" |
42 | 45 | #include "my_compiler.h" |
@@ -23309,6 +23312,76 @@ static void test_wl13128() { |
23309 | 23312 | mysql_close(lmysql); |
23310 | 23313 | } |
23311 | 23314 |
|
| 23315 | +static void test_bug25584097() { |
| 23316 | + DBUG_TRACE; |
| 23317 | + myheader("test_bug25584097"); |
| 23318 | + int rc; |
| 23319 | + |
| 23320 | + class test_bug25584097_thd { |
| 23321 | + unsigned long thread_id{0}; |
| 23322 | + std::condition_variable cnd; |
| 23323 | + std::mutex mtx; |
| 23324 | + |
| 23325 | + public: |
| 23326 | + void run() { |
| 23327 | + int rc; |
| 23328 | + MYSQL *lmysql; |
| 23329 | + MYSQL_STMT *stmt; |
| 23330 | + const char *sqlstmt = "select sleep(300)"; |
| 23331 | + unsigned long ct = (unsigned long)CURSOR_TYPE_READ_ONLY; |
| 23332 | + |
| 23333 | + printf("child thread start\n"); |
| 23334 | + lmysql = mysql_client_init(nullptr); |
| 23335 | + DIE_UNLESS(lmysql); |
| 23336 | + |
| 23337 | + if (!mysql_real_connect(lmysql, opt_host, opt_user, opt_password, |
| 23338 | + current_db, opt_port, opt_unix_socket, 0)) { |
| 23339 | + fprintf(stderr, "Failed to connect to the database\n"); |
| 23340 | + DIE_UNLESS(0); |
| 23341 | + } |
| 23342 | + |
| 23343 | + { |
| 23344 | + std::unique_lock lk(mtx); |
| 23345 | + thread_id = mysql_thread_id(lmysql); |
| 23346 | + } |
| 23347 | + stmt = mysql_stmt_init(lmysql); |
| 23348 | + DIE_UNLESS(stmt != nullptr); |
| 23349 | + rc = mysql_stmt_prepare(stmt, sqlstmt, (unsigned long)strlen(sqlstmt)); |
| 23350 | + DIE_UNLESS(rc == 0); |
| 23351 | + rc = mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void *)&ct); |
| 23352 | + DIE_UNLESS(rc == 0); |
| 23353 | + printf("child thread ready to exec\n"); |
| 23354 | + cnd.notify_one(); |
| 23355 | + rc = mysql_stmt_execute(stmt); |
| 23356 | + DIE_UNLESS(rc != 0); |
| 23357 | + printf("child thread cleaning up\n"); |
| 23358 | + rc = mysql_stmt_close(stmt); |
| 23359 | + DIE_UNLESS(rc == 0); |
| 23360 | + mysql_close(lmysql); |
| 23361 | + printf("child thread ending\n"); |
| 23362 | + } |
| 23363 | + |
| 23364 | + unsigned long wait_to_kill() { |
| 23365 | + std::unique_lock lk(mtx); |
| 23366 | + cnd.wait(lk, [this] { return thread_id != 0; }); |
| 23367 | + return thread_id; |
| 23368 | + } |
| 23369 | + } foo; |
| 23370 | + |
| 23371 | + std::thread thd(&test_bug25584097_thd::run, &foo); |
| 23372 | + printf("Waiting for the child thread\n"); |
| 23373 | + unsigned long thd_to_kill = foo.wait_to_kill(); |
| 23374 | + sleep(2); |
| 23375 | + |
| 23376 | + printf("Killing the child thread\n"); |
| 23377 | + char cmd[50]; |
| 23378 | + sprintf(cmd, "KILL %lu", thd_to_kill); |
| 23379 | + rc = mysql_query(mysql, cmd); |
| 23380 | + myquery(rc); |
| 23381 | + printf("Wating for the child thread to finish\n"); |
| 23382 | + thd.join(); |
| 23383 | +} |
| 23384 | + |
23312 | 23385 | static struct my_tests_st my_tests[] = { |
23313 | 23386 | {"test_bug5194", test_bug5194}, |
23314 | 23387 | {"disable_query_logs", disable_query_logs}, |
@@ -23623,6 +23696,7 @@ static struct my_tests_st my_tests[] = { |
23623 | 23696 | {"test_bug34007830", test_bug34007830}, |
23624 | 23697 | {"test_bug33535746", test_bug33535746}, |
23625 | 23698 | {"test_wl13128", test_wl13128}, |
| 23699 | + {"test_bug25584097", test_bug25584097}, |
23626 | 23700 | {nullptr, nullptr}}; |
23627 | 23701 |
|
23628 | 23702 | static struct my_tests_st *get_my_tests() { return my_tests; } |
0 commit comments