Unittest for thread_wrapper.
Added an explanation of the state variables of posix, wrote a simple test. This might help in fixing the TSAN issue with thread. BUG=webrtc:300 TEST= Review URL: https://webrtc-codereview.appspot.com/583008 git-svn-id: http://webrtc.googlecode.com/svn/trunk@2270 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@@ -193,6 +193,7 @@
|
||||
'data_log_helpers_unittest.cc',
|
||||
'data_log_c_helpers_unittest.c',
|
||||
'data_log_c_helpers_unittest.h',
|
||||
'thread_unittest.cc',
|
||||
'trace_unittest.cc',
|
||||
],
|
||||
'conditions': [
|
||||
|
||||
@@ -8,6 +8,40 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
// The state of a thread is controlled by the two member variables
|
||||
// _alive and _dead.
|
||||
// _alive represents the state the thread has been ordered to achieve.
|
||||
// It is set to true by the thread at startup, and is set to false by
|
||||
// other threads, using SetNotAlive() and Stop().
|
||||
// _dead represents the state the thread has achieved.
|
||||
// It is written by the thread encapsulated by this class only
|
||||
// (except at init). It is read only by the Stop() method.
|
||||
// The Run() method fires _event when it's started; this ensures that the
|
||||
// Start() method does not continue until after _dead is false.
|
||||
// This protects against premature Stop() calls from the creator thread, but
|
||||
// not from other threads.
|
||||
|
||||
// Their transitions and states:
|
||||
// _alive _dead Set by
|
||||
// false true Constructor
|
||||
// true false Run() method entry
|
||||
// false any Run() method runFunction failure
|
||||
// any false Run() method exit (happens only with _alive false)
|
||||
// false any SetNotAlive
|
||||
// false any Stop Stop waits for _dead to become true.
|
||||
//
|
||||
// Summarized a different way:
|
||||
// Variable Writer Reader
|
||||
// _alive Constructor(false) Run.loop
|
||||
// Run.start(true)
|
||||
// Run.fail(false)
|
||||
// SetNotAlive(false)
|
||||
// Stop(false)
|
||||
//
|
||||
// _dead Constructor(true) Stop.loop
|
||||
// Run.start(false)
|
||||
// Run.exit(true)
|
||||
|
||||
#include "thread_posix.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
93
src/system_wrappers/source/thread_unittest.cc
Normal file
93
src/system_wrappers/source/thread_unittest.cc
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "system_wrappers/interface/thread_wrapper.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "system_wrappers/interface/trace.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
const int kLogTrace = 1;
|
||||
|
||||
class TestTraceCallback : public TraceCallback {
|
||||
public:
|
||||
virtual void Print(const TraceLevel level,
|
||||
const char* traceString,
|
||||
const int length) {
|
||||
if (traceString) {
|
||||
char* cmd_print = new char[length+1];
|
||||
memcpy(cmd_print, traceString, length);
|
||||
cmd_print[length] = '\0';
|
||||
printf("%s\n", cmd_print);
|
||||
fflush(stdout);
|
||||
delete[] cmd_print;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class ThreadTest : public ::testing::Test {
|
||||
public:
|
||||
ThreadTest() {
|
||||
StartTrace();
|
||||
}
|
||||
~ThreadTest() {
|
||||
StopTrace();
|
||||
}
|
||||
|
||||
private:
|
||||
void StartTrace() {
|
||||
if (kLogTrace) {
|
||||
Trace::CreateTrace();
|
||||
Trace::SetLevelFilter(webrtc::kTraceAll);
|
||||
Trace::SetTraceCallback(&trace_);
|
||||
}
|
||||
}
|
||||
|
||||
void StopTrace() {
|
||||
if (kLogTrace) {
|
||||
Trace::ReturnTrace();
|
||||
}
|
||||
}
|
||||
|
||||
TestTraceCallback trace_;
|
||||
};
|
||||
|
||||
// Function that does nothing, and reports success.
|
||||
bool NullRunFunction(void* /* obj */) {
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST_F(ThreadTest, StartStop) {
|
||||
ThreadWrapper* thread = ThreadWrapper::CreateThread(&NullRunFunction);
|
||||
unsigned int id = 42;
|
||||
ASSERT_TRUE(thread->Start(id));
|
||||
EXPECT_TRUE(thread->Stop());
|
||||
}
|
||||
|
||||
// Function that sets a boolean.
|
||||
bool SetFlagRunFunction(void* obj) {
|
||||
bool* obj_as_bool = static_cast<bool*> (obj);
|
||||
*obj_as_bool = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST_F(ThreadTest, RunFunctionIsCalled) {
|
||||
bool flag = false;
|
||||
ThreadWrapper* thread = ThreadWrapper::CreateThread(&SetFlagRunFunction,
|
||||
&flag);
|
||||
unsigned int id = 42;
|
||||
ASSERT_TRUE(thread->Start(id));
|
||||
// At this point, the flag may be either true or false.
|
||||
EXPECT_TRUE(thread->Stop());
|
||||
// We expect the thread to have run at least once.
|
||||
EXPECT_TRUE(flag);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
Reference in New Issue
Block a user