148 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C++
		
	
	
	
		
		
			
		
	
	
			148 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C++
		
	
	
	
|  | //
 | ||
|  | // detail/win_thread.hpp
 | ||
|  | // ~~~~~~~~~~~~~~~~~~~~~
 | ||
|  | //
 | ||
|  | // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 | ||
|  | //
 | ||
|  | // Distributed under the Boost Software License, Version 1.0. (See accompanying
 | ||
|  | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | ||
|  | //
 | ||
|  | 
 | ||
|  | #ifndef ASIO_DETAIL_WIN_THREAD_HPP
 | ||
|  | #define ASIO_DETAIL_WIN_THREAD_HPP
 | ||
|  | 
 | ||
|  | #if defined(_MSC_VER) && (_MSC_VER >= 1200)
 | ||
|  | # pragma once
 | ||
|  | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 | ||
|  | 
 | ||
|  | #include "asio/detail/config.hpp"
 | ||
|  | 
 | ||
|  | #if defined(ASIO_WINDOWS) \
 | ||
|  |   && !defined(ASIO_WINDOWS_APP) \ | ||
|  |   && !defined(UNDER_CE) | ||
|  | 
 | ||
|  | #include <cstddef>
 | ||
|  | #include "asio/detail/noncopyable.hpp"
 | ||
|  | #include "asio/detail/socket_types.hpp"
 | ||
|  | 
 | ||
|  | #include "asio/detail/push_options.hpp"
 | ||
|  | 
 | ||
|  | namespace asio { | ||
|  | namespace detail { | ||
|  | 
 | ||
|  | ASIO_DECL unsigned int __stdcall win_thread_function(void* arg); | ||
|  | 
 | ||
|  | #if defined(WINVER) && (WINVER < 0x0500)
 | ||
|  | ASIO_DECL void __stdcall apc_function(ULONG data); | ||
|  | #else
 | ||
|  | ASIO_DECL void __stdcall apc_function(ULONG_PTR data); | ||
|  | #endif
 | ||
|  | 
 | ||
|  | template <typename T> | ||
|  | class win_thread_base | ||
|  | { | ||
|  | public: | ||
|  |   static bool terminate_threads() | ||
|  |   { | ||
|  |     return ::InterlockedExchangeAdd(&terminate_threads_, 0) != 0; | ||
|  |   } | ||
|  | 
 | ||
|  |   static void set_terminate_threads(bool b) | ||
|  |   { | ||
|  |     ::InterlockedExchange(&terminate_threads_, b ? 1 : 0); | ||
|  |   } | ||
|  | 
 | ||
|  | private: | ||
|  |   static long terminate_threads_; | ||
|  | }; | ||
|  | 
 | ||
|  | template <typename T> | ||
|  | long win_thread_base<T>::terminate_threads_ = 0; | ||
|  | 
 | ||
|  | class win_thread | ||
|  |   : private noncopyable, | ||
|  |     public win_thread_base<win_thread> | ||
|  | { | ||
|  | public: | ||
|  |   // Constructor.
 | ||
|  |   template <typename Function> | ||
|  |   win_thread(Function f, unsigned int stack_size = 0) | ||
|  |     : thread_(0), | ||
|  |       exit_event_(0) | ||
|  |   { | ||
|  |     start_thread(new func<Function>(f), stack_size); | ||
|  |   } | ||
|  | 
 | ||
|  |   // Destructor.
 | ||
|  |   ASIO_DECL ~win_thread(); | ||
|  | 
 | ||
|  |   // Wait for the thread to exit.
 | ||
|  |   ASIO_DECL void join(); | ||
|  | 
 | ||
|  |   // Get number of CPUs.
 | ||
|  |   ASIO_DECL static std::size_t hardware_concurrency(); | ||
|  | 
 | ||
|  | private: | ||
|  |   friend ASIO_DECL unsigned int __stdcall win_thread_function(void* arg); | ||
|  | 
 | ||
|  | #if defined(WINVER) && (WINVER < 0x0500)
 | ||
|  |   friend ASIO_DECL void __stdcall apc_function(ULONG); | ||
|  | #else
 | ||
|  |   friend ASIO_DECL void __stdcall apc_function(ULONG_PTR); | ||
|  | #endif
 | ||
|  | 
 | ||
|  |   class func_base | ||
|  |   { | ||
|  |   public: | ||
|  |     virtual ~func_base() {} | ||
|  |     virtual void run() = 0; | ||
|  |     ::HANDLE entry_event_; | ||
|  |     ::HANDLE exit_event_; | ||
|  |   }; | ||
|  | 
 | ||
|  |   struct auto_func_base_ptr | ||
|  |   { | ||
|  |     func_base* ptr; | ||
|  |     ~auto_func_base_ptr() { delete ptr; } | ||
|  |   }; | ||
|  | 
 | ||
|  |   template <typename Function> | ||
|  |   class func | ||
|  |     : public func_base | ||
|  |   { | ||
|  |   public: | ||
|  |     func(Function f) | ||
|  |       : f_(f) | ||
|  |     { | ||
|  |     } | ||
|  | 
 | ||
|  |     virtual void run() | ||
|  |     { | ||
|  |       f_(); | ||
|  |     } | ||
|  | 
 | ||
|  |   private: | ||
|  |     Function f_; | ||
|  |   }; | ||
|  | 
 | ||
|  |   ASIO_DECL void start_thread(func_base* arg, unsigned int stack_size); | ||
|  | 
 | ||
|  |   ::HANDLE thread_; | ||
|  |   ::HANDLE exit_event_; | ||
|  | }; | ||
|  | 
 | ||
|  | } // namespace detail
 | ||
|  | } // namespace asio
 | ||
|  | 
 | ||
|  | #include "asio/detail/pop_options.hpp"
 | ||
|  | 
 | ||
|  | #if defined(ASIO_HEADER_ONLY)
 | ||
|  | # include "asio/detail/impl/win_thread.ipp"
 | ||
|  | #endif // defined(ASIO_HEADER_ONLY)
 | ||
|  | 
 | ||
|  | #endif // defined(ASIO_WINDOWS)
 | ||
|  |        // && !defined(ASIO_WINDOWS_APP)
 | ||
|  |        // && !defined(UNDER_CE)
 | ||
|  | 
 | ||
|  | #endif // ASIO_DETAIL_WIN_THREAD_HPP
 |