Condition.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /*
  2. EQ2Emulator: Everquest II Server Emulator
  3. Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net)
  4. This file is part of EQ2Emulator.
  5. EQ2Emulator is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. EQ2Emulator is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with EQ2Emulator. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include "debug.h"
  17. #include "Condition.h"
  18. #ifdef WIN32
  19. #else
  20. #include <pthread.h>
  21. #include <sys/time.h>
  22. #include <errno.h>
  23. #endif
  24. #ifdef WIN32
  25. /*
  26. Windows does not support condition variables by default.
  27. So we use a simple hack of sleeping in wait() and doing
  28. nothing anywhere else.
  29. some possible places to look for ways to do this:
  30. http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
  31. http://sources.redhat.com/pthreads-win32/
  32. http://sources.redhat.com/cgi-bin/cvsweb.cgi/pthreads/pthread_cond_signal.c?rev=1.7&content-type=text/x-cvsweb-markup&cvsroot=pthreads-win32
  33. */
  34. #define CONDITION_HACK_GRANULARITY 4
  35. Condition::Condition()
  36. {
  37. }
  38. void Condition::Signal()
  39. {
  40. }
  41. void Condition::SignalAll()
  42. {
  43. }
  44. void Condition::Wait()
  45. {
  46. Sleep(CONDITION_HACK_GRANULARITY);
  47. }
  48. Condition::~Condition()
  49. {
  50. }
  51. #else //!WIN32
  52. Condition::Condition()
  53. {
  54. pthread_cond_init(&cond,NULL);
  55. pthread_mutex_init(&mutex,NULL);
  56. }
  57. void Condition::Signal()
  58. {
  59. pthread_mutex_lock(&mutex);
  60. pthread_cond_signal(&cond);
  61. pthread_mutex_unlock(&mutex);
  62. }
  63. void Condition::SignalAll()
  64. {
  65. pthread_mutex_lock(&mutex);
  66. pthread_cond_broadcast(&cond);
  67. pthread_mutex_unlock(&mutex);
  68. }
  69. void Condition::Wait()
  70. {
  71. pthread_mutex_lock(&mutex);
  72. pthread_cond_wait(&cond,&mutex);
  73. pthread_mutex_unlock(&mutex);
  74. }
  75. /*
  76. I commented this specifically because I think it might be very
  77. difficult to write a windows counterpart to it, so I would like
  78. to discourage its use until we can confirm that it can be reasonably
  79. implemented on windows.
  80. bool Condition::TimedWait(unsigned long usec)
  81. {
  82. struct timeval now;
  83. struct timespec timeout;
  84. int retcode=0;
  85. pthread_mutex_lock(&mutex);
  86. gettimeofday(&now,NULL);
  87. now.tv_usec+=usec;
  88. timeout.tv_sec = now.tv_sec + (now.tv_usec/1000000);
  89. timeout.tv_nsec = (now.tv_usec%1000000) *1000;
  90. //cout << "now=" << now.tv_sec << "."<<now.tv_usec << endl;
  91. //cout << "timeout=" << timeout.tv_sec << "."<<timeout.tv_nsec << endl;
  92. retcode=pthread_cond_timedwait(&cond,&mutex,&timeout);
  93. pthread_mutex_unlock(&mutex);
  94. return retcode!=ETIMEDOUT;
  95. }
  96. */
  97. Condition::~Condition()
  98. {
  99. pthread_mutex_lock(&mutex);
  100. pthread_cond_broadcast(&cond);
  101. pthread_cond_destroy(&cond);
  102. pthread_mutex_unlock(&mutex);
  103. pthread_mutex_destroy(&mutex);
  104. }
  105. #endif