This source file includes following definitions.
- was_started_
- RunAsync
- Run
- OnSignalReceived
- WasStarted
- blocking_task_
- StartBlockingTaskAsync
- StartBlockingTaskAndWaitForItToStart
- CancelBlocking
- VerifyTaskNotStarted
- OnSignalReceived
- TEST
- TEST_F
- TEST_F
#include "sync/internal_api/public/base/cancelation_signal.h"
#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "sync/internal_api/public/base/cancelation_observer.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace syncer {
class BlockingTask : public CancelationObserver {
public:
BlockingTask(CancelationSignal* cancel_signal);
virtual ~BlockingTask();
void RunAsync(base::WaitableEvent* task_start_signal,
base::WaitableEvent* task_done_signal);
void Run(base::WaitableEvent* task_start_signal,
base::WaitableEvent* task_done_signal);
virtual void OnSignalReceived() OVERRIDE;
bool WasStarted();
private:
base::WaitableEvent event_;
base::Thread exec_thread_;
CancelationSignal* cancel_signal_;
bool was_started_;
};
BlockingTask::BlockingTask(CancelationSignal* cancel_signal)
: event_(true, false),
exec_thread_("BlockingTaskBackgroundThread"),
cancel_signal_(cancel_signal),
was_started_(false) { }
BlockingTask::~BlockingTask() {
if (was_started_) {
cancel_signal_->UnregisterHandler(this);
}
}
void BlockingTask::RunAsync(base::WaitableEvent* task_start_signal,
base::WaitableEvent* task_done_signal) {
exec_thread_.Start();
exec_thread_.message_loop()->PostTask(
FROM_HERE,
base::Bind(&BlockingTask::Run,
base::Unretained(this),
base::Unretained(task_start_signal),
base::Unretained(task_done_signal)));
}
void BlockingTask::Run(
base::WaitableEvent* task_start_signal,
base::WaitableEvent* task_done_signal) {
if (cancel_signal_->TryRegisterHandler(this)) {
DCHECK(!event_.IsSignaled());
was_started_ = true;
task_start_signal->Signal();
event_.Wait();
}
task_done_signal->Signal();
}
void BlockingTask::OnSignalReceived() {
event_.Signal();
}
bool BlockingTask::WasStarted() {
return was_started_;
}
class CancelationSignalTest : public ::testing::Test {
public:
CancelationSignalTest();
virtual ~CancelationSignalTest();
void StartBlockingTaskAsync();
void StartBlockingTaskAndWaitForItToStart();
void CancelBlocking();
bool VerifyTaskNotStarted();
private:
base::MessageLoop main_loop_;
CancelationSignal signal_;
base::WaitableEvent task_start_event_;
base::WaitableEvent task_done_event_;
BlockingTask blocking_task_;
};
CancelationSignalTest::CancelationSignalTest()
: task_start_event_(false, false),
task_done_event_(false, false),
blocking_task_(&signal_) {}
CancelationSignalTest::~CancelationSignalTest() {}
void CancelationSignalTest::StartBlockingTaskAsync() {
blocking_task_.RunAsync(&task_start_event_, &task_done_event_);
}
void CancelationSignalTest::StartBlockingTaskAndWaitForItToStart() {
blocking_task_.RunAsync(&task_start_event_, &task_done_event_);
task_start_event_.Wait();
}
void CancelationSignalTest::CancelBlocking() {
signal_.Signal();
}
bool CancelationSignalTest::VerifyTaskNotStarted() {
task_done_event_.Wait();
return !blocking_task_.WasStarted();
}
class FakeCancelationObserver : public CancelationObserver {
virtual void OnSignalReceived() OVERRIDE { }
};
TEST(CancelationSignalTest_SingleThread, CheckFlags) {
FakeCancelationObserver observer;
CancelationSignal signal;
EXPECT_FALSE(signal.IsSignalled());
signal.Signal();
EXPECT_TRUE(signal.IsSignalled());
EXPECT_FALSE(signal.TryRegisterHandler(&observer));
}
TEST_F(CancelationSignalTest, CancelEarly) {
CancelBlocking();
StartBlockingTaskAsync();
EXPECT_TRUE(VerifyTaskNotStarted());
}
TEST_F(CancelationSignalTest, Cancel) {
StartBlockingTaskAndWaitForItToStart();
CancelBlocking();
EXPECT_FALSE(VerifyTaskNotStarted());
}
}