Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
751};753port::Mutex background_work_mutex_;754port::CondVar background_work_cv_ GUARDED_BY(background_work_mutex_);755bool started_background_thread_ GUARDED_BY(background_work_mutex_);757std::queue<BackgroundWorkItem> background_work_queue_758GUARDED_BY(background_work_mutex_);760PosixLockTable locks_; // Thread-safe.761Limiter mmap_limiter_; // Thread-safe.762Limiter fd_limiter_; // Thread-safe.763};765// Return the maximum number of concurrent mmaps.766int MaxMmaps() { return g_mmap_limit; }768// Return the maximum number of read-only files to keep open.769int MaxOpenFiles() {770if (g_open_read_only_file_limit >= 0) {771return g_open_read_only_file_limit;772}773struct ::rlimit rlim;774if (::getrlimit(RLIMIT_NOFILE, &rlim)) {775// getrlimit failed, fallback to hard-coded default.776g_open_read_only_file_limit = 50;777} else if (rlim.rlim_cur == RLIM_INFINITY) {778g_open_read_only_file_limit = std::numeric_limits<int>::max();779} else {780// Allow use of 20% of available file descriptors for read-only files.781g_open_read_only_file_limit = rlim.rlim_cur / 5;782}783return g_open_read_only_file_limit;784}786} // namespace788PosixEnv::PosixEnv()789: background_work_cv_(&background_work_mutex_),790started_background_thread_(false),791mmap_limiter_(MaxMmaps()),792fd_limiter_(MaxOpenFiles()) {}794void PosixEnv::Schedule(795void (*background_work_function)(void* background_work_arg),796void* background_work_arg) {797background_work_mutex_.Lock();799// Start the background thread, if we haven't done so already.800if (!started_background_thread_) {801started_background_thread_ = true;802std::thread background_thread(PosixEnv::BackgroundThreadEntryPoint, this);803background_thread.detach();804}806// If the queue is empty, the background thread may be waiting for work.807if (background_work_queue_.empty()) {808background_work_cv_.Signal();809}811background_work_queue_.emplace(background_work_function, background_work_arg);812background_work_mutex_.Unlock();813}815void PosixEnv::BackgroundThreadMain() {816while (true) {817background_work_mutex_.Lock();819// Wait until there is work to be done.820while (background_work_queue_.empty()) {821background_work_cv_.Wait();822}824assert(!background_work_queue_.empty());825auto background_work_function = background_work_queue_.front().function;826void* background_work_arg = background_work_queue_.front().arg;827background_work_queue_.pop();829background_work_mutex_.Unlock();830background_work_function(background_work_arg);831}832}834namespace {836// Wraps an Env instance whose destructor is never created.837//838// Intended usage:839// using PlatformSingletonEnv = SingletonEnv<PlatformEnv>;840// void ConfigurePosixEnv(int param) {841// PlatformSingletonEnv::AssertEnvNotInitialized();842// // set global configuration flags.843// }844// Env* Env::Default() {845// static PlatformSingletonEnv default_env;846// return default_env.env();847// }848template <typename EnvType>849class SingletonEnv {850public:851SingletonEnv() {852#if !defined(NDEBUG)853env_initialized_.store(true, std::memory_order_relaxed);854#endif // !defined(NDEBUG)855static_assert(sizeof(env_storage_) >= sizeof(EnvType),856"env_storage_ will not fit the Env");857static_assert(std::is_standard_layout_v<SingletonEnv<EnvType>>);858static_assert(859offsetof(SingletonEnv<EnvType>, env_storage_) % alignof(EnvType) == 0,860"env_storage_ does not meet the Env's alignment needs");861static_assert(alignof(SingletonEnv<EnvType>) % alignof(EnvType) == 0,862"env_storage_ does not meet the Env's alignment needs");863new (env_storage_) EnvType();864}865~SingletonEnv() = default;867SingletonEnv(const SingletonEnv&) = delete;868SingletonEnv& operator=(const SingletonEnv&) = delete;870Env* env() { return reinterpret_cast<Env*>(&env_storage_); }872static void AssertEnvNotInitialized() {873#if !defined(NDEBUG)874assert(!env_initialized_.load(std::memory_order_relaxed));875#endif // !defined(NDEBUG)876}878private:879alignas(EnvType) char env_storage_[sizeof(EnvType)];880#if !defined(NDEBUG)881static std::atomic<bool> env_initialized_;882#endif // !defined(NDEBUG)883};885#if !defined(NDEBUG)886template <typename EnvType>887std::atomic<bool> SingletonEnv<EnvType>::env_initialized_;888#endif // !defined(NDEBUG)890using PosixDefaultEnv = SingletonEnv<PosixEnv>;892} // namespace894void EnvPosixTestHelper::SetReadOnlyFDLimit(int limit) {895PosixDefaultEnv::AssertEnvNotInitialized();896g_open_read_only_file_limit = limit;897}899void EnvPosixTestHelper::SetReadOnlyMMapLimit(int limit) {900PosixDefaultEnv::AssertEnvNotInitialized();901g_mmap_limit = limit;902}904Env* Env::Default() {905static PosixDefaultEnv env_container;906return env_container.env();907}909} // namespace leveldb
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.