From: Tor Didriksen Date: July 23 2010 12:51pm Subject: bzr commit into mysql-next-mr-bugfixing branch (tor.didriksen:3322) Bug#55434 List-Archive: http://lists.mysql.com/commits/114224 X-Bug: 55434 Message-Id: <20100723125148.3C2383718@atum07.norway.sun.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============8937895090100045823==" --===============8937895090100045823== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///export/home/didrik/repo/next-mr-bf-bug55434/ based on revid:davi.arnaut@stripped 3322 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 === 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. */ --===============8937895090100045823== 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\ # qyxaovw429olp2jm # target_branch: file:///export/home/didrik/repo/next-mr-bf-bug55434/ # testament_sha1: f007b1738a35b662fc29fb6b3edbdc320f95d8ac # timestamp: 2010-07-23 14:51:48 +0200 # base_revision_id: davi.arnaut@stripped\ # nh2n0vmq01c217kj # # Begin bundle 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 jRIP4eoFjdtRj5QWYQv5pMQv8XckU4UJBUHjP3A= --===============8937895090100045823==--