Move thread from test/ to util/thread/.

BUG=
R=scottmg@chromium.org

Review URL: https://codereview.chromium.org/1134943003
This commit is contained in:
Erik Wright 2015-05-13 14:05:57 -04:00
parent 658cd3e1a7
commit f357afc43e
10 changed files with 125 additions and 37 deletions

View File

@ -51,10 +51,6 @@
'scoped_temp_dir.h', 'scoped_temp_dir.h',
'scoped_temp_dir_posix.cc', 'scoped_temp_dir_posix.cc',
'scoped_temp_dir_win.cc', 'scoped_temp_dir_win.cc',
'thread.cc',
'thread.h',
'thread_posix.cc',
'thread_win.cc',
], ],
'conditions': [ 'conditions': [
['OS=="mac"', { ['OS=="mac"', {

View File

@ -20,7 +20,7 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "test/errors.h" #include "test/errors.h"
#include "test/scoped_temp_dir.h" #include "test/scoped_temp_dir.h"
#include "test/thread.h" #include "util/thread/thread.h"
namespace crashpad { namespace crashpad {
namespace test { namespace test {

View File

@ -12,19 +12,17 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "test/thread.h" #include "util/thread/thread.h"
#include "gtest/gtest.h" #include "base/logging.h"
namespace crashpad { namespace crashpad {
namespace test {
Thread::Thread() : platform_thread_(0) { Thread::Thread() : platform_thread_(0) {
} }
Thread::~Thread() { Thread::~Thread() {
EXPECT_FALSE(platform_thread_); DCHECK(!platform_thread_);
} }
} // namespace test
} // namespace crashpad } // namespace crashpad

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef CRASHPAD_TEST_THREAD_H_ #ifndef CRASHPAD_UTIL_THREAD_THREAD_H_
#define CRASHPAD_TEST_THREAD_H_ #define CRASHPAD_UTIL_THREAD_THREAD_H_
#include "base/basictypes.h" #include "base/basictypes.h"
#include "build/build_config.h" #include "build/build_config.h"
@ -25,9 +25,8 @@
#endif // OS_POSIX #endif // OS_POSIX
namespace crashpad { namespace crashpad {
namespace test {
//! \brief Basic thread abstraction for testing. Users should derive from this //! \brief Basic thread abstraction. Users should derive from this
//! class and implement ThreadMain(). //! class and implement ThreadMain().
class Thread { class Thread {
public: public:
@ -43,8 +42,7 @@ class Thread {
void Join(); void Join();
private: private:
//! \brief The entry point to be overridden to implement the test-specific //! \brief The thread entry point to be implemented by the subclass.
//! functionality.
virtual void ThreadMain() = 0; virtual void ThreadMain() = 0;
static static
@ -64,7 +62,6 @@ class Thread {
DISALLOW_COPY_AND_ASSIGN(Thread); DISALLOW_COPY_AND_ASSIGN(Thread);
}; };
} // namespace test
} // namespace crashpad } // namespace crashpad
#endif // CRASHPAD_TEST_THREAD_H_ #endif // CRASHPAD_UTIL_THREAD_THREAD_H_

View File

@ -19,7 +19,7 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "test/thread.h" #include "util/thread/thread.h"
namespace crashpad { namespace crashpad {
namespace test { namespace test {

View File

@ -12,24 +12,22 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "test/thread.h" #include "util/thread/thread.h"
#include "gtest/gtest.h" #include "base/logging.h"
#include "test/errors.h"
namespace crashpad { namespace crashpad {
namespace test {
void Thread::Start() { void Thread::Start() {
ASSERT_FALSE(platform_thread_); DCHECK(!platform_thread_);
int rv = pthread_create(&platform_thread_, nullptr, ThreadEntryThunk, this); int rv = pthread_create(&platform_thread_, nullptr, ThreadEntryThunk, this);
ASSERT_EQ(0, rv) << ErrnoMessage(rv, "pthread_create"); PCHECK(0 == rv);
} }
void Thread::Join() { void Thread::Join() {
ASSERT_TRUE(platform_thread_); DCHECK(platform_thread_);
int rv = pthread_join(platform_thread_, nullptr); int rv = pthread_join(platform_thread_, nullptr);
EXPECT_EQ(0, rv) << ErrnoMessage(rv, "pthread_join"); PCHECK(0 == rv);
platform_thread_ = 0; platform_thread_ = 0;
} }
@ -40,5 +38,4 @@ void* Thread::ThreadEntryThunk(void* argument) {
return nullptr; return nullptr;
} }
} // namespace test
} // namespace crashpad } // namespace crashpad

View File

@ -0,0 +1,98 @@
// Copyright 2015 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "util/thread/thread.h"
#include "base/basictypes.h"
#include "gtest/gtest.h"
#include "util/synchronization/semaphore.h"
namespace crashpad {
namespace test {
namespace {
class NoopThread : public Thread {
public:
NoopThread() {}
~NoopThread() override {}
private:
void ThreadMain() override {}
DISALLOW_COPY_AND_ASSIGN(NoopThread);
};
class WaitThread : public Thread {
public:
explicit WaitThread(Semaphore* semaphore) : semaphore_(semaphore) {}
~WaitThread() override {}
private:
void ThreadMain() override { semaphore_->Wait(); }
Semaphore* semaphore_;
DISALLOW_COPY_AND_ASSIGN(WaitThread);
};
class JoinAndSignalThread : public Thread {
public:
JoinAndSignalThread(Thread* thread, Semaphore* semaphore)
: thread_(thread), semaphore_(semaphore) {}
~JoinAndSignalThread() override {}
private:
void ThreadMain() override {
thread_->Join();
semaphore_->Signal();
}
Thread* thread_;
Semaphore* semaphore_;
DISALLOW_COPY_AND_ASSIGN(JoinAndSignalThread);
};
TEST(ThreadTest, NoStart) {
NoopThread thread;
}
TEST(ThreadTest, Start) {
NoopThread thread;
thread.Start();
thread.Join();
}
TEST(ThreadTest, JoinBlocks) {
Semaphore unblock_wait_thread_semaphore(0);
Semaphore join_completed_semaphore(0);
WaitThread wait_thread(&unblock_wait_thread_semaphore);
wait_thread.Start();
JoinAndSignalThread join_and_signal_thread(&wait_thread,
&join_completed_semaphore);
join_and_signal_thread.Start();
// join_completed_semaphore will be signaled when wait_thread.Join() returns
// (in JoinAndSignalThread::ThreadMain). Since wait_thread is blocking on
// unblock_wait_thread_semaphore, we don't expect the Join to return yet. We
// wait up to 100ms to give a broken implementation of Thread::Join a chance
// to return.
ASSERT_FALSE(join_completed_semaphore.TimedWait(.1));
unblock_wait_thread_semaphore.Signal();
join_completed_semaphore.Wait();
join_and_signal_thread.Join();
}
} // namespace
} // namespace test
} // namespace crashpad

View File

@ -12,25 +12,23 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "test/thread.h" #include "util/thread/thread.h"
#include "gtest/gtest.h" #include "base/logging.h"
#include "test/errors.h"
namespace crashpad { namespace crashpad {
namespace test {
void Thread::Start() { void Thread::Start() {
ASSERT_FALSE(platform_thread_); DCHECK(!platform_thread_);
platform_thread_ = platform_thread_ =
CreateThread(nullptr, 0, ThreadEntryThunk, this, 0, nullptr); CreateThread(nullptr, 0, ThreadEntryThunk, this, 0, nullptr);
ASSERT_TRUE(platform_thread_) << ErrorMessage("CreateThread"); PCHECK(platform_thread_);
} }
void Thread::Join() { void Thread::Join() {
ASSERT_TRUE(platform_thread_); DCHECK(platform_thread_);
DWORD result = WaitForSingleObject(platform_thread_, INFINITE); DWORD result = WaitForSingleObject(platform_thread_, INFINITE);
EXPECT_EQ(WAIT_OBJECT_0, result) << ErrorMessage("WaitForSingleObject"); PCHECK(WAIT_OBJECT_0 == result);
platform_thread_ = 0; platform_thread_ = 0;
} }
@ -41,5 +39,4 @@ DWORD WINAPI Thread::ThreadEntryThunk(void* argument) {
return 0; return 0;
} }
} // namespace test
} // namespace crashpad } // namespace crashpad

View File

@ -139,8 +139,12 @@
'synchronization/semaphore_posix.cc', 'synchronization/semaphore_posix.cc',
'synchronization/semaphore_win.cc', 'synchronization/semaphore_win.cc',
'synchronization/semaphore.h', 'synchronization/semaphore.h',
'thread/thread.cc',
'thread/thread.h',
'thread/thread_log_messages.cc', 'thread/thread_log_messages.cc',
'thread/thread_log_messages.h', 'thread/thread_log_messages.h',
'thread/thread_posix.cc',
'thread/thread_win.cc',
'win/address_types.h', 'win/address_types.h',
'win/checked_win_address_range.h', 'win/checked_win_address_range.h',
'win/process_info.cc', 'win/process_info.cc',

View File

@ -77,6 +77,7 @@
'string/split_string_test.cc', 'string/split_string_test.cc',
'synchronization/semaphore_test.cc', 'synchronization/semaphore_test.cc',
'thread/thread_log_messages_test.cc', 'thread/thread_log_messages_test.cc',
'thread/thread_test.cc',
'win/process_info_test.cc', 'win/process_info_test.cc',
'win/time_test.cc', 'win/time_test.cc',
], ],