Back to index

php5  5.3.10
time.c
Go to the documentation of this file.
00001 
00002 /*****************************************************************************
00003  *                                                                           *
00004  * DH_TIME.C                                                                 *
00005  *                                                                           *
00006  * Freely redistributable and modifiable.  Use at your own risk.             *
00007  *                                                                           *
00008  * Copyright 1994 The Downhill Project                                       *
00009  * 
00010  * Modified by Shane Caraveo for use with PHP
00011  *
00012  *****************************************************************************/
00013 
00014 /* $Id: time.c 305298 2010-11-12 18:37:02Z cataphract $ */
00015 
00023 /* Include stuff ************************************************************ */
00024 
00025 #include <config.w32.h>
00026 
00027 #include "time.h"
00028 #include "unistd.h"
00029 #include "signal.h"
00030 #include <windows.h>
00031 #include <winbase.h>
00032 #include <mmsystem.h>
00033 #include <errno.h>
00034 #include "php_win32_globals.h"
00035 
00036 int getfilesystemtime(struct timeval *time_Info) 
00037 {
00038 FILETIME ft;
00039 __int64 ff;
00040 
00041     GetSystemTimeAsFileTime(&ft);   /* 100 ns blocks since 01-Jan-1641 */
00042                                     /* resolution seems to be 0.01 sec */ 
00043     ff = *(__int64*)(&ft);
00044     time_Info->tv_sec = (int)(ff/(__int64)10000000-(__int64)11644473600);
00045     time_Info->tv_usec = (int)(ff % 10000000)/10;
00046     return 0;
00047 }
00048 
00049  
00050 
00051 PHPAPI int gettimeofday(struct timeval *time_Info, struct timezone *timezone_Info)
00052 {
00053        __int64 timer;
00054        LARGE_INTEGER li;
00055        BOOL b;
00056        double dt;
00057        TSRMLS_FETCH();
00058 
00059        /* Get the time, if they want it */
00060        if (time_Info != NULL) {
00061               if (PW32G(starttime).tv_sec == 0) {
00062             b = QueryPerformanceFrequency(&li);
00063             if (!b) {
00064                 PW32G(starttime).tv_sec = -1;
00065             }
00066             else {
00067                 PW32G(freq) = li.QuadPart;
00068                 b = QueryPerformanceCounter(&li);
00069                 if (!b) {
00070                     PW32G(starttime).tv_sec = -1;
00071                 }
00072                 else {
00073                     getfilesystemtime(&PW32G(starttime));
00074                     timer = li.QuadPart;
00075                     dt = (double)timer/PW32G(freq);
00076                     PW32G(starttime).tv_usec -= (int)((dt-(int)dt)*1000000);
00077                     if (PW32G(starttime).tv_usec < 0) {
00078                         PW32G(starttime).tv_usec += 1000000;
00079                         --PW32G(starttime).tv_sec;
00080                     }
00081                     PW32G(starttime).tv_sec -= (int)dt;
00082                 }
00083             }
00084         }
00085         if (PW32G(starttime).tv_sec > 0) {
00086             b = QueryPerformanceCounter(&li);
00087             if (!b) {
00088                 PW32G(starttime).tv_sec = -1;
00089             }
00090             else {
00091                 timer = li.QuadPart;
00092                 if (timer < PW32G(lasttime)) {
00093                     getfilesystemtime(time_Info);
00094                     dt = (double)timer/PW32G(freq);
00095                     PW32G(starttime) = *time_Info;
00096                     PW32G(starttime).tv_usec -= (int)((dt-(int)dt)*1000000);
00097                     if (PW32G(starttime).tv_usec < 0) {
00098                         PW32G(starttime).tv_usec += 1000000;
00099                         --PW32G(starttime).tv_sec;
00100                     }
00101                     PW32G(starttime).tv_sec -= (int)dt;
00102                 }
00103                 else {
00104                     PW32G(lasttime) = timer;
00105                     dt = (double)timer/PW32G(freq);
00106                     time_Info->tv_sec = PW32G(starttime).tv_sec + (int)dt;
00107                     time_Info->tv_usec = PW32G(starttime).tv_usec + (int)((dt-(int)dt)*1000000);
00108                     if (time_Info->tv_usec >= 1000000) {
00109                         time_Info->tv_usec -= 1000000;
00110                         ++time_Info->tv_sec;
00111                     }
00112                 }
00113             }
00114         }
00115         if (PW32G(starttime).tv_sec < 0) {
00116             getfilesystemtime(time_Info);
00117         }
00118 
00119        }
00120        /* Get the timezone, if they want it */
00121        if (timezone_Info != NULL) {
00122               _tzset();
00123               timezone_Info->tz_minuteswest = _timezone;
00124               timezone_Info->tz_dsttime = _daylight;
00125        }
00126        /* And return */
00127        return 0;
00128 }
00129 
00130 PHPAPI int usleep(unsigned int useconds)
00131 {
00132        HANDLE timer;
00133        LARGE_INTEGER due;
00134 
00135        due.QuadPart = -(10 * (__int64)useconds);
00136 
00137        timer = CreateWaitableTimer(NULL, TRUE, NULL);
00138        SetWaitableTimer(timer, &due, 0, NULL, NULL, 0);
00139        WaitForSingleObject(timer, INFINITE);
00140        CloseHandle(timer);
00141        return 0;
00142 }
00143 
00144 PHPAPI int nanosleep( const struct timespec * rqtp, struct timespec * rmtp )
00145 {
00146        if (rqtp->tv_nsec > 999999999) {
00147               /* The time interval specified 1,000,000 or more microseconds. */
00148               errno = EINVAL;
00149               return -1;
00150        }
00151        return usleep( rqtp->tv_sec * 1000000 + rqtp->tv_nsec / 1000  );
00152 }
00153 
00154 #if 0 /* looks pretty ropey in here */
00155 #ifdef HAVE_SETITIMER
00156 
00157 
00158 #ifndef THREAD_SAFE
00159 unsigned int proftimer, virttimer, realtimer;
00160 extern LPMSG phpmsg;
00161 #endif
00162 
00163 struct timer_msg {
00164        int signal;
00165        unsigned int threadid;
00166 };
00167 
00168 
00169 LPTIMECALLBACK setitimer_timeout(UINT uTimerID, UINT info, DWORD dwUser, DWORD dw1, DWORD dw2)
00170 {
00171        struct timer_msg *msg = (struct timer_msg *) info;
00172 
00173        if (msg) {
00174               raise((int) msg->signal);
00175               PostThreadMessage(msg->threadid,
00176                                             WM_NOTIFY, msg->signal, 0);
00177               free(msg);
00178        }
00179        return 0;
00180 }
00181 
00182 PHPAPI int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue)
00183 {
00184        int timeout = value->it_value.tv_sec * 1000 + value->it_value.tv_usec;
00185        int repeat = TIME_ONESHOT;
00186 
00187        /*make sure the message queue is initialized */
00188        PeekMessage(phpmsg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
00189        if (timeout > 0) {
00190               struct timer_msg *msg = malloc(sizeof(struct timer_msg));
00191               msg->threadid = GetCurrentThreadId();
00192               if (!ovalue) {
00193                      repeat = TIME_PERIODIC;
00194               }
00195               switch (which) {
00196                      case ITIMER_REAL:
00197                             msg->signal = SIGALRM;
00198                             realtimer = timeSetEvent(timeout, 100, (LPTIMECALLBACK) setitimer_timeout, (UINT) msg, repeat);
00199                             break;
00200                      case ITIMER_VIRT:
00201                             msg->signal = SIGVTALRM;
00202                             virttimer = timeSetEvent(timeout, 100, (LPTIMECALLBACK) setitimer_timeout, (UINT) msg, repeat);
00203                             break;
00204                      case ITIMER_PROF:
00205                             msg->signal = SIGPROF;
00206                             proftimer = timeSetEvent(timeout, 100, (LPTIMECALLBACK) setitimer_timeout, (UINT) msg, repeat);
00207                             break;
00208                      default:
00209                             errno = EINVAL;
00210                             return -1;
00211                             break;
00212               }
00213        } else {
00214               switch (which) {
00215                      case ITIMER_REAL:
00216                             timeKillEvent(realtimer);
00217                             break;
00218                      case ITIMER_VIRT:
00219                             timeKillEvent(virttimer);
00220                             break;
00221                      case ITIMER_PROF:
00222                             timeKillEvent(proftimer);
00223                             break;
00224                      default:
00225                             errno = EINVAL;
00226                             return -1;
00227                             break;
00228               }
00229        }
00230 
00231 
00232        return 0;
00233 }
00234 
00235 #endif
00236 #endif
00237