diff options
Diffstat (limited to 'mojo/public/cpp/utility/lib')
-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 |
6 files changed, 0 insertions, 515 deletions
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 |