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