root/win32/time.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. get_time_func
  2. getfilesystemtime
  3. gettimeofday
  4. usleep
  5. nanosleep
  6. setitimer_timeout
  7. setitimer

   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 
  13 /* $Id$ */
  14 
  15 /* Include stuff ************************************************************ */
  16 
  17 #include <config.w32.h>
  18 
  19 #include "time.h"
  20 #include "unistd.h"
  21 #include "signal.h"
  22 #include <windows.h>
  23 #include <winbase.h>
  24 #include <mmsystem.h>
  25 #include <errno.h>
  26 #include "php_win32_globals.h"
  27 
  28 typedef VOID (WINAPI *MyGetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTime);
  29 
  30 static MyGetSystemTimeAsFileTime get_time_func(void)
  31 {
  32         MyGetSystemTimeAsFileTime timefunc = NULL;
  33         HMODULE hMod = LoadLibrary("kernel32.dll");
  34 
  35         if (hMod) {
  36                 /* Max possible resolution <1us, win8/server2012 */
  37                 timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimePreciseAsFileTime");
  38 
  39                 if(!timefunc) {
  40                         /* 100ns blocks since 01-Jan-1641 */
  41                         timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimeAsFileTime");
  42                 }
  43         }
  44 
  45         return timefunc;
  46 }
  47 
  48 int getfilesystemtime(struct timeval *tv)
  49 {
  50         FILETIME ft;
  51         unsigned __int64 ff = 0;
  52         MyGetSystemTimeAsFileTime timefunc;
  53         ULARGE_INTEGER fft;
  54 
  55         timefunc = get_time_func();
  56         if (timefunc) {
  57                 timefunc(&ft);
  58         } else {
  59                 GetSystemTimeAsFileTime(&ft);
  60         }
  61 
  62         /*
  63          * Do not cast a pointer to a FILETIME structure to either a 
  64          * ULARGE_INTEGER* or __int64* value because it can cause alignment faults on 64-bit Windows.
  65          * via  http://technet.microsoft.com/en-us/library/ms724284(v=vs.85).aspx
  66          */
  67         fft.HighPart = ft.dwHighDateTime;
  68         fft.LowPart = ft.dwLowDateTime;
  69         ff = fft.QuadPart;
  70 
  71         ff /= 10Ui64; /* convert to microseconds */
  72         ff -= 11644473600000000Ui64; /* convert to unix epoch */
  73 
  74         tv->tv_sec = (long)(ff / 1000000Ui64);
  75         tv->tv_usec = (long)(ff % 1000000Ui64);
  76 
  77         return 0;
  78 }
  79 
  80 PHPAPI int gettimeofday(struct timeval *time_Info, struct timezone *timezone_Info)
  81 {
  82         /* Get the time, if they want it */
  83         if (time_Info != NULL) {
  84                 getfilesystemtime(time_Info);
  85         }
  86         /* Get the timezone, if they want it */
  87         if (timezone_Info != NULL) {
  88                 _tzset();
  89                 timezone_Info->tz_minuteswest = _timezone;
  90                 timezone_Info->tz_dsttime = _daylight;
  91         }
  92         /* And return */
  93         return 0;
  94 }
  95 
  96 PHPAPI int usleep(unsigned int useconds)
  97 {
  98         HANDLE timer;
  99         LARGE_INTEGER due;
 100 
 101         due.QuadPart = -(10 * (__int64)useconds);
 102 
 103         timer = CreateWaitableTimer(NULL, TRUE, NULL);
 104         SetWaitableTimer(timer, &due, 0, NULL, NULL, 0);
 105         WaitForSingleObject(timer, INFINITE);
 106         CloseHandle(timer);
 107         return 0;
 108 }
 109 
 110 PHPAPI int nanosleep( const struct timespec * rqtp, struct timespec * rmtp )
 111 {
 112         if (rqtp->tv_nsec > 999999999) {
 113                 /* The time interval specified 1,000,000 or more microseconds. */
 114                 errno = EINVAL;
 115                 return -1;
 116         }
 117         return usleep( rqtp->tv_sec * 1000000 + rqtp->tv_nsec / 1000  );
 118 }
 119 
 120 #if 0 /* looks pretty ropey in here */
 121 #ifdef HAVE_SETITIMER
 122 
 123 
 124 #ifndef THREAD_SAFE
 125 unsigned int proftimer, virttimer, realtimer;
 126 extern LPMSG phpmsg;
 127 #endif
 128 
 129 struct timer_msg {
 130         int signal;
 131         unsigned int threadid;
 132 };
 133 
 134 
 135 LPTIMECALLBACK setitimer_timeout(UINT uTimerID, UINT info, DWORD dwUser, DWORD dw1, DWORD dw2)
 136 {
 137         struct timer_msg *msg = (struct timer_msg *) info;
 138 
 139         if (msg) {
 140                 raise((int) msg->signal);
 141                 PostThreadMessage(msg->threadid,
 142                                                   WM_NOTIFY, msg->signal, 0);
 143                 free(msg);
 144         }
 145         return 0;
 146 }
 147 
 148 PHPAPI int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue)
 149 {
 150         int timeout = value->it_value.tv_sec * 1000 + value->it_value.tv_usec;
 151         int repeat = TIME_ONESHOT;
 152 
 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 
 197 
 198         return 0;
 199 }
 200 
 201 #endif
 202 #endif
 203 

/* [<][>][^][v][top][bottom][index][help] */