gvox-sys 1.3.0

Voxel file format parser
Documentation
#pragma once

#include <functional>

#define ENABLE_THREAD_POOL (GVOX_ENABLE_MULTITHREADED_ADAPTERS && GVOX_ENABLE_THREADSAFETY)

#if ENABLE_THREAD_POOL
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#endif

namespace gvox_detail::thread_pool {
    struct ThreadPool {
        void start() {
#if ENABLE_THREAD_POOL
            uint32_t const num_threads = std::thread::hardware_concurrency();
            threads.resize(num_threads);
            for (uint32_t i = 0; i < num_threads; i++) {
                threads.at(i) = std::thread(&ThreadPool::thread_loop, this);
            }
#endif
        }
        void enqueue(std::function<void()> const &job) {
#if ENABLE_THREAD_POOL
            {
                std::unique_lock<std::mutex> lock(queue_mutex);
                jobs.push(job);
            }
            mutex_condition.notify_one();
#else
            job();
#endif
        }
        void stop() {
#if ENABLE_THREAD_POOL
            {
                std::unique_lock<std::mutex> lock(queue_mutex);
                should_terminate = true;
            }
            mutex_condition.notify_all();
            for (std::thread &active_thread : threads) {
                active_thread.join();
            }
            threads.clear();
#endif
        }
        auto busy() -> bool {
#if ENABLE_THREAD_POOL
            bool pool_busy;
            {
                std::unique_lock<std::mutex> lock(queue_mutex);
                pool_busy = !jobs.empty();
            }
            return pool_busy;
#else
            return false;
#endif
        }

      private:
        void thread_loop() {
#if ENABLE_THREAD_POOL
            while (true) {
                std::function<void()> job;
                {
                    std::unique_lock<std::mutex> lock(queue_mutex);
                    mutex_condition.wait(lock, [this] {
                        return !jobs.empty() || should_terminate;
                    });
                    if (should_terminate) {
                        return;
                    }
                    job = jobs.front();
                    jobs.pop();
                }
                job();
            }
#endif
        }
#if ENABLE_THREAD_POOL
        bool should_terminate = false;
        std::mutex queue_mutex;
        std::condition_variable mutex_condition;
        std::vector<std::thread> threads;
        std::queue<std::function<void()>> jobs;
#endif
    };
} // namespace gvox_detail::thread_pool