|
a/libupnpp/workqueue.hxx |
|
b/libupnpp/workqueue.hxx |
|
... |
|
... |
21 |
#include <time.h>
|
21 |
#include <time.h>
|
22 |
|
22 |
|
23 |
#include <string>
|
23 |
#include <string>
|
24 |
#include <queue>
|
24 |
#include <queue>
|
25 |
#include <unordered_map>
|
25 |
#include <unordered_map>
|
26 |
#include <unordered_set>
|
|
|
27 |
using std::unordered_map;
|
|
|
28 |
using std::unordered_set;
|
|
|
29 |
using std::queue;
|
|
|
30 |
using std::string;
|
|
|
31 |
|
26 |
|
32 |
#include "ptmutex.hxx"
|
27 |
#include "ptmutex.hxx"
|
|
|
28 |
|
|
|
29 |
namespace UPnPP {
|
33 |
|
30 |
|
34 |
/// Store per-worker-thread data. Just an initialized timespec, and
|
31 |
/// Store per-worker-thread data. Just an initialized timespec, and
|
35 |
/// used at the moment.
|
32 |
/// used at the moment.
|
36 |
class WQTData {
|
33 |
class WQTData {
|
37 |
public:
|
34 |
public:
|
|
... |
|
... |
59 |
* @param name for message printing
|
56 |
* @param name for message printing
|
60 |
* @param hi number of tasks on queue before clients blocks. Default 0
|
57 |
* @param hi number of tasks on queue before clients blocks. Default 0
|
61 |
* meaning no limit. hi == -1 means that the queue is disabled.
|
58 |
* meaning no limit. hi == -1 means that the queue is disabled.
|
62 |
* @param lo minimum count of tasks before worker starts. Default 1.
|
59 |
* @param lo minimum count of tasks before worker starts. Default 1.
|
63 |
*/
|
60 |
*/
|
64 |
WorkQueue(const string& name, size_t hi = 0, size_t lo = 1)
|
61 |
WorkQueue(const std::string& name, size_t hi = 0, size_t lo = 1)
|
65 |
: m_name(name), m_high(hi), m_low(lo),
|
62 |
: m_name(name), m_high(hi), m_low(lo),
|
66 |
m_workers_exited(0), m_clients_waiting(0), m_workers_waiting(0),
|
63 |
m_workers_exited(0), m_clients_waiting(0), m_workers_waiting(0),
|
67 |
m_tottasks(0), m_nowake(0), m_workersleeps(0), m_clientsleeps(0)
|
64 |
m_tottasks(0), m_nowake(0), m_workersleeps(0), m_clientsleeps(0)
|
68 |
{
|
65 |
{
|
69 |
m_ok = (pthread_cond_init(&m_ccond, 0) == 0) &&
|
66 |
m_ok = (pthread_cond_init(&m_ccond, 0) == 0) &&
|
|
... |
|
... |
201 |
}
|
198 |
}
|
202 |
|
199 |
|
203 |
// Perform the thread joins and compute overall status
|
200 |
// Perform the thread joins and compute overall status
|
204 |
// Workers return (void*)1 if ok
|
201 |
// Workers return (void*)1 if ok
|
205 |
void *statusall = (void*)1;
|
202 |
void *statusall = (void*)1;
|
206 |
unordered_map<pthread_t, WQTData>::iterator it;
|
203 |
std::unordered_map<pthread_t, WQTData>::iterator it;
|
207 |
while (!m_worker_threads.empty()) {
|
204 |
while (!m_worker_threads.empty()) {
|
208 |
void *status;
|
205 |
void *status;
|
209 |
it = m_worker_threads.begin();
|
206 |
it = m_worker_threads.begin();
|
210 |
pthread_join(it->first, &status);
|
207 |
pthread_join(it->first, &status);
|
211 |
if (status == (void *)0)
|
208 |
if (status == (void *)0)
|
|
... |
|
... |
295 |
return (newer.tv_sec - older.tv_sec) * 1000000000LL
|
292 |
return (newer.tv_sec - older.tv_sec) * 1000000000LL
|
296 |
+ newer.tv_nsec - older.tv_nsec;
|
293 |
+ newer.tv_nsec - older.tv_nsec;
|
297 |
}
|
294 |
}
|
298 |
|
295 |
|
299 |
// Configuration
|
296 |
// Configuration
|
300 |
string m_name;
|
297 |
std::string m_name;
|
301 |
size_t m_high;
|
298 |
size_t m_high;
|
302 |
size_t m_low;
|
299 |
size_t m_low;
|
303 |
|
300 |
|
304 |
// Status
|
301 |
// Status
|
305 |
// Worker threads having called exit
|
302 |
// Worker threads having called exit
|
306 |
unsigned int m_workers_exited;
|
303 |
unsigned int m_workers_exited;
|
307 |
bool m_ok;
|
304 |
bool m_ok;
|
308 |
|
305 |
|
309 |
// Per-thread data. The data is not used currently, this could be
|
306 |
// Per-thread data. The data is not used currently, this could be
|
310 |
// a set<pthread_t>
|
307 |
// a set<pthread_t>
|
311 |
unordered_map<pthread_t, WQTData> m_worker_threads;
|
308 |
std::unordered_map<pthread_t, WQTData> m_worker_threads;
|
312 |
|
309 |
|
313 |
// Synchronization
|
310 |
// Synchronization
|
314 |
queue<T> m_queue;
|
311 |
std::queue<T> m_queue;
|
315 |
pthread_cond_t m_ccond;
|
312 |
pthread_cond_t m_ccond;
|
316 |
pthread_cond_t m_wcond;
|
313 |
pthread_cond_t m_wcond;
|
317 |
PTMutexInit m_mutex;
|
314 |
PTMutexInit m_mutex;
|
318 |
// Client/Worker threads currently waiting for a job
|
315 |
// Client/Worker threads currently waiting for a job
|
319 |
unsigned int m_clients_waiting;
|
316 |
unsigned int m_clients_waiting;
|
|
... |
|
... |
324 |
unsigned int m_nowake;
|
321 |
unsigned int m_nowake;
|
325 |
unsigned int m_workersleeps;
|
322 |
unsigned int m_workersleeps;
|
326 |
unsigned int m_clientsleeps;
|
323 |
unsigned int m_clientsleeps;
|
327 |
};
|
324 |
};
|
328 |
|
325 |
|
|
|
326 |
} // namespace
|
|
|
327 |
|
329 |
#endif /* _WORKQUEUE_H_INCLUDED_ */
|
328 |
#endif /* _WORKQUEUE_H_INCLUDED_ */
|