// Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef PLATFORM_IMPL_WINDOWS_THREAD_POOL_H_ #define PLATFORM_IMPL_WINDOWS_THREAD_POOL_H_ #include #include #include #include #include #include "platform/impl/windows/runner.h" namespace location { namespace nearby { namespace windows { class ThreadPoolException : public std::runtime_error { public: ThreadPoolException() : std::runtime_error("") {} ThreadPoolException(const std::string& message) : std::runtime_error(message) {} virtual const char* what() const throw() { return "ThreadPool creation failed"; } }; // all functions passed in by clients will be initially stored in this list. typedef std::list> FunctionList; // info about threads in the pool will be saved using this struct. typedef struct tagThreadData { bool free; HANDLE wait_handle; HANDLE thread_handle; DWORD thread_id; } ThreadData; // info about all threads belonging to this pool will be stored in this map typedef std::map, std::allocator>> ThreadMap; enum class State { Ready, // has been created Destroying, // in the process of getting destroyed, no request is processed / // accepted Destroyed // Destroyed, no threads are available, request can still be queued }; class ThreadPool { public: ThreadPool(int nPoolSize, bool bCreateNow); virtual ~ThreadPool(); bool Create(); // creates the thread pool void Destroy(); // destroy the thread pool int GetPoolSize(); void SetPoolSize(int); bool Run(std::unique_ptr runObject); bool CheckThreadStop(); int GetWorkingThreadCount(); State GetState(); private: static DWORD WINAPI _ThreadProc(LPVOID); std::unique_ptr function_list_; std::unique_ptr thread_map_; HANDLE* thread_handles_ = nullptr; int pool_size_; int wait_for_threads_to_die_ms_; // In milli-seconds std::string pool_name_; // To assist in logging and debug HANDLE notify_shutdown_; // notifies threads that a new function // is added volatile State pool_state_; static __declspec( align(8)) volatile long instance_; // NOLINT Windows function takes // volatile long CRITICAL_SECTION critical_section_; bool GetThreadProc(DWORD dwThreadId, std::unique_ptr&& runner); void FinishNotify(DWORD dwThreadId); void BusyNotify(DWORD dwThreadId); void ReleaseMemory(); HANDLE GetWaitHandle(DWORD dwThreadId); HANDLE GetShutdownHandle(); void AddRunner(std::unique_ptr runner); }; } // namespace windows } // namespace nearby } // namespace location #endif // PLATFORM_IMPL_WINDOWS_THREAD_POOL_H_