diff options
Diffstat (limited to 'src/leveldb/port/port_win.cc')
-rw-r--r-- | src/leveldb/port/port_win.cc | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/src/leveldb/port/port_win.cc b/src/leveldb/port/port_win.cc new file mode 100644 index 0000000000..7cf9537937 --- /dev/null +++ b/src/leveldb/port/port_win.cc @@ -0,0 +1,154 @@ +// LevelDB Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// See port_example.h for documentation for the following types/functions. + +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the University of California, Berkeley nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + +#include "port/port_win.h" + +#include <windows.h> +#include <cassert> + +namespace leveldb { +namespace port { + +Mutex::Mutex() : + cs_(nullptr) { + assert(!cs_); + cs_ = static_cast<void *>(new CRITICAL_SECTION()); + ::InitializeCriticalSection(static_cast<CRITICAL_SECTION *>(cs_)); + assert(cs_); +} + +Mutex::~Mutex() { + assert(cs_); + ::DeleteCriticalSection(static_cast<CRITICAL_SECTION *>(cs_)); + delete static_cast<CRITICAL_SECTION *>(cs_); + cs_ = nullptr; + assert(!cs_); +} + +void Mutex::Lock() { + assert(cs_); + ::EnterCriticalSection(static_cast<CRITICAL_SECTION *>(cs_)); +} + +void Mutex::Unlock() { + assert(cs_); + ::LeaveCriticalSection(static_cast<CRITICAL_SECTION *>(cs_)); +} + +void Mutex::AssertHeld() { + assert(cs_); + assert(1); +} + +CondVar::CondVar(Mutex* mu) : + waiting_(0), + mu_(mu), + sem1_(::CreateSemaphore(NULL, 0, 10000, NULL)), + sem2_(::CreateSemaphore(NULL, 0, 10000, NULL)) { + assert(mu_); +} + +CondVar::~CondVar() { + ::CloseHandle(sem1_); + ::CloseHandle(sem2_); +} + +void CondVar::Wait() { + mu_->AssertHeld(); + + wait_mtx_.Lock(); + ++waiting_; + wait_mtx_.Unlock(); + + mu_->Unlock(); + + // initiate handshake + ::WaitForSingleObject(sem1_, INFINITE); + ::ReleaseSemaphore(sem2_, 1, NULL); + mu_->Lock(); +} + +void CondVar::Signal() { + wait_mtx_.Lock(); + if (waiting_ > 0) { + --waiting_; + + // finalize handshake + ::ReleaseSemaphore(sem1_, 1, NULL); + ::WaitForSingleObject(sem2_, INFINITE); + } + wait_mtx_.Unlock(); +} + +void CondVar::SignalAll() { + wait_mtx_.Lock(); + for(long i = 0; i < waiting_; ++i) { + ::ReleaseSemaphore(sem1_, 1, NULL); + while(waiting_ > 0) { + --waiting_; + ::WaitForSingleObject(sem2_, INFINITE); + } + } + wait_mtx_.Unlock(); +} + +AtomicPointer::AtomicPointer(void* v) { + Release_Store(v); +} + +BOOL CALLBACK InitHandleFunction (PINIT_ONCE InitOnce, PVOID func, PVOID *lpContext) { + ((void (*)())func)(); + return true; +} + +void InitOnce(OnceType* once, void (*initializer)()) { + InitOnceExecuteOnce((PINIT_ONCE)once, InitHandleFunction, initializer, NULL); +} + +void* AtomicPointer::Acquire_Load() const { + void * p = nullptr; + InterlockedExchangePointer(&p, rep_); + return p; +} + +void AtomicPointer::Release_Store(void* v) { + InterlockedExchangePointer(&rep_, v); +} + +void* AtomicPointer::NoBarrier_Load() const { + return rep_; +} + +void AtomicPointer::NoBarrier_Store(void* v) { + rep_ = v; +} + +} +} |