X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=blobdiff_plain;f=src%2Ftype3_AndroidCloud%2Fanbox-master%2Fexternal%2Fandroid-emugl%2Fshared%2Femugl%2Fcommon%2Fcondition_variable_win32.cpp;fp=src%2Ftype3_AndroidCloud%2Fanbox-master%2Fexternal%2Fandroid-emugl%2Fshared%2Femugl%2Fcommon%2Fcondition_variable_win32.cpp;h=e0e51a481338d109e884fbc2dbf51e216f3eb59f;hb=e26c1ec581be598521517829adba8c8dd23a768f;hp=0000000000000000000000000000000000000000;hpb=6699c1aea74eeb0eb400e6299079f0c7576f716f;p=iec.git diff --git a/src/type3_AndroidCloud/anbox-master/external/android-emugl/shared/emugl/common/condition_variable_win32.cpp b/src/type3_AndroidCloud/anbox-master/external/android-emugl/shared/emugl/common/condition_variable_win32.cpp new file mode 100644 index 0000000..e0e51a4 --- /dev/null +++ b/src/type3_AndroidCloud/anbox-master/external/android-emugl/shared/emugl/common/condition_variable_win32.cpp @@ -0,0 +1,114 @@ +// Copyright (C) 2014 The Android Open Source Project +// +// 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 "emugl/common/condition_variable.h" + +#include "emugl/common/lazy_instance.h" +#include "emugl/common/mutex.h" +#include "emugl/common/pod_vector.h" + +// Technical note: this is loosely based on the Chromium implementation +// of ConditionVariable. This version works on Windows XP and above and +// doesn't try to use Vista's CONDITION_VARIABLE types. + +namespace emugl { + +namespace { + +// Helper class which implements a free list of event handles. +class WaitEventStorage { +public: + WaitEventStorage() : mFreeHandles(), mLock() {} + + ~WaitEventStorage() { + for (size_t n = 0; n < mFreeHandles.size(); ++n) { + CloseHandle(mFreeHandles[n]); + } + } + + HANDLE alloc() { + HANDLE handle; + mLock.lock(); + size_t size = mFreeHandles.size(); + if (size > 0) { + handle = mFreeHandles[size - 1U]; + mFreeHandles.remove(size - 1U); + } else { + handle = CreateEvent(NULL, TRUE, FALSE, NULL); + } + mLock.unlock(); + return handle; + } + + void free(HANDLE h) { + mLock.lock(); + ResetEvent(h); + mFreeHandles.push_back(h); + mLock.unlock(); + } + +private: + PodVector mFreeHandles; + Mutex mLock; +}; + +LazyInstance sWaitEvents = LAZY_INSTANCE_INIT; + +} // namespace + +ConditionVariable::ConditionVariable() : mWaiters(), mLock() {} + +ConditionVariable::~ConditionVariable() { + mLock.lock(); + for (size_t n = 0; n < mWaiters.size(); ++n) { + CloseHandle(mWaiters[n]); + } + mWaiters.resize(0U); + mLock.unlock(); +} + +void ConditionVariable::wait(Mutex* userLock) { + // Grab new waiter event handle. + mLock.lock(); + HANDLE handle = sWaitEvents->alloc(); + mWaiters.push_back(handle); + mLock.unlock(); + + // Unlock user lock then wait for event. + userLock->unlock(); + WaitForSingleObject(handle, INFINITE); + // NOTE: The handle has been removed from mWaiters here, + // see signal() below. Close/recycle the event. + sWaitEvents->free(handle); + userLock->lock(); +} + +void ConditionVariable::signal() { + mLock.lock(); + size_t size = mWaiters.size(); + if (size > 0U) { + // NOTE: This wakes up the thread that went to sleep most + // recently (LIFO) for performance reason. For better + // fairness, using (FIFO) would be appropriate. + HANDLE handle = mWaiters[size - 1U]; + mWaiters.remove(size - 1U); + SetEvent(handle); + // NOTE: The handle will be closed/recycled by the waiter. + } else { + // Nothing to signal. + } + mLock.unlock(); +} + +} // namespace emugl