1 | #include "InterruptableSleeper.h"
|
---|
2 |
|
---|
3 | namespace spovnet {
|
---|
4 | namespace common {
|
---|
5 |
|
---|
6 | InterruptableSleeper::InterruptableSleeper() {
|
---|
7 | boost::mutex::scoped_lock scopedLock(m_mutex);
|
---|
8 |
|
---|
9 | #ifdef WIN32
|
---|
10 | m_handle = CreateEvent (NULL, TRUE, FALSE, NULL);
|
---|
11 | assert (m_handle != NULL);
|
---|
12 | #else
|
---|
13 | m_handle = new MUTEX_COND();
|
---|
14 | int ret = 0;
|
---|
15 |
|
---|
16 | ret = pthread_mutex_init(&(m_handle->mutex), NULL);
|
---|
17 | assert (ret == 0);
|
---|
18 |
|
---|
19 | ret = pthread_cond_init(&(m_handle->cond), NULL);
|
---|
20 | assert (ret == 0);
|
---|
21 | #endif
|
---|
22 | }
|
---|
23 |
|
---|
24 | InterruptableSleeper::~InterruptableSleeper() {
|
---|
25 | boost::mutex::scoped_lock scopedLock(m_mutex);
|
---|
26 |
|
---|
27 | #ifdef WIN32
|
---|
28 | BOOL ret = CloseHandle (m_handle);
|
---|
29 | assert (ret == TRUE);
|
---|
30 | #else
|
---|
31 | int ret = 0;
|
---|
32 |
|
---|
33 | ret = pthread_cond_destroy(&(m_handle->cond));
|
---|
34 | assert (ret == 0);
|
---|
35 |
|
---|
36 | ret = pthread_mutex_destroy(&(m_handle->mutex));
|
---|
37 | assert (ret == 0);
|
---|
38 |
|
---|
39 | delete m_handle;
|
---|
40 | #endif
|
---|
41 | }
|
---|
42 |
|
---|
43 | void InterruptableSleeper::interrupt() {
|
---|
44 | boost::mutex::scoped_lock scopedLock(m_mutex);
|
---|
45 |
|
---|
46 | #ifdef WIN32
|
---|
47 | BOOL ret = SetEvent (m_handle);
|
---|
48 | assert (ret == TRUE);
|
---|
49 | #else
|
---|
50 | int ret = pthread_cond_signal(&(m_handle)->cond);
|
---|
51 | assert (ret == 0);
|
---|
52 | #endif
|
---|
53 | }
|
---|
54 |
|
---|
55 | void InterruptableSleeper::sleep(unsigned long millis) {
|
---|
56 | //
|
---|
57 | // NO mutex, otherwise the ::interrupt
|
---|
58 | // function can not be called at all
|
---|
59 | //
|
---|
60 |
|
---|
61 | #ifdef WIN32
|
---|
62 |
|
---|
63 | DWORD dret = WaitForSingleObject (m_handle, millis);
|
---|
64 | assert (dret != WAIT_FAILED);
|
---|
65 |
|
---|
66 | #else
|
---|
67 |
|
---|
68 | int ret;
|
---|
69 | struct timespec tm;
|
---|
70 | struct timeb tp;
|
---|
71 |
|
---|
72 | ret = pthread_mutex_lock(&(m_handle->mutex));
|
---|
73 | assert (ret == 0);
|
---|
74 |
|
---|
75 | long sec = millis / 1000;
|
---|
76 | long millisec = millis % 1000;
|
---|
77 |
|
---|
78 | ftime(&tp);
|
---|
79 | tp.time += sec;
|
---|
80 | tp.millitm += millisec;
|
---|
81 |
|
---|
82 | if (tp.millitm > 999) {
|
---|
83 | tp.millitm -= 1000;
|
---|
84 | tp.time++;
|
---|
85 | }
|
---|
86 |
|
---|
87 | tm.tv_sec = tp.time;
|
---|
88 | tm.tv_nsec = tp.millitm * 1000000;
|
---|
89 |
|
---|
90 | ret = pthread_cond_timedwait(&(m_handle->cond), &(m_handle->mutex), &tm);
|
---|
91 | assert (ret == 0 || ret == ETIMEDOUT);
|
---|
92 |
|
---|
93 | ret = pthread_mutex_unlock(&(m_handle->mutex));
|
---|
94 | assert (ret == 0);
|
---|
95 |
|
---|
96 | #endif
|
---|
97 |
|
---|
98 | //
|
---|
99 | // under Windows we have to reset the event again
|
---|
100 | //
|
---|
101 |
|
---|
102 | #ifdef WIN32
|
---|
103 | {
|
---|
104 | boost::mutex::scoped_lock scopedLock (m_mutex);
|
---|
105 | BOOL bret;
|
---|
106 | bret = ResetEvent (m_handle);
|
---|
107 | assert (bret == TRUE);
|
---|
108 | }
|
---|
109 | #endif
|
---|
110 | }
|
---|
111 | }
|
---|
112 | } // namespace spovnet, common
|
---|