Annotation of embedaddon/php/win32/time.c, revision 1.1.1.3

1.1       misho       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: 
1.1.1.2   misho      13: /* $Id$ */
1.1       misho      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: 
1.1.1.3 ! misho      28: typedef VOID (WINAPI *MyGetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTime);
        !            29: 
        !            30: static MyGetSystemTimeAsFileTime get_time_func(void)
1.1       misho      31: {
1.1.1.3 ! misho      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:        }
1.1       misho      44: 
1.1.1.3 ! misho      45:        return timefunc;
1.1       misho      46: }
                     47: 
1.1.1.3 ! misho      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: }
1.1       misho      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) {
1.1.1.3 ! misho      84:                getfilesystemtime(time_Info);
1.1       misho      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: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>