]>
Commit | Line | Data |
---|---|---|
9540fc59 CF |
1 | /* threaded_queue.h |
2 | ||
9540fc59 CF |
3 | Written by Robert Collins <rbtcollins@hotmail.com> |
4 | ||
5 | This file is part of Cygwin. | |
6 | ||
7 | This software is a copyrighted work licensed under the terms of the | |
8 | Cygwin license. Please consult the file "CYGWIN_LICENSE" for | |
9 | details. */ | |
10 | ||
11 | #ifndef _THREADED_QUEUE_ | |
12 | #define _THREADED_QUEUE_ | |
13 | ||
14 | /*****************************************************************************/ | |
15 | ||
16 | /* a specific request */ | |
17 | ||
18 | class queue_request | |
19 | { | |
20 | public: | |
21 | queue_request *_next; | |
22 | ||
23 | queue_request () : _next (NULL) {} | |
24 | virtual ~queue_request (); | |
25 | ||
26 | virtual void process () = 0; | |
27 | }; | |
28 | ||
29 | /*****************************************************************************/ | |
30 | ||
31 | /* a queue to allocate requests from n submission loops to x worker threads */ | |
32 | ||
33 | class queue_submission_loop; | |
34 | ||
35 | class threaded_queue | |
36 | { | |
37 | public: | |
38 | threaded_queue (size_t initial_workers = 1); | |
39 | ~threaded_queue (); | |
40 | ||
41 | void add_submission_loop (queue_submission_loop *); | |
42 | ||
43 | bool running () const { return _running; } | |
44 | ||
45 | bool start (); | |
46 | bool stop (); | |
47 | ||
48 | void add (queue_request *); | |
49 | ||
50 | private: | |
61522196 | 51 | LONG _workers_count; |
0b73dba4 | 52 | LONG _workers_busy; |
9540fc59 CF |
53 | bool _running; |
54 | ||
55 | queue_submission_loop *_submitters_head; | |
56 | ||
57 | long _requests_count; // Informational only. | |
58 | queue_request *_requests_head; | |
59 | ||
60 | CRITICAL_SECTION _queue_lock; | |
61 | HANDLE _requests_sem; // == _requests_count | |
62 | ||
63 | static DWORD WINAPI start_routine (LPVOID /* this */); | |
64 | ||
65 | void create_workers (size_t initial_workers); | |
66 | void worker_loop (); | |
67 | }; | |
68 | ||
69 | /*****************************************************************************/ | |
70 | ||
71 | /* parameters for a request finding and submitting loop */ | |
72 | ||
73 | class queue_submission_loop | |
74 | { | |
75 | friend class threaded_queue; | |
76 | ||
77 | public: | |
78 | queue_submission_loop (threaded_queue *, bool ninterruptible); | |
79 | virtual ~queue_submission_loop (); | |
80 | ||
81 | bool start (); | |
82 | bool stop (); | |
83 | ||
84 | threaded_queue *queue () { return _queue; }; | |
85 | ||
86 | protected: | |
87 | bool _running; | |
88 | HANDLE _interrupt_event; | |
89 | threaded_queue *const _queue; | |
90 | ||
91 | private: | |
92 | bool _interruptible; | |
93 | HANDLE _hThread; | |
94 | DWORD _tid; | |
95 | queue_submission_loop *_next; | |
96 | ||
97 | static DWORD WINAPI start_routine (LPVOID /* this */); | |
98 | virtual void request_loop () = 0; | |
99 | }; | |
100 | ||
101 | #ifdef __cplusplus | |
102 | ||
103 | /*---------------------------------------------------------------------------* | |
104 | * Some type-safe versions of the various interlocked functions. | |
105 | *---------------------------------------------------------------------------*/ | |
106 | ||
107 | template <typename T> T * | |
108 | TInterlockedExchangePointer (T **lvalue, T *rvalue) | |
109 | { | |
110 | return reinterpret_cast<T *> | |
111 | (InterlockedExchangePointer (reinterpret_cast<void **> (lvalue), | |
112 | reinterpret_cast<void *> (rvalue))); | |
113 | } | |
114 | ||
115 | template <typename T> T * | |
116 | TInterlockedCompareExchangePointer (T **lvalue, T *rvalue1, T *rvalue2) | |
117 | { | |
118 | return reinterpret_cast<T *> | |
119 | (InterlockedCompareExchangePointer (reinterpret_cast<void **> (lvalue), | |
120 | reinterpret_cast<void *> (rvalue1), | |
121 | reinterpret_cast<void *> (rvalue2))); | |
122 | } | |
123 | ||
124 | #endif /* __cplusplus */ | |
125 | ||
126 | #endif /* _THREADED_QUEUE_ */ |