diff options
author | blundell <blundell@chromium.org> | 2015-01-19 09:18:33 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-01-19 17:19:27 +0000 |
commit | 70fb54767b472a5edfb859e489beeeec7abdb0e4 (patch) | |
tree | 28e534ec774391a9f6571a1770e12a0d63ebf833 /mojo/public/cpp/utility | |
parent | ba5f0233fa38f949e24f6274ba891fa652eab640 (diff) | |
download | chromium_src-70fb54767b472a5edfb859e489beeeec7abdb0e4.zip chromium_src-70fb54767b472a5edfb859e489beeeec7abdb0e4.tar.gz chromium_src-70fb54767b472a5edfb859e489beeeec7abdb0e4.tar.bz2 |
Move //mojo/{public, edk} underneath //third_party
This CL move //mojo/public and //mojo/edk to live in the following locations:
- //third_party/mojo/src/mojo/public
- //third_party/mojo/src/mojo/edk
It moves the related gypfiles from //mojo to //third_party/mojo and updates
them as necessary to account for the file moves. It also updates clients of the
mojo SDK and EDK targets in both GYP and GN. (Note that for GN, the mojo SDK
and EDK build systems are maintained in the Mojo repo and designed to be
flexible wrt the location of the SDK/EDK in a client repo, so no changes are
needed.
This CL does not update include paths to the code being moved to limit the
number of moving parts, instead relying on the include_dirs that the SDK and
EDK targets supply to their direct dependents to ensure that include paths
continue to resolve correctly.
NOPRESUBMIT=true
Review URL: https://codereview.chromium.org/814543006
Cr-Commit-Position: refs/heads/master@{#312129}
Diffstat (limited to 'mojo/public/cpp/utility')
-rw-r--r-- | mojo/public/cpp/utility/BUILD.gn | 35 | ||||
-rw-r--r-- | mojo/public/cpp/utility/DEPS | 3 | ||||
-rw-r--r-- | mojo/public/cpp/utility/lib/mutex.cc | 52 | ||||
-rw-r--r-- | mojo/public/cpp/utility/lib/run_loop.cc | 267 | ||||
-rw-r--r-- | mojo/public/cpp/utility/lib/thread.cc | 64 | ||||
-rw-r--r-- | mojo/public/cpp/utility/lib/thread_local.h | 54 | ||||
-rw-r--r-- | mojo/public/cpp/utility/lib/thread_local_posix.cc | 39 | ||||
-rw-r--r-- | mojo/public/cpp/utility/lib/thread_local_win.cc | 39 | ||||
-rw-r--r-- | mojo/public/cpp/utility/mutex.h | 70 | ||||
-rw-r--r-- | mojo/public/cpp/utility/run_loop.h | 145 | ||||
-rw-r--r-- | mojo/public/cpp/utility/run_loop_handler.h | 25 | ||||
-rw-r--r-- | mojo/public/cpp/utility/tests/BUILD.gn | 31 | ||||
-rw-r--r-- | mojo/public/cpp/utility/tests/mutex_unittest.cc | 259 | ||||
-rw-r--r-- | mojo/public/cpp/utility/tests/run_loop_unittest.cc | 425 | ||||
-rw-r--r-- | mojo/public/cpp/utility/tests/thread_unittest.cc | 106 | ||||
-rw-r--r-- | mojo/public/cpp/utility/thread.h | 62 |
16 files changed, 0 insertions, 1676 deletions
diff --git a/mojo/public/cpp/utility/BUILD.gn b/mojo/public/cpp/utility/BUILD.gn deleted file mode 100644 index 9660a07..0000000 --- a/mojo/public/cpp/utility/BUILD.gn +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2014 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("../../mojo_sdk.gni") - -mojo_sdk_source_set("utility") { - sources = [ - "mutex.h", - "run_loop.h", - "run_loop_handler.h", - "thread.h", - "lib/mutex.cc", - "lib/run_loop.cc", - "lib/thread.cc", - "lib/thread_local.h", - "lib/thread_local_posix.cc", - "lib/thread_local_win.cc", - ] - - mojo_sdk_deps = [ - "mojo/public/cpp/bindings:callback", - "mojo/public/cpp/system", - ] - - if (is_win) { - # See crbug.com/342893: - sources -= [ - "mutex.h", - "thread.h", - "lib/mutex.cc", - "lib/thread.cc", - ] - } -} diff --git a/mojo/public/cpp/utility/DEPS b/mojo/public/cpp/utility/DEPS deleted file mode 100644 index a9dfbd1..0000000 --- a/mojo/public/cpp/utility/DEPS +++ /dev/null @@ -1,3 +0,0 @@ -include_rules = [ - "+mojo/public/cpp/bindings/callback.h" -] diff --git a/mojo/public/cpp/utility/lib/mutex.cc b/mojo/public/cpp/utility/lib/mutex.cc deleted file mode 100644 index 23370e1..0000000 --- a/mojo/public/cpp/utility/lib/mutex.cc +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/public/cpp/utility/mutex.h" - -#include <assert.h> -#include <errno.h> - -namespace mojo { - -// Release builds have inlined (non-error-checking) definitions in the header. -#if !defined(NDEBUG) -Mutex::Mutex() { - pthread_mutexattr_t mutexattr; - int rv = pthread_mutexattr_init(&mutexattr); - assert(rv == 0); - rv = pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_ERRORCHECK); - assert(rv == 0); - rv = pthread_mutex_init(&mutex_, &mutexattr); - assert(rv == 0); - rv = pthread_mutexattr_destroy(&mutexattr); - assert(rv == 0); -} - -Mutex::~Mutex() { - int rv = pthread_mutex_destroy(&mutex_); - assert(rv == 0); -} - -void Mutex::Lock() { - int rv = pthread_mutex_lock(&mutex_); - assert(rv == 0); -} - -void Mutex::Unlock() { - int rv = pthread_mutex_unlock(&mutex_); - assert(rv == 0); -} - -bool Mutex::TryLock() { - int rv = pthread_mutex_trylock(&mutex_); - assert(rv == 0 || rv == EBUSY); - return rv == 0; -} - -void Mutex::AssertHeld() { - assert(pthread_mutex_lock(&mutex_) == EDEADLK); -} -#endif // !defined(NDEBUG) - -} // namespace mojo diff --git a/mojo/public/cpp/utility/lib/run_loop.cc b/mojo/public/cpp/utility/lib/run_loop.cc deleted file mode 100644 index 7faf748..0000000 --- a/mojo/public/cpp/utility/lib/run_loop.cc +++ /dev/null @@ -1,267 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/public/cpp/utility/run_loop.h" - -#include <assert.h> - -#include <algorithm> -#include <vector> - -#include "mojo/public/cpp/utility/lib/thread_local.h" -#include "mojo/public/cpp/utility/run_loop_handler.h" - -namespace mojo { -namespace { - -internal::ThreadLocalPointer<RunLoop> current_run_loop; - -const MojoTimeTicks kInvalidTimeTicks = static_cast<MojoTimeTicks>(0); - -} // namespace - -// State needed for one iteration of WaitMany(). -struct RunLoop::WaitState { - WaitState() : deadline(MOJO_DEADLINE_INDEFINITE) {} - - std::vector<Handle> handles; - std::vector<MojoHandleSignals> handle_signals; - MojoDeadline deadline; -}; - -struct RunLoop::RunState { - RunState() : should_quit(false) {} - - bool should_quit; -}; - -RunLoop::RunLoop() - : run_state_(nullptr), next_handler_id_(0), next_sequence_number_(0) { - assert(!current()); - current_run_loop.Set(this); -} - -RunLoop::~RunLoop() { - assert(current() == this); - NotifyHandlers(MOJO_RESULT_ABORTED, IGNORE_DEADLINE); - current_run_loop.Set(nullptr); -} - -// static -void RunLoop::SetUp() { - current_run_loop.Allocate(); -} - -// static -void RunLoop::TearDown() { - assert(!current()); - current_run_loop.Free(); -} - -// static -RunLoop* RunLoop::current() { - return current_run_loop.Get(); -} - -void RunLoop::AddHandler(RunLoopHandler* handler, - const Handle& handle, - MojoHandleSignals handle_signals, - MojoDeadline deadline) { - assert(current() == this); - assert(handler); - assert(handle.is_valid()); - // Assume it's an error if someone tries to reregister an existing handle. - assert(0u == handler_data_.count(handle)); - HandlerData handler_data; - handler_data.handler = handler; - handler_data.handle_signals = handle_signals; - handler_data.deadline = - (deadline == MOJO_DEADLINE_INDEFINITE) - ? kInvalidTimeTicks - : GetTimeTicksNow() + static_cast<MojoTimeTicks>(deadline); - handler_data.id = next_handler_id_++; - handler_data_[handle] = handler_data; -} - -void RunLoop::RemoveHandler(const Handle& handle) { - assert(current() == this); - handler_data_.erase(handle); -} - -bool RunLoop::HasHandler(const Handle& handle) const { - return handler_data_.find(handle) != handler_data_.end(); -} - -void RunLoop::Run() { - RunInternal(UNTIL_EMPTY); -} - -void RunLoop::RunUntilIdle() { - RunInternal(UNTIL_IDLE); -} - -void RunLoop::RunInternal(RunMode run_mode) { - assert(current() == this); - RunState* old_state = run_state_; - RunState run_state; - run_state_ = &run_state; - for (;;) { - bool did_work = DoDelayedWork(); - if (run_state.should_quit) - break; - did_work |= Wait(run_mode == UNTIL_IDLE); - if (run_state.should_quit) - break; - if (!did_work && run_mode == UNTIL_IDLE) - break; - } - run_state_ = old_state; -} - -bool RunLoop::DoDelayedWork() { - MojoTimeTicks now = GetTimeTicksNow(); - if (!delayed_tasks_.empty() && delayed_tasks_.top().run_time <= now) { - PendingTask task = delayed_tasks_.top(); - delayed_tasks_.pop(); - task.task.Run(); - return true; - } - return false; -} - -void RunLoop::Quit() { - assert(current() == this); - if (run_state_) - run_state_->should_quit = true; -} - -void RunLoop::PostDelayedTask(const Closure& task, MojoTimeTicks delay) { - assert(current() == this); - MojoTimeTicks run_time = delay + GetTimeTicksNow(); - delayed_tasks_.push(PendingTask(task, run_time, next_sequence_number_++)); -} - -bool RunLoop::Wait(bool non_blocking) { - const WaitState wait_state = GetWaitState(non_blocking); - if (wait_state.handles.empty()) { - if (delayed_tasks_.empty()) - Quit(); - return false; - } - - const WaitManyResult wmr = - WaitMany(wait_state.handles, wait_state.handle_signals, - wait_state.deadline, nullptr); - - if (!wmr.IsIndexValid()) { - assert(wmr.result == MOJO_RESULT_DEADLINE_EXCEEDED); - return NotifyHandlers(MOJO_RESULT_DEADLINE_EXCEEDED, CHECK_DEADLINE); - } - - Handle handle = wait_state.handles[wmr.index]; - assert(handler_data_.find(handle) != handler_data_.end()); - RunLoopHandler* handler = handler_data_[handle].handler; - - switch (wmr.result) { - case MOJO_RESULT_OK: - handler->OnHandleReady(handle); - return true; - case MOJO_RESULT_INVALID_ARGUMENT: - case MOJO_RESULT_FAILED_PRECONDITION: - // Remove the handle first, this way if OnHandleError() tries to remove - // the handle our iterator isn't invalidated. - handler_data_.erase(handle); - handler->OnHandleError(handle, wmr.result); - return true; - default: - assert(false); - return false; - } -} - -bool RunLoop::NotifyHandlers(MojoResult error, CheckDeadline check) { - bool notified = false; - - // Make a copy in case someone tries to add/remove new handlers as part of - // notifying. - const HandleToHandlerData cloned_handlers(handler_data_); - const MojoTimeTicks now(GetTimeTicksNow()); - for (HandleToHandlerData::const_iterator i = cloned_handlers.begin(); - i != cloned_handlers.end(); - ++i) { - // Only check deadline exceeded if that's what we're notifying. - if (check == CHECK_DEADLINE && - (i->second.deadline == kInvalidTimeTicks || i->second.deadline > now)) { - continue; - } - - // Since we're iterating over a clone of the handlers, verify the handler - // is still valid before notifying. - if (handler_data_.find(i->first) == handler_data_.end() || - handler_data_[i->first].id != i->second.id) { - continue; - } - - RunLoopHandler* handler = i->second.handler; - handler_data_.erase(i->first); - handler->OnHandleError(i->first, error); - notified = true; - } - - return notified; -} - -RunLoop::WaitState RunLoop::GetWaitState(bool non_blocking) const { - WaitState wait_state; - MojoTimeTicks min_time = kInvalidTimeTicks; - for (HandleToHandlerData::const_iterator i = handler_data_.begin(); - i != handler_data_.end(); - ++i) { - wait_state.handles.push_back(i->first); - wait_state.handle_signals.push_back(i->second.handle_signals); - if (!non_blocking && i->second.deadline != kInvalidTimeTicks && - (min_time == kInvalidTimeTicks || i->second.deadline < min_time)) { - min_time = i->second.deadline; - } - } - if (!delayed_tasks_.empty()) { - MojoTimeTicks delayed_min_time = delayed_tasks_.top().run_time; - if (min_time == kInvalidTimeTicks) - min_time = delayed_min_time; - else - min_time = std::min(min_time, delayed_min_time); - } - if (non_blocking) { - wait_state.deadline = static_cast<MojoDeadline>(0); - } else if (min_time != kInvalidTimeTicks) { - const MojoTimeTicks now = GetTimeTicksNow(); - if (min_time < now) - wait_state.deadline = static_cast<MojoDeadline>(0); - else - wait_state.deadline = static_cast<MojoDeadline>(min_time - now); - } - return wait_state; -} - -RunLoop::PendingTask::PendingTask(const Closure& task, - MojoTimeTicks run_time, - uint64_t sequence_number) - : task(task), run_time(run_time), sequence_number(sequence_number) { -} - -RunLoop::PendingTask::~PendingTask() { -} - -bool RunLoop::PendingTask::operator<(const RunLoop::PendingTask& other) const { - if (run_time != other.run_time) { - // std::priority_queue<> puts the least element at the end of the queue. We - // want the soonest eligible task to be at the head of the queue, so - // run_times further in the future are considered lesser. - return run_time > other.run_time; - } - - return sequence_number > other.sequence_number; -} - -} // namespace mojo diff --git a/mojo/public/cpp/utility/lib/thread.cc b/mojo/public/cpp/utility/lib/thread.cc deleted file mode 100644 index 40f0bdd..0000000 --- a/mojo/public/cpp/utility/lib/thread.cc +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/public/cpp/utility/thread.h" - -#include <assert.h> - -namespace mojo { - -Thread::Thread() : options_(), thread_(), started_(false), joined_(false) { -} - -Thread::Thread(const Options& options) - : options_(options), thread_(), started_(false), joined_(false) { -} - -Thread::~Thread() { - // If it was started, it must have been joined. - assert(!started_ || joined_); -} - -void Thread::Start() { - assert(!started_); - assert(!joined_); - - pthread_attr_t attr; - int rv = pthread_attr_init(&attr); - MOJO_ALLOW_UNUSED_LOCAL(rv); - assert(rv == 0); - - // Non-default stack size? - if (options_.stack_size() != 0) { - rv = pthread_attr_setstacksize(&attr, options_.stack_size()); - assert(rv == 0); - } - - started_ = true; - rv = pthread_create(&thread_, &attr, &ThreadRunTrampoline, this); - assert(rv == 0); - - rv = pthread_attr_destroy(&attr); - assert(rv == 0); -} - -void Thread::Join() { - // Must have been started but not yet joined. - assert(started_); - assert(!joined_); - - joined_ = true; - int rv = pthread_join(thread_, nullptr); - MOJO_ALLOW_UNUSED_LOCAL(rv); - assert(rv == 0); -} - -// static -void* Thread::ThreadRunTrampoline(void* arg) { - Thread* self = static_cast<Thread*>(arg); - self->Run(); - return nullptr; -} - -} // namespace mojo diff --git a/mojo/public/cpp/utility/lib/thread_local.h b/mojo/public/cpp/utility/lib/thread_local.h deleted file mode 100644 index f5461ee..0000000 --- a/mojo/public/cpp/utility/lib/thread_local.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_CPP_UTILITY_LIB_THREAD_LOCAL_H_ -#define MOJO_PUBLIC_CPP_UTILITY_LIB_THREAD_LOCAL_H_ - -#ifndef _WIN32 -#include <pthread.h> -#endif - -#include "mojo/public/cpp/system/macros.h" - -namespace mojo { -namespace internal { - -// Helper functions that abstract the cross-platform APIs. -struct ThreadLocalPlatform { -#ifdef _WIN32 - typedef unsigned long SlotType; -#else - typedef pthread_key_t SlotType; -#endif - - static void AllocateSlot(SlotType* slot); - static void FreeSlot(SlotType slot); - static void* GetValueFromSlot(SlotType slot); - static void SetValueInSlot(SlotType slot, void* value); -}; - -// This class is intended to be statically allocated. -template <typename P> -class ThreadLocalPointer { - public: - ThreadLocalPointer() : slot_() {} - - void Allocate() { ThreadLocalPlatform::AllocateSlot(&slot_); } - - void Free() { ThreadLocalPlatform::FreeSlot(slot_); } - - P* Get() { - return static_cast<P*>(ThreadLocalPlatform::GetValueFromSlot(slot_)); - } - - void Set(P* value) { ThreadLocalPlatform::SetValueInSlot(slot_, value); } - - private: - ThreadLocalPlatform::SlotType slot_; -}; - -} // namespace internal -} // namespace mojo - -#endif // MOJO_PUBLIC_CPP_UTILITY_LIB_THREAD_LOCAL_H_ diff --git a/mojo/public/cpp/utility/lib/thread_local_posix.cc b/mojo/public/cpp/utility/lib/thread_local_posix.cc deleted file mode 100644 index ea7343e..0000000 --- a/mojo/public/cpp/utility/lib/thread_local_posix.cc +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/public/cpp/utility/lib/thread_local.h" - -#include <assert.h> - -namespace mojo { -namespace internal { - -// static -void ThreadLocalPlatform::AllocateSlot(SlotType* slot) { - if (pthread_key_create(slot, nullptr) != 0) { - assert(false); - } -} - -// static -void ThreadLocalPlatform::FreeSlot(SlotType slot) { - if (pthread_key_delete(slot) != 0) { - assert(false); - } -} - -// static -void* ThreadLocalPlatform::GetValueFromSlot(SlotType slot) { - return pthread_getspecific(slot); -} - -// static -void ThreadLocalPlatform::SetValueInSlot(SlotType slot, void* value) { - if (pthread_setspecific(slot, value) != 0) { - assert(false); - } -} - -} // namespace internal -} // namespace mojo diff --git a/mojo/public/cpp/utility/lib/thread_local_win.cc b/mojo/public/cpp/utility/lib/thread_local_win.cc deleted file mode 100644 index 98841f7..0000000 --- a/mojo/public/cpp/utility/lib/thread_local_win.cc +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/public/cpp/utility/lib/thread_local.h" - -#include <assert.h> -#include <windows.h> - -namespace mojo { -namespace internal { - -// static -void ThreadLocalPlatform::AllocateSlot(SlotType* slot) { - *slot = TlsAlloc(); - assert(*slot != TLS_OUT_OF_INDEXES); -} - -// static -void ThreadLocalPlatform::FreeSlot(SlotType slot) { - if (!TlsFree(slot)) { - assert(false); - } -} - -// static -void* ThreadLocalPlatform::GetValueFromSlot(SlotType slot) { - return TlsGetValue(slot); -} - -// static -void ThreadLocalPlatform::SetValueInSlot(SlotType slot, void* value) { - if (!TlsSetValue(slot, value)) { - assert(false); - } -} - -} // namespace internal -} // namespace mojo diff --git a/mojo/public/cpp/utility/mutex.h b/mojo/public/cpp/utility/mutex.h deleted file mode 100644 index 4dc4aee..0000000 --- a/mojo/public/cpp/utility/mutex.h +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_CPP_UTILITY_MUTEX_H_ -#define MOJO_PUBLIC_CPP_UTILITY_MUTEX_H_ - -#ifdef _WIN32 -#error "Not implemented: See crbug.com/342893." -#endif - -#include <pthread.h> - -#include "mojo/public/cpp/system/macros.h" - -namespace mojo { - -#ifdef NDEBUG -// Note: Make a C++ constant for |PTHREAD_MUTEX_INITIALIZER|. (We can't directly -// use the C macro in an initializer list, since it might expand to |{ ... }|.) -namespace internal { -const pthread_mutex_t kPthreadMutexInitializer = PTHREAD_MUTEX_INITIALIZER; -} -#endif - -class Mutex { - public: -#ifdef NDEBUG - Mutex() : mutex_(internal::kPthreadMutexInitializer) {} - ~Mutex() { pthread_mutex_destroy(&mutex_); } - - void Lock() { pthread_mutex_lock(&mutex_); } - void Unlock() { pthread_mutex_unlock(&mutex_); } - bool TryLock() { return pthread_mutex_trylock(&mutex_) == 0; } - - void AssertHeld() {} -#else - Mutex(); - ~Mutex(); - - void Lock(); - void Unlock(); - bool TryLock(); - - void AssertHeld(); -#endif - - private: - pthread_mutex_t mutex_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(Mutex); -}; - -class MutexLock { - public: - explicit MutexLock(Mutex* mutex) : mutex_(mutex) { mutex_->Lock(); } - ~MutexLock() { mutex_->Unlock(); } - - private: - Mutex* const mutex_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(MutexLock); -}; - -// Catch bug where variable name is omitted (e.g., |MutexLock (&mu)|). -#define MutexLock(x) static_assert(0, "MutexLock() missing variable name"); - -} // namespace mojo - -#endif // MOJO_PUBLIC_CPP_UTILITY_MUTEX_H_ diff --git a/mojo/public/cpp/utility/run_loop.h b/mojo/public/cpp/utility/run_loop.h deleted file mode 100644 index 5ebe63e..0000000 --- a/mojo/public/cpp/utility/run_loop.h +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_H_ -#define MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_H_ - -#include <map> -#include <queue> - -#include "mojo/public/cpp/bindings/callback.h" -#include "mojo/public/cpp/system/core.h" - -namespace mojo { - -class RunLoopHandler; - -class RunLoop { - public: - RunLoop(); - ~RunLoop(); - - // Sets up state needed for RunLoop. This must be invoked before creating a - // RunLoop. - static void SetUp(); - - // Cleans state created by Setup(). - static void TearDown(); - - // Returns the RunLoop for the current thread. Returns null if not yet - // created. - static RunLoop* current(); - - // Registers a RunLoopHandler for the specified handle. Only one handler can - // be registered for a specified handle. - void AddHandler(RunLoopHandler* handler, - const Handle& handle, - MojoHandleSignals handle_signals, - MojoDeadline deadline); - void RemoveHandler(const Handle& handle); - bool HasHandler(const Handle& handle) const; - - // Runs the loop servicing handles and tasks as they are ready. This returns - // when Quit() is invoked, or there are no more handles nor tasks. - void Run(); - - // Runs the loop servicing any handles and tasks that are ready. Does not wait - // for handles or tasks to become ready before returning. Returns early if - // Quit() is invoked. - void RunUntilIdle(); - - void Quit(); - - // Adds a task to be performed after delay has elapsed. Must be posted to the - // current thread's RunLoop. - void PostDelayedTask(const Closure& task, MojoTimeTicks delay); - - private: - struct RunState; - struct WaitState; - - // Contains the data needed to track a request to AddHandler(). - struct HandlerData { - HandlerData() - : handler(nullptr), - handle_signals(MOJO_HANDLE_SIGNAL_NONE), - deadline(0), - id(0) {} - - RunLoopHandler* handler; - MojoHandleSignals handle_signals; - MojoTimeTicks deadline; - // See description of |RunLoop::next_handler_id_| for details. - int id; - }; - - typedef std::map<Handle, HandlerData> HandleToHandlerData; - - // Used for NotifyHandlers to specify whether HandlerData's |deadline| - // should be checked prior to notifying. - enum CheckDeadline { CHECK_DEADLINE, IGNORE_DEADLINE }; - - // Mode of operation of the run loop. - enum RunMode { UNTIL_EMPTY, UNTIL_IDLE }; - - // Runs the loop servicing any handles and tasks that are ready. If - // |run_mode| is |UNTIL_IDLE|, does not wait for handles or tasks to become - // ready before returning. Returns early if Quit() is invoked. - void RunInternal(RunMode run_mode); - - // Do one unit of delayed work, if eligible. Returns true is a task was run. - bool DoDelayedWork(); - - // Waits for a handle to be ready or until the next task must be run. Returns - // after servicing at least one handle (or there are no more handles) unless - // a task must be run or |non_blocking| is true, in which case it will also - // return if no task is registered and servicing at least one handle would - // require blocking. Returns true if a RunLoopHandler was notified. - bool Wait(bool non_blocking); - - // Notifies handlers of |error|. If |check| == CHECK_DEADLINE, this will - // only notify handlers whose deadline has expired and skips the rest. - // Returns true if a RunLoopHandler was notified. - bool NotifyHandlers(MojoResult error, CheckDeadline check); - - // Returns the state needed to pass to WaitMany(). - WaitState GetWaitState(bool non_blocking) const; - - HandleToHandlerData handler_data_; - - // If non-null we're running (inside Run()). Member references a value on the - // stack. - RunState* run_state_; - - // An ever increasing value assigned to each HandlerData::id. Used to detect - // uniqueness while notifying. That is, while notifying expired timers we copy - // |handler_data_| and only notify handlers whose id match. If the id does not - // match it means the handler was removed then added so that we shouldn't - // notify it. - int next_handler_id_; - - struct PendingTask { - PendingTask(const Closure& task, - MojoTimeTicks runtime, - uint64_t sequence_number); - ~PendingTask(); - - bool operator<(const PendingTask& other) const; - - Closure task; - MojoTimeTicks run_time; - uint64_t sequence_number; - }; - // An ever increasing sequence number attached to each pending task in order - // to preserve relative order of tasks posted at the 'same' time. - uint64_t next_sequence_number_; - typedef std::priority_queue<PendingTask> DelayedTaskQueue; - DelayedTaskQueue delayed_tasks_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(RunLoop); -}; - -} // namespace mojo - -#endif // MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_H_ diff --git a/mojo/public/cpp/utility/run_loop_handler.h b/mojo/public/cpp/utility/run_loop_handler.h deleted file mode 100644 index 69838d5..0000000 --- a/mojo/public/cpp/utility/run_loop_handler.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_HANDLER_H_ -#define MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_HANDLER_H_ - -#include "mojo/public/cpp/system/core.h" - -namespace mojo { - -// Used by RunLoop to notify when a handle is either ready or has become -// invalid. -class RunLoopHandler { - public: - virtual void OnHandleReady(const Handle& handle) = 0; - virtual void OnHandleError(const Handle& handle, MojoResult result) = 0; - - protected: - virtual ~RunLoopHandler() {} -}; - -} // namespace mojo - -#endif // MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_HANDLER_H_ diff --git a/mojo/public/cpp/utility/tests/BUILD.gn b/mojo/public/cpp/utility/tests/BUILD.gn deleted file mode 100644 index a8a96c1..0000000 --- a/mojo/public/cpp/utility/tests/BUILD.gn +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright 2014 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("../../../mojo_sdk.gni") - -mojo_sdk_source_set("tests") { - testonly = true - - sources = [ - "run_loop_unittest.cc", - ] - - deps = [ - "//testing/gtest", - ] - - mojo_sdk_deps = [ - "mojo/public/cpp/system", - "mojo/public/cpp/test_support:test_utils", - "mojo/public/cpp/utility", - ] - - # crbug.com/342893 - if (!is_win) { - sources += [ - "mutex_unittest.cc", - "thread_unittest.cc", - ] - } -} diff --git a/mojo/public/cpp/utility/tests/mutex_unittest.cc b/mojo/public/cpp/utility/tests/mutex_unittest.cc deleted file mode 100644 index 78e95c5..0000000 --- a/mojo/public/cpp/utility/tests/mutex_unittest.cc +++ /dev/null @@ -1,259 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/public/cpp/utility/mutex.h" - -#include <stdlib.h> // For |rand()|. -#include <time.h> // For |nanosleep()| (defined by POSIX). - -#include <vector> - -#include "mojo/public/cpp/system/macros.h" -#include "mojo/public/cpp/utility/thread.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace { - -TEST(MutexTest, TrivialSingleThreaded) { - Mutex mutex; - - mutex.Lock(); - mutex.AssertHeld(); - mutex.Unlock(); - - EXPECT_TRUE(mutex.TryLock()); - mutex.AssertHeld(); - mutex.Unlock(); - - { - MutexLock lock(&mutex); - mutex.AssertHeld(); - } - - EXPECT_TRUE(mutex.TryLock()); - mutex.Unlock(); -} - -class Fiddler { - public: - enum Type { kTypeLock, kTypeTry }; - Fiddler(size_t times_to_lock, - Type type, - bool should_sleep, - Mutex* mutex, - int* shared_value) - : times_to_lock_(times_to_lock), - type_(type), - should_sleep_(should_sleep), - mutex_(mutex), - shared_value_(shared_value) { - } - - ~Fiddler() { - } - - void Fiddle() { - for (size_t i = 0; i < times_to_lock_;) { - switch (type_) { - case kTypeLock: { - mutex_->Lock(); - int old_shared_value = *shared_value_; - if (should_sleep_) - SleepALittle(); - *shared_value_ = old_shared_value + 1; - mutex_->Unlock(); - i++; - break; - } - case kTypeTry: - if (mutex_->TryLock()) { - int old_shared_value = *shared_value_; - if (should_sleep_) - SleepALittle(); - *shared_value_ = old_shared_value + 1; - mutex_->Unlock(); - i++; - } else { - SleepALittle(); // Don't spin. - } - break; - } - } - } - - private: - static void SleepALittle() { - static const long kNanosPerMilli = 1000000; - struct timespec req = { - 0, // Seconds. - (rand() % 10) * kNanosPerMilli // Nanoseconds. - }; - int rv = nanosleep(&req, nullptr); - MOJO_ALLOW_UNUSED_LOCAL(rv); - assert(rv == 0); - } - - const size_t times_to_lock_; - const Type type_; - const bool should_sleep_; - Mutex* const mutex_; - int* const shared_value_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(Fiddler); -}; - -class FiddlerThread : public Thread { - public: - // Takes ownership of |fiddler|. - FiddlerThread(Fiddler* fiddler) - : fiddler_(fiddler) { - } - - ~FiddlerThread() override { delete fiddler_; } - - void Run() override { fiddler_->Fiddle(); } - - private: - Fiddler* const fiddler_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(FiddlerThread); -}; - -// This does a stress test (that also checks exclusion). -TEST(MutexTest, ThreadedStress) { - static const size_t kNumThreads = 20; - static const int kTimesToLockEach = 20; - assert(kNumThreads % 4 == 0); - - Mutex mutex; - int shared_value = 0; - - std::vector<FiddlerThread*> fiddler_threads; - - for (size_t i = 0; i < kNumThreads; i += 4) { - fiddler_threads.push_back(new FiddlerThread(new Fiddler( - kTimesToLockEach, Fiddler::kTypeLock, false, &mutex, &shared_value))); - fiddler_threads.push_back(new FiddlerThread(new Fiddler( - kTimesToLockEach, Fiddler::kTypeTry, false, &mutex, &shared_value))); - fiddler_threads.push_back(new FiddlerThread(new Fiddler( - kTimesToLockEach, Fiddler::kTypeLock, true, &mutex, &shared_value))); - fiddler_threads.push_back(new FiddlerThread(new Fiddler( - kTimesToLockEach, Fiddler::kTypeTry, true, &mutex, &shared_value))); - } - - for (size_t i = 0; i < kNumThreads; i++) - fiddler_threads[i]->Start(); - - // Do some fiddling ourselves. - Fiddler(kTimesToLockEach, Fiddler::kTypeLock, true, &mutex, &shared_value) - .Fiddle(); - - // Join. - for (size_t i = 0; i < kNumThreads; i++) - fiddler_threads[i]->Join(); - - EXPECT_EQ(static_cast<int>(kNumThreads + 1) * kTimesToLockEach, shared_value); - - // Delete. - for (size_t i = 0; i < kNumThreads; i++) - delete fiddler_threads[i]; - fiddler_threads.clear(); -} - -class TryThread : public Thread { - public: - explicit TryThread(Mutex* mutex) : mutex_(mutex), try_lock_succeeded_() {} - ~TryThread() override {} - - void Run() override { - try_lock_succeeded_ = mutex_->TryLock(); - if (try_lock_succeeded_) - mutex_->Unlock(); - } - - bool try_lock_succeeded() const { return try_lock_succeeded_; } - - private: - Mutex* const mutex_; - bool try_lock_succeeded_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(TryThread); -}; - -TEST(MutexTest, TryLock) { - Mutex mutex; - - // |TryLock()| should succeed -- we don't have the lock. - { - TryThread thread(&mutex); - thread.Start(); - thread.Join(); - EXPECT_TRUE(thread.try_lock_succeeded()); - } - - // Take the lock. - ASSERT_TRUE(mutex.TryLock()); - - // Now it should fail. - { - TryThread thread(&mutex); - thread.Start(); - thread.Join(); - EXPECT_FALSE(thread.try_lock_succeeded()); - } - - // Release the lock. - mutex.Unlock(); - - // It should succeed again. - { - TryThread thread(&mutex); - thread.Start(); - thread.Join(); - EXPECT_TRUE(thread.try_lock_succeeded()); - } -} - - -// Tests of assertions for Debug builds. -#if !defined(NDEBUG) -// Test |AssertHeld()| (which is an actual user API). -TEST(MutexTest, DebugAssertHeldFailure) { - Mutex mutex; - EXPECT_DEATH_IF_SUPPORTED(mutex.AssertHeld(), ""); -} - -// Test other consistency checks. -TEST(MutexTest, DebugAssertionFailures) { - // Unlock without lock held. - EXPECT_DEATH_IF_SUPPORTED({ - Mutex mutex; - mutex.Unlock(); - }, ""); - - // Lock with lock held (on same thread). - EXPECT_DEATH_IF_SUPPORTED({ - Mutex mutex; - mutex.Lock(); - mutex.Lock(); - }, ""); - - // Try lock with lock held. - EXPECT_DEATH_IF_SUPPORTED({ - Mutex mutex; - mutex.Lock(); - mutex.TryLock(); - }, ""); - - // Destroy lock with lock held. - EXPECT_DEATH_IF_SUPPORTED({ - Mutex mutex; - mutex.Lock(); - }, ""); -} -#endif // !defined(NDEBUG) - -} // namespace -} // namespace mojo diff --git a/mojo/public/cpp/utility/tests/run_loop_unittest.cc b/mojo/public/cpp/utility/tests/run_loop_unittest.cc deleted file mode 100644 index 4ab4876..0000000 --- a/mojo/public/cpp/utility/tests/run_loop_unittest.cc +++ /dev/null @@ -1,425 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/public/cpp/utility/run_loop.h" - -#include <string> - -#include "mojo/public/cpp/system/core.h" -#include "mojo/public/cpp/test_support/test_utils.h" -#include "mojo/public/cpp/utility/run_loop_handler.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace { - -class TestRunLoopHandler : public RunLoopHandler { - public: - TestRunLoopHandler() - : ready_count_(0), - error_count_(0), - last_error_result_(MOJO_RESULT_OK) { - } - ~TestRunLoopHandler() override {} - - void clear_ready_count() { ready_count_ = 0; } - int ready_count() const { return ready_count_; } - - void clear_error_count() { error_count_ = 0; } - int error_count() const { return error_count_; } - - MojoResult last_error_result() const { return last_error_result_; } - - // RunLoopHandler: - void OnHandleReady(const Handle& handle) override { ready_count_++; } - void OnHandleError(const Handle& handle, MojoResult result) override { - error_count_++; - last_error_result_ = result; - } - - private: - int ready_count_; - int error_count_; - MojoResult last_error_result_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(TestRunLoopHandler); -}; - -class RunLoopTest : public testing::Test { - public: - RunLoopTest() {} - - void SetUp() override { - Test::SetUp(); - RunLoop::SetUp(); - } - void TearDown() override { - RunLoop::TearDown(); - Test::TearDown(); - } - - private: - MOJO_DISALLOW_COPY_AND_ASSIGN(RunLoopTest); -}; - -// Trivial test to verify Run() with no added handles returns. -TEST_F(RunLoopTest, ExitsWithNoHandles) { - RunLoop run_loop; - run_loop.Run(); -} - -class RemoveOnReadyRunLoopHandler : public TestRunLoopHandler { - public: - RemoveOnReadyRunLoopHandler() : run_loop_(nullptr) {} - ~RemoveOnReadyRunLoopHandler() override {} - - void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; } - - // RunLoopHandler: - void OnHandleReady(const Handle& handle) override { - run_loop_->RemoveHandler(handle); - TestRunLoopHandler::OnHandleReady(handle); - } - - private: - RunLoop* run_loop_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(RemoveOnReadyRunLoopHandler); -}; - -// Verifies RunLoop quits when no more handles (handle is removed when ready). -TEST_F(RunLoopTest, HandleReady) { - RemoveOnReadyRunLoopHandler handler; - MessagePipe test_pipe; - EXPECT_TRUE(test::WriteTextMessage(test_pipe.handle1.get(), std::string())); - - RunLoop run_loop; - handler.set_run_loop(&run_loop); - run_loop.AddHandler(&handler, test_pipe.handle0.get(), - MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE); - run_loop.Run(); - EXPECT_EQ(1, handler.ready_count()); - EXPECT_EQ(0, handler.error_count()); - EXPECT_FALSE(run_loop.HasHandler(test_pipe.handle0.get())); -} - -class QuitOnReadyRunLoopHandler : public TestRunLoopHandler { - public: - QuitOnReadyRunLoopHandler() : run_loop_(nullptr) {} - ~QuitOnReadyRunLoopHandler() override {} - - void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; } - - // RunLoopHandler: - void OnHandleReady(const Handle& handle) override { - run_loop_->Quit(); - TestRunLoopHandler::OnHandleReady(handle); - } - - private: - RunLoop* run_loop_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(QuitOnReadyRunLoopHandler); -}; - -// Verifies Quit() from OnHandleReady() quits the loop. -TEST_F(RunLoopTest, QuitFromReady) { - QuitOnReadyRunLoopHandler handler; - MessagePipe test_pipe; - EXPECT_TRUE(test::WriteTextMessage(test_pipe.handle1.get(), std::string())); - - RunLoop run_loop; - handler.set_run_loop(&run_loop); - run_loop.AddHandler(&handler, test_pipe.handle0.get(), - MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE); - run_loop.Run(); - EXPECT_EQ(1, handler.ready_count()); - EXPECT_EQ(0, handler.error_count()); - EXPECT_TRUE(run_loop.HasHandler(test_pipe.handle0.get())); -} - -class QuitOnErrorRunLoopHandler : public TestRunLoopHandler { - public: - QuitOnErrorRunLoopHandler() : run_loop_(nullptr) {} - ~QuitOnErrorRunLoopHandler() override {} - - void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; } - - // RunLoopHandler: - void OnHandleError(const Handle& handle, MojoResult result) override { - run_loop_->Quit(); - TestRunLoopHandler::OnHandleError(handle, result); - } - - private: - RunLoop* run_loop_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(QuitOnErrorRunLoopHandler); -}; - -// Verifies Quit() when the deadline is reached works. -TEST_F(RunLoopTest, QuitWhenDeadlineExpired) { - QuitOnErrorRunLoopHandler handler; - MessagePipe test_pipe; - RunLoop run_loop; - handler.set_run_loop(&run_loop); - run_loop.AddHandler(&handler, test_pipe.handle0.get(), - MOJO_HANDLE_SIGNAL_READABLE, - static_cast<MojoDeadline>(10000)); - run_loop.Run(); - EXPECT_EQ(0, handler.ready_count()); - EXPECT_EQ(1, handler.error_count()); - EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, handler.last_error_result()); - EXPECT_FALSE(run_loop.HasHandler(test_pipe.handle0.get())); -} - -// Test that handlers are notified of loop destruction. -TEST_F(RunLoopTest, Destruction) { - TestRunLoopHandler handler; - MessagePipe test_pipe; - { - RunLoop run_loop; - run_loop.AddHandler(&handler, - test_pipe.handle0.get(), - MOJO_HANDLE_SIGNAL_READABLE, - MOJO_DEADLINE_INDEFINITE); - } - EXPECT_EQ(1, handler.error_count()); - EXPECT_EQ(MOJO_RESULT_ABORTED, handler.last_error_result()); -} - -class RemoveManyRunLoopHandler : public TestRunLoopHandler { - public: - RemoveManyRunLoopHandler() : run_loop_(nullptr) {} - ~RemoveManyRunLoopHandler() override {} - - void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; } - void add_handle(const Handle& handle) { handles_.push_back(handle); } - - // RunLoopHandler: - void OnHandleError(const Handle& handle, MojoResult result) override { - for (size_t i = 0; i < handles_.size(); i++) - run_loop_->RemoveHandler(handles_[i]); - TestRunLoopHandler::OnHandleError(handle, result); - } - - private: - std::vector<Handle> handles_; - RunLoop* run_loop_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(RemoveManyRunLoopHandler); -}; - -// Test that handlers are notified of loop destruction. -TEST_F(RunLoopTest, MultipleHandleDestruction) { - RemoveManyRunLoopHandler odd_handler; - TestRunLoopHandler even_handler; - MessagePipe test_pipe1, test_pipe2, test_pipe3; - { - RunLoop run_loop; - odd_handler.set_run_loop(&run_loop); - odd_handler.add_handle(test_pipe1.handle0.get()); - odd_handler.add_handle(test_pipe3.handle0.get()); - run_loop.AddHandler(&odd_handler, - test_pipe1.handle0.get(), - MOJO_HANDLE_SIGNAL_READABLE, - MOJO_DEADLINE_INDEFINITE); - run_loop.AddHandler(&even_handler, - test_pipe2.handle0.get(), - MOJO_HANDLE_SIGNAL_READABLE, - MOJO_DEADLINE_INDEFINITE); - run_loop.AddHandler(&odd_handler, - test_pipe3.handle0.get(), - MOJO_HANDLE_SIGNAL_READABLE, - MOJO_DEADLINE_INDEFINITE); - } - EXPECT_EQ(1, odd_handler.error_count()); - EXPECT_EQ(1, even_handler.error_count()); - EXPECT_EQ(MOJO_RESULT_ABORTED, odd_handler.last_error_result()); - EXPECT_EQ(MOJO_RESULT_ABORTED, even_handler.last_error_result()); -} - -class AddHandlerOnErrorHandler : public TestRunLoopHandler { - public: - AddHandlerOnErrorHandler() : run_loop_(nullptr) {} - ~AddHandlerOnErrorHandler() override {} - - void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; } - - // RunLoopHandler: - void OnHandleError(const Handle& handle, MojoResult result) override { - run_loop_->AddHandler(this, handle, - MOJO_HANDLE_SIGNAL_READABLE, - MOJO_DEADLINE_INDEFINITE); - TestRunLoopHandler::OnHandleError(handle, result); - } - - private: - RunLoop* run_loop_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(AddHandlerOnErrorHandler); -}; - -TEST_F(RunLoopTest, AddHandlerOnError) { - AddHandlerOnErrorHandler handler; - MessagePipe test_pipe; - { - RunLoop run_loop; - handler.set_run_loop(&run_loop); - run_loop.AddHandler(&handler, - test_pipe.handle0.get(), - MOJO_HANDLE_SIGNAL_READABLE, - MOJO_DEADLINE_INDEFINITE); - } - EXPECT_EQ(1, handler.error_count()); - EXPECT_EQ(MOJO_RESULT_ABORTED, handler.last_error_result()); -} - -TEST_F(RunLoopTest, Current) { - EXPECT_TRUE(RunLoop::current() == nullptr); - { - RunLoop run_loop; - EXPECT_EQ(&run_loop, RunLoop::current()); - } - EXPECT_TRUE(RunLoop::current() == nullptr); -} - -class NestingRunLoopHandler : public TestRunLoopHandler { - public: - static const size_t kDepthLimit; - static const char kSignalMagic; - - NestingRunLoopHandler() - : run_loop_(nullptr), - pipe_(nullptr), - depth_(0), - reached_depth_limit_(false) {} - - ~NestingRunLoopHandler() override {} - - void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; } - void set_pipe(MessagePipe* pipe) { pipe_ = pipe; } - bool reached_depth_limit() const { return reached_depth_limit_; } - - // RunLoopHandler: - void OnHandleReady(const Handle& handle) override { - TestRunLoopHandler::OnHandleReady(handle); - EXPECT_EQ(handle.value(), pipe_->handle0.get().value()); - - ReadSignal(); - size_t current_depth = ++depth_; - if (current_depth < kDepthLimit) { - WriteSignal(); - run_loop_->Run(); - if (current_depth == kDepthLimit - 1) { - // The topmost loop Quit()-ed, so its parent takes back the - // control without exeeding deadline. - EXPECT_EQ(error_count(), 0); - } else { - EXPECT_EQ(error_count(), 1); - } - - } else { - EXPECT_EQ(current_depth, kDepthLimit); - reached_depth_limit_ = true; - run_loop_->Quit(); - } - --depth_; - } - - void WriteSignal() { - char write_byte = kSignalMagic; - MojoResult write_result = - WriteMessageRaw(pipe_->handle1.get(), &write_byte, 1, nullptr, 0, - MOJO_WRITE_MESSAGE_FLAG_NONE); - EXPECT_EQ(write_result, MOJO_RESULT_OK); - } - - void ReadSignal() { - char read_byte = 0; - uint32_t bytes_read = 1; - uint32_t handles_read = 0; - MojoResult read_result = - ReadMessageRaw(pipe_->handle0.get(), &read_byte, &bytes_read, nullptr, - &handles_read, MOJO_READ_MESSAGE_FLAG_NONE); - EXPECT_EQ(read_result, MOJO_RESULT_OK); - EXPECT_EQ(read_byte, kSignalMagic); - } - - private: - RunLoop* run_loop_; - MessagePipe* pipe_; - size_t depth_; - bool reached_depth_limit_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(NestingRunLoopHandler); -}; - -const size_t NestingRunLoopHandler::kDepthLimit = 10; -const char NestingRunLoopHandler::kSignalMagic = 'X'; - -TEST_F(RunLoopTest, NestedRun) { - NestingRunLoopHandler handler; - MessagePipe test_pipe; - RunLoop run_loop; - handler.set_run_loop(&run_loop); - handler.set_pipe(&test_pipe); - run_loop.AddHandler(&handler, test_pipe.handle0.get(), - MOJO_HANDLE_SIGNAL_READABLE, - static_cast<MojoDeadline>(10000)); - handler.WriteSignal(); - run_loop.Run(); - - EXPECT_TRUE(handler.reached_depth_limit()); - // Got MOJO_RESULT_DEADLINE_EXCEEDED once then removed from the - // RunLoop's handler list. - EXPECT_EQ(handler.error_count(), 1); - EXPECT_EQ(handler.last_error_result(), MOJO_RESULT_DEADLINE_EXCEEDED); -} - -struct Task { - Task(int num, std::vector<int>* sequence) : num(num), sequence(sequence) {} - - void Run() const { sequence->push_back(num); } - - int num; - std::vector<int>* sequence; -}; - -TEST_F(RunLoopTest, DelayedTaskOrder) { - std::vector<int> sequence; - RunLoop run_loop; - run_loop.PostDelayedTask(Closure(Task(1, &sequence)), 0); - run_loop.PostDelayedTask(Closure(Task(2, &sequence)), 0); - run_loop.PostDelayedTask(Closure(Task(3, &sequence)), 0); - run_loop.RunUntilIdle(); - - ASSERT_EQ(3u, sequence.size()); - EXPECT_EQ(1, sequence[0]); - EXPECT_EQ(2, sequence[1]); - EXPECT_EQ(3, sequence[2]); -} - -struct QuittingTask { - explicit QuittingTask(RunLoop* run_loop) : run_loop(run_loop) {} - - void Run() const { run_loop->Quit(); } - - RunLoop* run_loop; -}; - -TEST_F(RunLoopTest, QuitFromDelayedTask) { - TestRunLoopHandler handler; - MessagePipe test_pipe; - RunLoop run_loop; - run_loop.AddHandler(&handler, - test_pipe.handle0.get(), - MOJO_HANDLE_SIGNAL_READABLE, - MOJO_DEADLINE_INDEFINITE); - run_loop.PostDelayedTask(Closure(QuittingTask(&run_loop)), 0); - run_loop.Run(); -} - -} // namespace -} // namespace mojo diff --git a/mojo/public/cpp/utility/tests/thread_unittest.cc b/mojo/public/cpp/utility/tests/thread_unittest.cc deleted file mode 100644 index 57c4ad9..0000000 --- a/mojo/public/cpp/utility/tests/thread_unittest.cc +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "mojo/public/cpp/utility/thread.h" - -#include "mojo/public/cpp/system/macros.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace { - -class SetIntThread : public Thread { - public: - SetIntThread(int* int_to_set, int value) - : int_to_set_(int_to_set), - value_(value) { - } - SetIntThread(const Options& options, int* int_to_set, int value) - : Thread(options), - int_to_set_(int_to_set), - value_(value) { - } - - ~SetIntThread() override {} - - void Run() override { *int_to_set_ = value_; } - - private: - int* const int_to_set_; - const int value_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(SetIntThread); -}; - -TEST(ThreadTest, CreateAndJoin) { - int value = 0; - - // Not starting the thread should result in a no-op. - { - SetIntThread thread(&value, 1234567); - } - EXPECT_EQ(0, value); - - // Start and join. - { - SetIntThread thread(&value, 12345678); - thread.Start(); - thread.Join(); - EXPECT_EQ(12345678, value); - } - - // Ditto, with non-default (but reasonable) stack size. - { - Thread::Options options; - options.set_stack_size(1024 * 1024); // 1 MB. - SetIntThread thread(options, &value, 12345678); - thread.Start(); - thread.Join(); - EXPECT_EQ(12345678, value); - } -} - -// Tests of assertions for Debug builds. -// Note: It's okay to create threads, despite gtest having to fork. (The threads -// are in the child process.) -#if !defined(NDEBUG) -TEST(ThreadTest, DebugAssertionFailures) { - // Can only start once. - EXPECT_DEATH_IF_SUPPORTED({ - int value = 0; - SetIntThread thread(&value, 1); - thread.Start(); - thread.Start(); - }, ""); - - // Must join (if you start). - EXPECT_DEATH_IF_SUPPORTED({ - int value = 0; - SetIntThread thread(&value, 2); - thread.Start(); - }, ""); - - // Can only join once. - EXPECT_DEATH_IF_SUPPORTED({ - int value = 0; - SetIntThread thread(&value, 3); - thread.Start(); - thread.Join(); - thread.Join(); - }, ""); - - // Stack too big (we're making certain assumptions here). - EXPECT_DEATH_IF_SUPPORTED({ - int value = 0; - Thread::Options options; - options.set_stack_size(static_cast<size_t>(-1)); - SetIntThread thread(options, &value, 4); - thread.Start(); - thread.Join(); - }, ""); -} -#endif // !defined(NDEBUG) - -} // namespace -} // namespace mojo diff --git a/mojo/public/cpp/utility/thread.h b/mojo/public/cpp/utility/thread.h deleted file mode 100644 index b7d10ee..0000000 --- a/mojo/public/cpp/utility/thread.h +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MOJO_PUBLIC_CPP_UTILITY_THREAD_H_ -#define MOJO_PUBLIC_CPP_UTILITY_THREAD_H_ - -#ifdef _WIN32 -#error "Not implemented: See crbug.com/342893." -#endif - -#include <pthread.h> -#include <stddef.h> - -#include "mojo/public/cpp/system/macros.h" - -namespace mojo { - -// This class is thread-friendly, not thread-safe (e.g., you mustn't call -// |Join()| from multiple threads and/or simultaneously try to destroy the -// object). -class Thread { - public: - // TODO(vtl): Support non-joinable? priority? - class Options { - public: - Options() : stack_size_(0) {} - - // A stack size of 0 means the default. - size_t stack_size() const { return stack_size_; } - void set_stack_size(size_t stack_size) { stack_size_ = stack_size; } - - private: - size_t stack_size_; - - // Copy and assign allowed. - }; - - // TODO(vtl): Add name or name prefix? - Thread(); - explicit Thread(const Options& options); - virtual ~Thread(); - - void Start(); - void Join(); - - virtual void Run() = 0; - - private: - static void* ThreadRunTrampoline(void* arg); - - const Options options_; - pthread_t thread_; - bool started_; - bool joined_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(Thread); -}; - -} // namespace mojo - -#endif // MOJO_PUBLIC_CPP_UTILITY_THREAD_H_ |