From: Tor Didriksen Date: July 23 2010 1:44pm Subject: bzr push into mysql-next-mr-bugfixing branch (tor.didriksen:3322 to 3323) Bug#55434 List-Archive: http://lists.mysql.com/commits/114229 X-Bug: 55434 Message-Id: <20100723134419.F39CB3719@atum07.norway.sun.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============1182535588592418221==" --===============1182535588592418221== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline 3323 Tor Didriksen 2010-07-23 Bug #55434 multithreaded gunit tests fail on windows On windows we need an open handle to the thread in order to join it. @ unittest/gunit/thread_utils.cc On windows: keep an open handle to a thread in order to join it safely. Use mysql_xxx() wrappers for pthread_xxx() functions. @ unittest/gunit/thread_utils.h Use mysql_mutex_t/mysql_cond_t rather than pthread_mutex_t/pthread_cond_t modified: unittest/gunit/thread_utils.cc unittest/gunit/thread_utils.h 3322 Alexander Nozdrin 2010-07-23 [merge] Auto-merge from mysql-next-mr. added: mysql-test/include/ctype_unicode520.inc modified: include/m_ctype.h mysql-test/r/ctype_ldml.result mysql-test/r/ctype_uca.result mysql-test/r/ctype_ucs.result mysql-test/r/ctype_utf16_uca.result mysql-test/r/ctype_utf32_uca.result mysql-test/std_data/Index.xml mysql-test/suite/engines/funcs/r/db_alter_collate_utf8.result mysql-test/suite/engines/funcs/t/db_alter_collate_utf8.test mysql-test/suite/sys_vars/inc/collation_basic.inc mysql-test/suite/sys_vars/r/collation_connection_basic.result mysql-test/suite/sys_vars/r/collation_database_basic.result mysql-test/suite/sys_vars/r/collation_server_basic.result mysql-test/t/ctype_ldml.test mysql-test/t/ctype_uca.test mysql-test/t/ctype_ucs.test mysql-test/t/ctype_utf16_uca.test mysql-test/t/ctype_utf32_uca.test mysys/charset-def.c mysys/charset.c strings/conf_to_src.c strings/ctype-big5.c strings/ctype-bin.c strings/ctype-cp932.c strings/ctype-czech.c strings/ctype-euc_kr.c strings/ctype-eucjpms.c strings/ctype-extra.c strings/ctype-gb2312.c strings/ctype-gbk.c strings/ctype-latin1.c strings/ctype-mb.c strings/ctype-simple.c strings/ctype-sjis.c strings/ctype-tis620.c strings/ctype-uca.c strings/ctype-ucs2.c strings/ctype-ujis.c strings/ctype-utf8.c strings/ctype-win1250ch.c strings/ctype.c strings/uca-dump.c === modified file 'unittest/gunit/thread_utils.cc' --- a/unittest/gunit/thread_utils.cc 2010-05-21 13:02:27 +0000 +++ b/unittest/gunit/thread_utils.cc 2010-07-23 12:49:56 +0000 @@ -15,14 +15,41 @@ #include #include "thread_utils.h" +#include "mysql/psi/mysql_thread.h" namespace thread { +/* + On windows we need an open handle to the thread in order to join it. + The three instances of Notification are used as follows: + - The main thread starts sub-thread, waits for m_thread_started. + - The main thread picks up the thread id, and does OpenThread to get a handle. + - The main thread tells the sub-thread that it can continue + (notifies m_thread_continue) + - The main thread waits until the sub-thread is actually running + (waits for m_thread_running) before destroying all objects. + + All this is to work around a bug in pthread_create() in mysys/my_winthread, + which closes the thread handle (it has nowhere to store it). + When we later call pthread_join() we try to re-open a handle. + This will fail if the thread has already finished, and then the join will fail. + */ +class Thread_start_arg +{ +public: + Thread_start_arg(Thread *thread) : m_thread(thread) {} + + Notification m_thread_started; + Notification m_thread_continue; + Notification m_thread_running; + Thread *m_thread; +}; + namespace { void *thread_start_routine(void *arg) { - Thread *thread= (Thread*) arg; - Thread::run_wrapper(thread); + Thread_start_arg *start_arg= (Thread_start_arg*) arg; + Thread::run_wrapper(start_arg); return NULL; } @@ -38,56 +65,111 @@ void assert_false(int arg, int line) Thread::~Thread() { +#ifdef __WIN__ + if (m_thread_handle != NULL) + CloseHandle(m_thread_handle); +#endif } int Thread::start() { - return pthread_create(&m_thread_id, NULL, thread_start_routine, this); + Thread_start_arg start_arg(this); + const int retval= + pthread_create(&m_thread_id, NULL, thread_start_routine, &start_arg); + if (retval != 0) + { + ADD_FAILURE() << " could not start thread, errno: " << errno; + return retval; + } + + start_arg.m_thread_started.wait_for_notification(); +#ifdef __WIN__ + m_thread_handle= OpenThread(SYNCHRONIZE, FALSE, m_thread_id); + if (m_thread_handle == NULL) + { + DWORD lasterror= GetLastError(); + ADD_FAILURE() + << " could not open thread id " << m_thread_id + << " GetLastError: " << lasterror + ; + } +#endif + start_arg.m_thread_continue.notify(); + start_arg.m_thread_running.wait_for_notification(); + return retval; } +#ifdef __WIN__ void Thread::join() { - int failed= pthread_join(m_thread_id, NULL); - ASSERT_FALSE(failed); + DWORD ret= WaitForSingleObject(m_thread_handle, INFINITE); + if (ret != WAIT_OBJECT_0) + { + DWORD lasterror= GetLastError(); + ADD_FAILURE() + << " could not join thread id " << m_thread_id + << " handle " << m_thread_handle + << " GetLastError: " << lasterror + ; + } + CloseHandle(m_thread_handle); + m_thread_handle= NULL; +} +#else +void Thread::join() +{ + const int failed= pthread_join(m_thread_id, NULL); + if (failed) + { + ADD_FAILURE() + << " could not join thread id " << m_thread_id + << " failed: " << failed << " errno: " << errno + ; + } } +#endif -void Thread::run_wrapper(Thread *thread) +void Thread::run_wrapper(Thread_start_arg *start_arg) { const my_bool error= my_thread_init(); ASSERT_FALSE(error); + Thread *thread= start_arg->m_thread; + start_arg->m_thread_started.notify(); + start_arg->m_thread_continue.wait_for_notification(); + start_arg->m_thread_running.notify(); thread->run(); my_thread_end(); } -Mutex_lock::Mutex_lock(pthread_mutex_t *mutex) : m_mutex(mutex) +Mutex_lock::Mutex_lock(mysql_mutex_t *mutex) : m_mutex(mutex) { - pthread_mutex_lock(m_mutex); + mysql_mutex_lock(m_mutex); } Mutex_lock::~Mutex_lock() { - const int failed= pthread_mutex_unlock(m_mutex); + const int failed= mysql_mutex_unlock(m_mutex); LOCAL_ASSERT_FALSE(failed); } Notification::Notification() : m_notified(FALSE) { - const int failed1= pthread_cond_init(&m_cond, NULL); + const int failed1= mysql_cond_init(0, &m_cond, NULL); LOCAL_ASSERT_FALSE(failed1); - const int failed2= pthread_mutex_init(&m_mutex, MY_MUTEX_INIT_FAST); + const int failed2= mysql_mutex_init(0, &m_mutex, MY_MUTEX_INIT_FAST); LOCAL_ASSERT_FALSE(failed2); } Notification::~Notification() { - pthread_mutex_destroy(&m_mutex); - pthread_cond_destroy(&m_cond); + mysql_mutex_destroy(&m_mutex); + mysql_cond_destroy(&m_cond); } bool Notification::has_been_notified() @@ -101,7 +183,7 @@ void Notification::wait_for_notification Mutex_lock lock(&m_mutex); while (!m_notified) { - const int failed= pthread_cond_wait(&m_cond, &m_mutex); + const int failed= mysql_cond_wait(&m_cond, &m_mutex); ASSERT_FALSE(failed); } } @@ -110,7 +192,7 @@ void Notification::notify() { Mutex_lock lock(&m_mutex); m_notified= TRUE; - const int failed= pthread_cond_broadcast(&m_cond); + const int failed= mysql_cond_broadcast(&m_cond); ASSERT_FALSE(failed); } === modified file 'unittest/gunit/thread_utils.h' --- a/unittest/gunit/thread_utils.h 2010-03-19 11:46:14 +0000 +++ b/unittest/gunit/thread_utils.h 2010-07-23 12:49:56 +0000 @@ -21,6 +21,8 @@ namespace thread { +class Thread_start_arg; + /* An abstract class for creating/running/joining threads. Thread::start() will create a new pthread, and execute the run() function. @@ -28,7 +30,11 @@ namespace thread { class Thread { public: - Thread() : m_thread_id(0) {} + Thread() : m_thread_id(0) +#ifdef __WIN__ + , m_thread_handle(NULL) +#endif + {} virtual ~Thread(); /* @@ -51,7 +57,7 @@ public: Users should *not* call this function directly, they should rather invoke the start() function. */ - static void run_wrapper(Thread*); + static void run_wrapper(Thread_start_arg*); protected: /* @@ -63,6 +69,10 @@ protected: private: pthread_t m_thread_id; +#ifdef __WIN__ + // We need an open handle to the thread in order to join() it. + HANDLE m_thread_handle; +#endif Thread(const Thread&); /* Not copyable. */ void operator=(const Thread&); /* Not assignable. */ @@ -74,10 +84,10 @@ private: class Mutex_lock { public: - Mutex_lock(pthread_mutex_t *mutex); + Mutex_lock(mysql_mutex_t *mutex); ~Mutex_lock(); private: - pthread_mutex_t *m_mutex; + mysql_mutex_t *m_mutex; Mutex_lock(const Mutex_lock&); /* Not copyable. */ void operator=(const Mutex_lock&); /* Not assignable. */ @@ -96,8 +106,8 @@ public: void notify(); private: bool m_notified; - pthread_cond_t m_cond; - pthread_mutex_t m_mutex; + mysql_cond_t m_cond; + mysql_mutex_t m_mutex; Notification(const Notification&); /* Not copyable. */ void operator=(const Notification&); /* Not assignable. */ --===============1182535588592418221== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/tor.didriksen@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: tor.didriksen@stripped\ # swk11on3t9qtldm7 # target_branch: file:///export/home/didrik/repo/next-mr-bf-bug55434/ # testament_sha1: 4c5fe9457849e608427d897b099e9282d9a6d637 # timestamp: 2010-07-23 15:44:19 +0200 # base_revision_id: alik@stripped # # Begin bundle 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 --===============1182535588592418221==--