| /* threaded_queue.h |
| |
| Written by Robert Collins <rbtcollins@hotmail.com> |
| |
| This file is part of Cygwin. |
| |
| This software is a copyrighted work licensed under the terms of the |
| Cygwin license. Please consult the file "CYGWIN_LICENSE" for |
| details. */ |
| |
| #ifndef _THREADED_QUEUE_ |
| #define _THREADED_QUEUE_ |
| |
| /*****************************************************************************/ |
| |
| /* a specific request */ |
| |
| class queue_request |
| { |
| public: |
| queue_request *_next; |
| |
| queue_request () : _next (NULL) {} |
| virtual ~queue_request (); |
| |
| virtual void process () = 0; |
| }; |
| |
| /*****************************************************************************/ |
| |
| /* a queue to allocate requests from n submission loops to x worker threads */ |
| |
| class queue_submission_loop; |
| |
| class threaded_queue |
| { |
| public: |
| threaded_queue (size_t initial_workers = 1); |
| ~threaded_queue (); |
| |
| void add_submission_loop (queue_submission_loop *); |
| |
| bool running () const { return _running; } |
| |
| bool start (); |
| bool stop (); |
| |
| void add (queue_request *); |
| |
| private: |
| LONG _workers_count; |
| LONG _workers_busy; |
| bool _running; |
| |
| queue_submission_loop *_submitters_head; |
| |
| long _requests_count; // Informational only. |
| queue_request *_requests_head; |
| |
| CRITICAL_SECTION _queue_lock; |
| HANDLE _requests_sem; // == _requests_count |
| |
| static DWORD WINAPI start_routine (LPVOID /* this */); |
| |
| void create_workers (size_t initial_workers); |
| void worker_loop (); |
| }; |
| |
| /*****************************************************************************/ |
| |
| /* parameters for a request finding and submitting loop */ |
| |
| class queue_submission_loop |
| { |
| friend class threaded_queue; |
| |
| public: |
| queue_submission_loop (threaded_queue *, bool ninterruptible); |
| virtual ~queue_submission_loop (); |
| |
| bool start (); |
| bool stop (); |
| |
| threaded_queue *queue () { return _queue; }; |
| |
| protected: |
| bool _running; |
| HANDLE _interrupt_event; |
| threaded_queue *const _queue; |
| |
| private: |
| bool _interruptible; |
| HANDLE _hThread; |
| DWORD _tid; |
| queue_submission_loop *_next; |
| |
| static DWORD WINAPI start_routine (LPVOID /* this */); |
| virtual void request_loop () = 0; |
| }; |
| |
| #ifdef __cplusplus |
| |
| /*---------------------------------------------------------------------------* |
| * Some type-safe versions of the various interlocked functions. |
| *---------------------------------------------------------------------------*/ |
| |
| template <typename T> T * |
| TInterlockedExchangePointer (T **lvalue, T *rvalue) |
| { |
| return reinterpret_cast<T *> |
| (InterlockedExchangePointer (reinterpret_cast<void **> (lvalue), |
| reinterpret_cast<void *> (rvalue))); |
| } |
| |
| template <typename T> T * |
| TInterlockedCompareExchangePointer (T **lvalue, T *rvalue1, T *rvalue2) |
| { |
| return reinterpret_cast<T *> |
| (InterlockedCompareExchangePointer (reinterpret_cast<void **> (lvalue), |
| reinterpret_cast<void *> (rvalue1), |
| reinterpret_cast<void *> (rvalue2))); |
| } |
| |
| #endif /* __cplusplus */ |
| |
| #endif /* _THREADED_QUEUE_ */ |