Event_POSIX.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. //
  2. // Event_POSIX.cpp
  3. //
  4. // $Id: //poco/1.4/Foundation/src/Event_POSIX.cpp#3 $
  5. //
  6. // Library: Foundation
  7. // Package: Threading
  8. // Module: Event
  9. //
  10. // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
  11. // and Contributors.
  12. //
  13. // SPDX-License-Identifier: BSL-1.0
  14. //
  15. #include "Poco/Event_POSIX.h"
  16. #if defined(POCO_VXWORKS)
  17. #include <timers.h>
  18. #include <cstring>
  19. #else
  20. #include <sys/time.h>
  21. #endif
  22. namespace Poco {
  23. EventImpl::EventImpl(bool autoReset): _auto(autoReset), _state(false)
  24. {
  25. #if defined(POCO_VXWORKS)
  26. // This workaround is for VxWorks 5.x where
  27. // pthread_mutex_init() won't properly initialize the mutex
  28. // resulting in a subsequent freeze in pthread_mutex_destroy()
  29. // if the mutex has never been used.
  30. std::memset(&_mutex, 0, sizeof(_mutex));
  31. #endif
  32. if (pthread_mutex_init(&_mutex, NULL))
  33. throw SystemException("cannot create event (mutex)");
  34. if (pthread_cond_init(&_cond, NULL))
  35. throw SystemException("cannot create event (condition)");
  36. }
  37. EventImpl::~EventImpl()
  38. {
  39. pthread_cond_destroy(&_cond);
  40. pthread_mutex_destroy(&_mutex);
  41. }
  42. void EventImpl::waitImpl()
  43. {
  44. if (pthread_mutex_lock(&_mutex))
  45. throw SystemException("wait for event failed (lock)");
  46. while (!_state)
  47. {
  48. if (pthread_cond_wait(&_cond, &_mutex))
  49. {
  50. pthread_mutex_unlock(&_mutex);
  51. throw SystemException("wait for event failed");
  52. }
  53. }
  54. if (_auto)
  55. _state = false;
  56. pthread_mutex_unlock(&_mutex);
  57. }
  58. bool EventImpl::waitImpl(long milliseconds)
  59. {
  60. int rc = 0;
  61. struct timespec abstime;
  62. #if defined(__VMS)
  63. struct timespec delta;
  64. delta.tv_sec = milliseconds / 1000;
  65. delta.tv_nsec = (milliseconds % 1000)*1000000;
  66. pthread_get_expiration_np(&delta, &abstime);
  67. #elif defined(POCO_VXWORKS)
  68. clock_gettime(CLOCK_REALTIME, &abstime);
  69. abstime.tv_sec += milliseconds / 1000;
  70. abstime.tv_nsec += (milliseconds % 1000)*1000000;
  71. if (abstime.tv_nsec >= 1000000000)
  72. {
  73. abstime.tv_nsec -= 1000000000;
  74. abstime.tv_sec++;
  75. }
  76. #else
  77. struct timeval tv;
  78. gettimeofday(&tv, NULL);
  79. abstime.tv_sec = tv.tv_sec + milliseconds / 1000;
  80. abstime.tv_nsec = tv.tv_usec*1000 + (milliseconds % 1000)*1000000;
  81. if (abstime.tv_nsec >= 1000000000)
  82. {
  83. abstime.tv_nsec -= 1000000000;
  84. abstime.tv_sec++;
  85. }
  86. #endif
  87. if (pthread_mutex_lock(&_mutex) != 0)
  88. throw SystemException("wait for event failed (lock)");
  89. while (!_state)
  90. {
  91. if ((rc = pthread_cond_timedwait(&_cond, &_mutex, &abstime)))
  92. {
  93. if (rc == ETIMEDOUT) break;
  94. pthread_mutex_unlock(&_mutex);
  95. throw SystemException("cannot wait for event");
  96. }
  97. }
  98. if (rc == 0 && _auto) _state = false;
  99. pthread_mutex_unlock(&_mutex);
  100. return rc == 0;
  101. }
  102. } // namespace Poco