You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
174 lines
4.8 KiB
174 lines
4.8 KiB
// 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. |
|
// |
|
|
|
#ifndef STORAGE_LEVELDB_PORT_PORT_WIN_H_ |
|
#define STORAGE_LEVELDB_PORT_PORT_WIN_H_ |
|
|
|
#ifdef _MSC_VER |
|
#define snprintf _snprintf |
|
#define close _close |
|
#define fread_unlocked _fread_nolock |
|
#endif |
|
|
|
#include <string> |
|
#include <stdint.h> |
|
#ifdef SNAPPY |
|
#include <snappy.h> |
|
#endif |
|
|
|
namespace leveldb { |
|
namespace port { |
|
|
|
// Windows is little endian (for now :p) |
|
static const bool kLittleEndian = true; |
|
|
|
class CondVar; |
|
|
|
class Mutex { |
|
public: |
|
Mutex(); |
|
~Mutex(); |
|
|
|
void Lock(); |
|
void Unlock(); |
|
void AssertHeld(); |
|
|
|
private: |
|
friend class CondVar; |
|
// critical sections are more efficient than mutexes |
|
// but they are not recursive and can only be used to synchronize threads within the same process |
|
// we use opaque void * to avoid including windows.h in port_win.h |
|
void * cs_; |
|
|
|
// No copying |
|
Mutex(const Mutex&); |
|
void operator=(const Mutex&); |
|
}; |
|
|
|
// the Win32 API offers a dependable condition variable mechanism, but only starting with |
|
// Windows 2008 and Vista |
|
// no matter what we will implement our own condition variable with a semaphore |
|
// implementation as described in a paper written by Andrew D. Birrell in 2003 |
|
class CondVar { |
|
public: |
|
explicit CondVar(Mutex* mu); |
|
~CondVar(); |
|
void Wait(); |
|
void Signal(); |
|
void SignalAll(); |
|
private: |
|
Mutex* mu_; |
|
|
|
Mutex wait_mtx_; |
|
long waiting_; |
|
|
|
void * sem1_; |
|
void * sem2_; |
|
|
|
|
|
}; |
|
|
|
class OnceType { |
|
public: |
|
// OnceType() : init_(false) {} |
|
OnceType(const OnceType &once) : init_(once.init_) {} |
|
OnceType(bool f) : init_(f) {} |
|
void InitOnce(void (*initializer)()) { |
|
mutex_.Lock(); |
|
if (!init_) { |
|
init_ = true; |
|
initializer(); |
|
} |
|
mutex_.Unlock(); |
|
} |
|
|
|
private: |
|
bool init_; |
|
Mutex mutex_; |
|
}; |
|
|
|
#define LEVELDB_ONCE_INIT false |
|
extern void InitOnce(port::OnceType*, void (*initializer)()); |
|
|
|
// Storage for a lock-free pointer |
|
class AtomicPointer { |
|
private: |
|
void * rep_; |
|
public: |
|
AtomicPointer() : rep_(NULL) { } |
|
explicit AtomicPointer(void* v); |
|
void* Acquire_Load() const; |
|
|
|
void Release_Store(void* v); |
|
|
|
void* NoBarrier_Load() const; |
|
|
|
void NoBarrier_Store(void* v); |
|
}; |
|
|
|
inline bool Snappy_Compress(const char* input, size_t length, |
|
::std::string* output) { |
|
#ifdef SNAPPY |
|
output->resize(snappy::MaxCompressedLength(length)); |
|
size_t outlen; |
|
snappy::RawCompress(input, length, &(*output)[0], &outlen); |
|
output->resize(outlen); |
|
return true; |
|
#endif |
|
|
|
return false; |
|
} |
|
|
|
inline bool Snappy_GetUncompressedLength(const char* input, size_t length, |
|
size_t* result) { |
|
#ifdef SNAPPY |
|
return snappy::GetUncompressedLength(input, length, result); |
|
#else |
|
return false; |
|
#endif |
|
} |
|
|
|
inline bool Snappy_Uncompress(const char* input, size_t length, |
|
char* output) { |
|
#ifdef SNAPPY |
|
return snappy::RawUncompress(input, length, output); |
|
#else |
|
return false; |
|
#endif |
|
} |
|
|
|
inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) { |
|
return false; |
|
} |
|
|
|
} |
|
} |
|
|
|
#endif // STORAGE_LEVELDB_PORT_PORT_WIN_H_
|
|
|