You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

228 lines
6.3 KiB

28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
  1. /*****************************************************************************
  2. * *
  3. * DH_TIME.C *
  4. * *
  5. * Freely redistributable and modifiable. Use at your own risk. *
  6. * *
  7. * Copyright 1994 The Downhill Project *
  8. *
  9. * Modified by Shane Caraveo for use with PHP
  10. *
  11. *****************************************************************************/
  12. /* $Id$ */
  13. /**
  14. *
  15. * 04-Feb-2001
  16. * - Added patch by "Vanhanen, Reijo" <Reijo.Vanhanen@helsoft.fi>
  17. * Improves accuracy of msec
  18. */
  19. /* Include stuff ************************************************************ */
  20. /* this allows the use of the WaitableTimer functions.
  21. * For win98 and later */
  22. #define _WIN32_WINNT 0x400
  23. #include "time.h"
  24. #include "unistd.h"
  25. #include "signal.h"
  26. #include <windows.h>
  27. #include <winbase.h>
  28. #include <mmsystem.h>
  29. #include <errno.h>
  30. #include "php_win32_globals.h"
  31. int getfilesystemtime(struct timeval *time_Info)
  32. {
  33. FILETIME ft;
  34. __int64 ff;
  35. GetSystemTimeAsFileTime(&ft); /* 100 ns blocks since 01-Jan-1641 */
  36. /* resolution seems to be 0.01 sec */
  37. ff = *(__int64*)(&ft);
  38. time_Info->tv_sec = (int)(ff/(__int64)10000000-(__int64)11644473600);
  39. time_Info->tv_usec = (int)(ff % 10000000)/10;
  40. return 0;
  41. }
  42. PHPAPI int gettimeofday(struct timeval *time_Info, struct timezone *timezone_Info)
  43. {
  44. __int64 timer;
  45. LARGE_INTEGER li;
  46. BOOL b;
  47. double dt;
  48. TSRMLS_FETCH();
  49. /* Get the time, if they want it */
  50. if (time_Info != NULL) {
  51. if (PW32G(starttime).tv_sec == 0) {
  52. b = QueryPerformanceFrequency(&li);
  53. if (!b) {
  54. PW32G(starttime).tv_sec = -1;
  55. }
  56. else {
  57. PW32G(freq) = li.QuadPart;
  58. b = QueryPerformanceCounter(&li);
  59. if (!b) {
  60. PW32G(starttime).tv_sec = -1;
  61. }
  62. else {
  63. getfilesystemtime(&PW32G(starttime));
  64. timer = li.QuadPart;
  65. dt = (double)timer/PW32G(freq);
  66. PW32G(starttime).tv_usec -= (int)((dt-(int)dt)*1000000);
  67. if (PW32G(starttime).tv_usec < 0) {
  68. PW32G(starttime).tv_usec += 1000000;
  69. --PW32G(starttime).tv_sec;
  70. }
  71. PW32G(starttime).tv_sec -= (int)dt;
  72. }
  73. }
  74. }
  75. if (PW32G(starttime).tv_sec > 0) {
  76. b = QueryPerformanceCounter(&li);
  77. if (!b) {
  78. PW32G(starttime).tv_sec = -1;
  79. }
  80. else {
  81. timer = li.QuadPart;
  82. if (timer < PW32G(lasttime)) {
  83. getfilesystemtime(time_Info);
  84. dt = (double)timer/PW32G(freq);
  85. PW32G(starttime) = *time_Info;
  86. PW32G(starttime).tv_usec -= (int)((dt-(int)dt)*1000000);
  87. if (PW32G(starttime).tv_usec < 0) {
  88. PW32G(starttime).tv_usec += 1000000;
  89. --PW32G(starttime).tv_sec;
  90. }
  91. PW32G(starttime).tv_sec -= (int)dt;
  92. }
  93. else {
  94. PW32G(lasttime) = timer;
  95. dt = (double)timer/PW32G(freq);
  96. time_Info->tv_sec = PW32G(starttime).tv_sec + (int)dt;
  97. time_Info->tv_usec = PW32G(starttime).tv_usec + (int)((dt-(int)dt)*1000000);
  98. if (time_Info->tv_usec > 1000000) {
  99. time_Info->tv_usec -= 1000000;
  100. ++time_Info->tv_sec;
  101. }
  102. }
  103. }
  104. }
  105. if (PW32G(starttime).tv_sec < 0) {
  106. getfilesystemtime(time_Info);
  107. }
  108. }
  109. /* Get the timezone, if they want it */
  110. if (timezone_Info != NULL) {
  111. _tzset();
  112. timezone_Info->tz_minuteswest = _timezone;
  113. timezone_Info->tz_dsttime = _daylight;
  114. }
  115. /* And return */
  116. return 0;
  117. }
  118. void usleep(unsigned int useconds)
  119. {
  120. HANDLE timer;
  121. LARGE_INTEGER due;
  122. due.QuadPart = -(10 * (__int64)useconds);
  123. timer = CreateWaitableTimer(NULL, TRUE, NULL);
  124. SetWaitableTimer(timer, &due, 0, NULL, NULL, 0);
  125. WaitForSingleObject(timer, INFINITE);
  126. CloseHandle(timer);
  127. }
  128. #if 0 /* looks pretty ropey in here */
  129. #ifdef HAVE_SETITIMER
  130. #ifndef THREAD_SAFE
  131. unsigned int proftimer, virttimer, realtimer;
  132. extern LPMSG phpmsg;
  133. #endif
  134. struct timer_msg {
  135. int signal;
  136. unsigned int threadid;
  137. };
  138. LPTIMECALLBACK setitimer_timeout(UINT uTimerID, UINT info, DWORD dwUser, DWORD dw1, DWORD dw2)
  139. {
  140. struct timer_msg *msg = (struct timer_msg *) info;
  141. if (msg) {
  142. raise((int) msg->signal);
  143. PostThreadMessage(msg->threadid,
  144. WM_NOTIFY, msg->signal, 0);
  145. free(msg);
  146. }
  147. return 0;
  148. }
  149. PHPAPI int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue)
  150. {
  151. int timeout = value->it_value.tv_sec * 1000 + value->it_value.tv_usec;
  152. int repeat = TIME_ONESHOT;
  153. /*make sure the message queue is initialized */
  154. PeekMessage(phpmsg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
  155. if (timeout > 0) {
  156. struct timer_msg *msg = malloc(sizeof(struct timer_msg));
  157. msg->threadid = GetCurrentThreadId();
  158. if (!ovalue) {
  159. repeat = TIME_PERIODIC;
  160. }
  161. switch (which) {
  162. case ITIMER_REAL:
  163. msg->signal = SIGALRM;
  164. realtimer = timeSetEvent(timeout, 100, (LPTIMECALLBACK) setitimer_timeout, (UINT) msg, repeat);
  165. break;
  166. case ITIMER_VIRT:
  167. msg->signal = SIGVTALRM;
  168. virttimer = timeSetEvent(timeout, 100, (LPTIMECALLBACK) setitimer_timeout, (UINT) msg, repeat);
  169. break;
  170. case ITIMER_PROF:
  171. msg->signal = SIGPROF;
  172. proftimer = timeSetEvent(timeout, 100, (LPTIMECALLBACK) setitimer_timeout, (UINT) msg, repeat);
  173. break;
  174. default:
  175. errno = EINVAL;
  176. return -1;
  177. break;
  178. }
  179. } else {
  180. switch (which) {
  181. case ITIMER_REAL:
  182. timeKillEvent(realtimer);
  183. break;
  184. case ITIMER_VIRT:
  185. timeKillEvent(virttimer);
  186. break;
  187. case ITIMER_PROF:
  188. timeKillEvent(proftimer);
  189. break;
  190. default:
  191. errno = EINVAL;
  192. return -1;
  193. break;
  194. }
  195. }
  196. return 0;
  197. }
  198. #endif
  199. #endif