#include "InterruptableSleeper.h" namespace spovnet { namespace common { InterruptableSleeper::InterruptableSleeper() { boost::mutex::scoped_lock scopedLock(m_mutex); #ifdef WIN32 m_handle = CreateEvent (NULL, TRUE, FALSE, NULL); assert (m_handle != NULL); #else m_handle = new MUTEX_COND(); int ret = 0; ret = pthread_mutex_init(&(m_handle->mutex), NULL); assert (ret == 0); ret = pthread_cond_init(&(m_handle->cond), NULL); assert (ret == 0); #endif } InterruptableSleeper::~InterruptableSleeper() { boost::mutex::scoped_lock scopedLock(m_mutex); #ifdef WIN32 BOOL ret = CloseHandle (m_handle); assert (ret == TRUE); #else int ret = 0; ret = pthread_cond_destroy(&(m_handle->cond)); assert (ret == 0); ret = pthread_mutex_destroy(&(m_handle->mutex)); assert (ret == 0); delete m_handle; #endif } void InterruptableSleeper::interrupt() { boost::mutex::scoped_lock scopedLock(m_mutex); #ifdef WIN32 BOOL ret = SetEvent (m_handle); assert (ret == TRUE); #else int ret = pthread_cond_signal(&(m_handle)->cond); assert (ret == 0); #endif } void InterruptableSleeper::sleep(unsigned long millis) { // // NO mutex, otherwise the ::interrupt // function can not be called at all // #ifdef WIN32 DWORD dret = WaitForSingleObject (m_handle, millis); assert (dret != WAIT_FAILED); #else int ret; struct timespec tm; struct timeb tp; ret = pthread_mutex_lock(&(m_handle->mutex)); assert (ret == 0); long sec = millis / 1000; long millisec = millis % 1000; ftime(&tp); tp.time += sec; tp.millitm += millisec; if (tp.millitm > 999) { tp.millitm -= 1000; tp.time++; } tm.tv_sec = tp.time; tm.tv_nsec = tp.millitm * 1000000; ret = pthread_cond_timedwait(&(m_handle->cond), &(m_handle->mutex), &tm); assert (ret == 0 || ret == ETIMEDOUT); ret = pthread_mutex_unlock(&(m_handle->mutex)); assert (ret == 0); #endif // // under Windows we have to reset the event again // #ifdef WIN32 { boost::mutex::scoped_lock scopedLock (m_mutex); BOOL bret; bret = ResetEvent (m_handle); assert (bret == TRUE); } #endif } } } // namespace spovnet, common