Revision 68c23e55 qemu-timer.c

b/qemu-timer.c
200 200

  
201 201
#ifdef _WIN32
202 202

  
203
struct qemu_alarm_win32 {
204
    MMRESULT timerId;
205
    unsigned int period;
206
} alarm_win32_data = {0, 0};
207

  
208 203
static int win32_start_timer(struct qemu_alarm_timer *t);
209 204
static void win32_stop_timer(struct qemu_alarm_timer *t);
210 205
static void win32_rearm_timer(struct qemu_alarm_timer *t);
......
298 293
    {"unix", unix_start_timer, unix_stop_timer, NULL, NULL},
299 294
#else
300 295
    {"dynticks", win32_start_timer,
301
     win32_stop_timer, win32_rearm_timer, &alarm_win32_data},
296
     win32_stop_timer, win32_rearm_timer, NULL},
302 297
    {"win32", win32_start_timer,
303
     win32_stop_timer, NULL, &alarm_win32_data},
298
     win32_stop_timer, NULL, NULL},
304 299
#endif
305 300
    {NULL, }
306 301
};
......
636 631
static int64_t qemu_next_alarm_deadline(void);
637 632

  
638 633
#ifdef _WIN32
639
static void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
640
                                        DWORD_PTR dwUser, DWORD_PTR dw1,
641
                                        DWORD_PTR dw2)
634
static void CALLBACK host_alarm_handler(PVOID lpParam, BOOLEAN unused)
642 635
#else
643 636
static void host_alarm_handler(int host_signum)
644 637
#endif
......
961 954

  
962 955
static int win32_start_timer(struct qemu_alarm_timer *t)
963 956
{
964
    TIMECAPS tc;
965
    struct qemu_alarm_win32 *data = t->priv;
966
    UINT flags;
967

  
968
    memset(&tc, 0, sizeof(tc));
969
    timeGetDevCaps(&tc, sizeof(tc));
970

  
971
    data->period = tc.wPeriodMin;
972
    timeBeginPeriod(data->period);
973

  
974
    flags = TIME_CALLBACK_FUNCTION;
975
    if (alarm_has_dynticks(t))
976
        flags |= TIME_ONESHOT;
977
    else
978
        flags |= TIME_PERIODIC;
979

  
980
    data->timerId = timeSetEvent(1,         // interval (ms)
981
                        data->period,       // resolution
982
                        host_alarm_handler, // function
983
                        (DWORD)t,           // parameter
984
                        flags);
985

  
986
    if (!data->timerId) {
957
    HANDLE hTimer;
958
    BOOLEAN success;
959

  
960
    /* If you call ChangeTimerQueueTimer on a one-shot timer (its period
961
       is zero) that has already expired, the timer is not updated.  Since
962
       creating a new timer is relatively expensive, set a bogus one-hour
963
       interval in the dynticks case.  */
964
    success = CreateTimerQueueTimer(&hTimer,
965
                          NULL,
966
                          host_alarm_handler,
967
                          t,
968
                          1,
969
                          alarm_has_dynticks(t) ? 3600000 : 1,
970
                          WT_EXECUTEINTIMERTHREAD);
971

  
972
    if (!success) {
987 973
        fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
988 974
                GetLastError());
989
        timeEndPeriod(data->period);
990 975
        return -1;
991 976
    }
992 977

  
978
    t->priv = (PVOID) hTimer;
993 979
    return 0;
994 980
}
995 981

  
996 982
static void win32_stop_timer(struct qemu_alarm_timer *t)
997 983
{
998
    struct qemu_alarm_win32 *data = t->priv;
984
    HANDLE hTimer = t->priv;
999 985

  
1000
    timeKillEvent(data->timerId);
1001
    timeEndPeriod(data->period);
986
    if (hTimer) {
987
        DeleteTimerQueueTimer(NULL, hTimer, NULL);
988
    }
1002 989
}
1003 990

  
1004 991
static void win32_rearm_timer(struct qemu_alarm_timer *t)
1005 992
{
1006
    struct qemu_alarm_win32 *data = t->priv;
993
    HANDLE hTimer = t->priv;
1007 994
    int nearest_delta_ms;
995
    BOOLEAN success;
1008 996

  
1009 997
    assert(alarm_has_dynticks(t));
1010 998
    if (!active_timers[QEMU_CLOCK_REALTIME] &&
......
1012 1000
        !active_timers[QEMU_CLOCK_HOST])
1013 1001
        return;
1014 1002

  
1015
    timeKillEvent(data->timerId);
1016

  
1017 1003
    nearest_delta_ms = (qemu_next_alarm_deadline() + 999999) / 1000000;
1018 1004
    if (nearest_delta_ms < 1) {
1019 1005
        nearest_delta_ms = 1;
1020 1006
    }
1021
    data->timerId = timeSetEvent(nearest_delta_ms,
1022
                        data->period,
1023
                        host_alarm_handler,
1024
                        (DWORD)t,
1025
                        TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
1026

  
1027
    if (!data->timerId) {
1028
        fprintf(stderr, "Failed to re-arm win32 alarm timer %ld\n",
1029
                GetLastError());
1007
    success = ChangeTimerQueueTimer(NULL,
1008
                                    hTimer,
1009
                                    nearest_delta_ms,
1010
                                    3600000);
1030 1011

  
1031
        timeEndPeriod(data->period);
1032
        exit(1);
1012
    if (!success) {
1013
        fprintf(stderr, "Failed to rearm win32 alarm timer: %ld\n",
1014
                GetLastError());
1015
        exit(-1);
1033 1016
    }
1017

  
1034 1018
}
1035 1019

  
1036 1020
#endif /* _WIN32 */

Also available in: Unified diff