diff --git a/CMakeLists.txt b/CMakeLists.txt index 5588120..4bf3df3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,33 +79,10 @@ if(BUILD_SHARED_LIBS) add_compile_options(-fvisibility=hidden) endif(BUILD_SHARED_LIBS) -# POSIX code is specified separately so we can leave it out in the future. -add_library(leveldb_port_posix OBJECT "") -target_sources(leveldb_port_posix - PRIVATE - "${PROJECT_SOURCE_DIR}/port/port_posix.cc" - - PUBLIC - # The headers below are dependencies for leveldb, but aren't needed by users - # that link to the installed version of leveldb and rely on its public API. - $ - $ - $ - $ -) -if (NOT HAVE_CXX17_HAS_INCLUDE) - target_compile_definitions(leveldb_port_posix - PRIVATE - LEVELDB_HAS_PORT_CONFIG_H=1 - ) -endif(NOT HAVE_CXX17_HAS_INCLUDE) -if(BUILD_SHARED_LIBS) - set_property(TARGET leveldb_port_posix PROPERTY POSITION_INDEPENDENT_CODE ON) -endif(BUILD_SHARED_LIBS) - add_library(leveldb "") target_sources(leveldb PRIVATE + "${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h" "${PROJECT_SOURCE_DIR}/db/builder.cc" "${PROJECT_SOURCE_DIR}/db/builder.h" "${PROJECT_SOURCE_DIR}/db/c.cc" @@ -136,6 +113,8 @@ target_sources(leveldb "${PROJECT_SOURCE_DIR}/db/version_set.h" "${PROJECT_SOURCE_DIR}/db/write_batch_internal.h" "${PROJECT_SOURCE_DIR}/db/write_batch.cc" + "${PROJECT_SOURCE_DIR}/port/atomic_pointer.h" + "${PROJECT_SOURCE_DIR}/port/port_stdcxx.h" "${PROJECT_SOURCE_DIR}/port/port.h" "${PROJECT_SOURCE_DIR}/port/thread_annotations.h" "${PROJECT_SOURCE_DIR}/table/block_builder.cc" @@ -163,7 +142,6 @@ target_sources(leveldb "${PROJECT_SOURCE_DIR}/util/comparator.cc" "${PROJECT_SOURCE_DIR}/util/crc32c.cc" "${PROJECT_SOURCE_DIR}/util/crc32c.h" - "${PROJECT_SOURCE_DIR}/util/env_posix.cc" "${PROJECT_SOURCE_DIR}/util/env.cc" "${PROJECT_SOURCE_DIR}/util/filter_policy.cc" "${PROJECT_SOURCE_DIR}/util/hash.cc" @@ -172,10 +150,8 @@ target_sources(leveldb "${PROJECT_SOURCE_DIR}/util/logging.h" "${PROJECT_SOURCE_DIR}/util/mutexlock.h" "${PROJECT_SOURCE_DIR}/util/options.cc" - "${PROJECT_SOURCE_DIR}/util/posix_logger.h" "${PROJECT_SOURCE_DIR}/util/random.h" "${PROJECT_SOURCE_DIR}/util/status.cc" - $ # Only CMake 3.3+ supports PUBLIC sources in targets exported by "install". $<$:PUBLIC> @@ -195,12 +171,21 @@ target_sources(leveldb "${LEVELDB_PUBLIC_INCLUDE_DIR}/table.h" "${LEVELDB_PUBLIC_INCLUDE_DIR}/write_batch.h" ) + +# POSIX code is specified separately so we can leave it out in the future. +target_sources(leveldb + PRIVATE + "${PROJECT_SOURCE_DIR}/util/env_posix.cc" + "${PROJECT_SOURCE_DIR}/util/posix_logger.h" +) + # MemEnv is not part of the interface and could be pulled to a separate library. target_sources(leveldb PRIVATE "${PROJECT_SOURCE_DIR}/helpers/memenv/memenv.cc" "${PROJECT_SOURCE_DIR}/helpers/memenv/memenv.h" ) + target_include_directories(leveldb PUBLIC $ @@ -234,11 +219,6 @@ if(HAVE_CLANG_THREAD_SAFETY) -Werror -Wthread-safety) endif(HAVE_CLANG_THREAD_SAFETY) -# TODO(costan): This is only needed for port_posix. -set(THREADS_PREFER_PTHREAD_FLAG ON) -find_package(Threads REQUIRED) -target_link_libraries(leveldb Threads::Threads) - if(HAVE_CRC32C) target_link_libraries(leveldb crc32c) endif(HAVE_CRC32C) @@ -249,6 +229,10 @@ if(HAVE_TCMALLOC) target_link_libraries(leveldb tcmalloc) endif(HAVE_TCMALLOC) +# Needed by port_stdcxx.h +find_package(Threads REQUIRED) +target_link_libraries(leveldb Threads::Threads) + add_executable(leveldbutil "${PROJECT_SOURCE_DIR}/db/leveldbutil.cc" ) @@ -271,14 +255,6 @@ if(LEVELDB_BUILD_TESTS) "${test_file}" ) - if(BUILD_SHARED_LIBS) - # Port functions aren't exposed in the shared library build. - target_sources("${test_target_name}" - PRIVATE - $ - ) - endif(BUILD_SHARED_LIBS) - target_link_libraries("${test_target_name}" leveldb) target_compile_definitions("${test_target_name}" PRIVATE @@ -351,14 +327,6 @@ if(LEVELDB_BUILD_BENCHMARKS) "${bench_file}" ) - if(BUILD_SHARED_LIBS) - # Port functions aren't exposed in the shared library build. - target_sources("${bench_target_name}" - PRIVATE - $ - ) - endif(BUILD_SHARED_LIBS) - target_link_libraries("${bench_target_name}" leveldb) target_compile_definitions("${bench_target_name}" PRIVATE diff --git a/port/README b/port/README index 422563e..8b17153 100644 --- a/port/README +++ b/port/README @@ -5,6 +5,6 @@ Code in the rest of the package includes "port.h" from this directory. "port.h" in turn includes a platform specific "port_.h" file that provides the platform specific implementation. -See port_posix.h for an example of what must be provided in a platform +See port_stdcxx.h for an example of what must be provided in a platform specific header file. diff --git a/port/port.h b/port/port.h index e667db4..0975fed 100644 --- a/port/port.h +++ b/port/port.h @@ -11,7 +11,7 @@ // porting to a new platform, see "port_example.h" for documentation // of what the new port_.h file must provide. #if defined(LEVELDB_PLATFORM_POSIX) -# include "port/port_posix.h" +# include "port/port_stdcxx.h" #elif defined(LEVELDB_PLATFORM_CHROMIUM) # include "port/port_chromium.h" #endif diff --git a/port/port_posix.cc b/port/port_posix.cc deleted file mode 100644 index 04095bb..0000000 --- a/port/port_posix.cc +++ /dev/null @@ -1,53 +0,0 @@ -// 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. - -#include "port/port_posix.h" - -#include -#include -#include - -namespace leveldb { -namespace port { - -static void PthreadCall(const char* label, int result) { - if (result != 0) { - fprintf(stderr, "pthread %s: %s\n", label, strerror(result)); - abort(); - } -} - -Mutex::Mutex() { PthreadCall("init mutex", pthread_mutex_init(&mu_, nullptr)); } - -Mutex::~Mutex() { PthreadCall("destroy mutex", pthread_mutex_destroy(&mu_)); } - -void Mutex::Lock() { PthreadCall("lock", pthread_mutex_lock(&mu_)); } - -void Mutex::Unlock() { PthreadCall("unlock", pthread_mutex_unlock(&mu_)); } - -CondVar::CondVar(Mutex* mu) - : mu_(mu) { - PthreadCall("init cv", pthread_cond_init(&cv_, nullptr)); -} - -CondVar::~CondVar() { PthreadCall("destroy cv", pthread_cond_destroy(&cv_)); } - -void CondVar::Wait() { - PthreadCall("wait", pthread_cond_wait(&cv_, &mu_->mu_)); -} - -void CondVar::Signal() { - PthreadCall("signal", pthread_cond_signal(&cv_)); -} - -void CondVar::SignalAll() { - PthreadCall("broadcast", pthread_cond_broadcast(&cv_)); -} - -void InitOnce(OnceType* once, void (*initializer)()) { - PthreadCall("once", pthread_once(once, initializer)); -} - -} // namespace port -} // namespace leveldb diff --git a/port/port_posix.h b/port/port_stdcxx.h similarity index 62% rename from port/port_posix.h rename to port/port_stdcxx.h index 54b07b6..4e58cba 100644 --- a/port/port_posix.h +++ b/port/port_stdcxx.h @@ -1,11 +1,9 @@ -// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Copyright (c) 2018 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. -#ifndef STORAGE_LEVELDB_PORT_PORT_POSIX_H_ -#define STORAGE_LEVELDB_PORT_PORT_POSIX_H_ +#ifndef STORAGE_LEVELDB_PORT_PORT_STDCXX_H_ +#define STORAGE_LEVELDB_PORT_PORT_STDCXX_H_ // port/port_config.h availability is automatically detected via __has_include // in newer compilers. If LEVELDB_HAS_PORT_CONFIG_H is defined, it overrides the @@ -24,22 +22,22 @@ #endif // defined(LEVELDB_HAS_PORT_CONFIG_H) -#include #if HAVE_CRC32C #include #endif // HAVE_CRC32C #if HAVE_SNAPPY #include #endif // HAVE_SNAPPY + +#include #include +#include +#include // NOLINT +#include // NOLINT #include #include "port/atomic_pointer.h" #include "port/thread_annotations.h" -#if !HAVE_FDATASYNC -#define fdatasync fsync -#endif // !HAVE_FDATASYNC - namespace leveldb { namespace port { @@ -47,39 +45,52 @@ static const bool kLittleEndian = !LEVELDB_IS_BIG_ENDIAN; class CondVar; +// Thinly wraps std::mutex. class LOCKABLE Mutex { public: - Mutex(); - ~Mutex(); + Mutex() = default; + ~Mutex() = default; + + Mutex(const Mutex&) = delete; + Mutex& operator=(const Mutex&) = delete; - void Lock() EXCLUSIVE_LOCK_FUNCTION(); - void Unlock() UNLOCK_FUNCTION(); + void Lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.lock(); } + void Unlock() UNLOCK_FUNCTION() { mu_.unlock(); } void AssertHeld() ASSERT_EXCLUSIVE_LOCK() { } private: friend class CondVar; - pthread_mutex_t mu_; - - // No copying - Mutex(const Mutex&); - void operator=(const Mutex&); + std::mutex mu_; }; +// Thinly wraps std::condition_variable. class CondVar { public: - explicit CondVar(Mutex* mu); - ~CondVar(); - void Wait(); - void Signal(); - void SignalAll(); + explicit CondVar(Mutex* mu) : mu_(mu) { assert(mu != nullptr); } + ~CondVar() = default; + + CondVar(const CondVar&) = delete; + CondVar& operator=(const CondVar&) = delete; + + void Wait() { + std::unique_lock lock(mu_->mu_, std::adopt_lock); + cv_.wait(lock); + lock.release(); + } + void Signal() { cv_.notify_one(); } + void SignalAll() { cv_.notify_all(); } private: - pthread_cond_t cv_; - Mutex* mu_; + std::condition_variable cv_; + Mutex* const mu_; }; -typedef pthread_once_t OnceType; -#define LEVELDB_ONCE_INIT PTHREAD_ONCE_INIT -void InitOnce(OnceType* once, void (*initializer)()); +using OnceType = std::once_flag; +#define LEVELDB_ONCE_INIT {} + +// Thinly wraps std::call_once. +inline void InitOnce(OnceType* once, void (*initializer)()) { + std::call_once(*once, *initializer); +} inline bool Snappy_Compress(const char* input, size_t length, ::std::string* output) { @@ -103,8 +114,7 @@ inline bool Snappy_GetUncompressedLength(const char* input, size_t length, #endif // HAVE_SNAPPY } -inline bool Snappy_Uncompress(const char* input, size_t length, - char* output) { +inline bool Snappy_Uncompress(const char* input, size_t length, char* output) { #if HAVE_SNAPPY return snappy::RawUncompress(input, length, output); #else @@ -127,4 +137,4 @@ inline uint32_t AcceleratedCRC32C(uint32_t crc, const char* buf, size_t size) { } // namespace port } // namespace leveldb -#endif // STORAGE_LEVELDB_PORT_PORT_POSIX_H_ +#endif // STORAGE_LEVELDB_PORT_PORT_STDCXX_H_ diff --git a/util/env_posix.cc b/util/env_posix.cc index e758d5f..51844ad 100644 --- a/util/env_posix.cc +++ b/util/env_posix.cc @@ -28,6 +28,12 @@ #include "util/posix_logger.h" #include "util/env_posix_test_helper.h" +// HAVE_FDATASYNC is defined in the auto-generated port_config.h, which is +// included by port_stdcxx.h. +#if !HAVE_FDATASYNC +#define fdatasync fsync +#endif // !HAVE_FDATASYNC + namespace leveldb { namespace {