diff options
Diffstat (limited to 'erts')
-rw-r--r-- | erts/emulator/test/driver_SUITE.erl | 6 | ||||
-rw-r--r-- | erts/emulator/test/driver_SUITE_data/timer_drv.c | 44 |
2 files changed, 42 insertions, 8 deletions
diff --git a/erts/emulator/test/driver_SUITE.erl b/erts/emulator/test/driver_SUITE.erl index 1df72193a6..2fbf6eae61 100644 --- a/erts/emulator/test/driver_SUITE.erl +++ b/erts/emulator/test/driver_SUITE.erl @@ -452,11 +452,7 @@ timer_delay(Config) when is_list(Config) -> TimeBefore = erlang:monotonic_time(), Timeout0 = 350, erlang:port_command(Port, <<?DELAY_START_TIMER,Timeout0:32>>), - Timeout = Timeout0 + - case os:type() of - {win32,_} -> 0; %Driver doesn't sleep on Windows. - _ -> 1000 - end, + Timeout = Timeout0 + 1000, receive {Port,{data,[?TIMER]}} -> Elapsed = erl_millisecs() - erl_millisecs(TimeBefore), diff --git a/erts/emulator/test/driver_SUITE_data/timer_drv.c b/erts/emulator/test/driver_SUITE_data/timer_drv.c index 57538e0d57..c3ce3b6e49 100644 --- a/erts/emulator/test/driver_SUITE_data/timer_drv.c +++ b/erts/emulator/test/driver_SUITE_data/timer_drv.c @@ -1,5 +1,13 @@ #include <stdio.h> #include "erl_driver.h" +#ifdef __WIN32__ +# include <windows.h> +#else +# include <sys/time.h> +# include <sys/types.h> +# include <sys/select.h> +# include <unistd.h> +#endif #define get_int32(s) ((((unsigned char*) (s))[0] << 24) | \ (((unsigned char*) (s))[1] << 16) | \ @@ -17,6 +25,7 @@ static ErlDrvData timer_start(ErlDrvPort, char*); static void timer_stop(ErlDrvData); static void timer_read(ErlDrvData, char*, ErlDrvSizeT); static void timer(ErlDrvData); +static void ms_sleep(int ms); static ErlDrvEntry timer_driver_entry = { @@ -75,9 +84,7 @@ static void timer_read(ErlDrvData p, char *buf, ErlDrvSizeT len) reply[0] = CANCELLED; driver_output(port, reply, 1); } else if (buf[0] == DELAY_START_TIMER) { -#ifndef __WIN32__ - sleep(1); -#endif + ms_sleep(1000); driver_set_timer(port, get_int32(buf + 1)); } } @@ -95,3 +102,34 @@ static void timer(ErlDrvData port) reply[0] = TIMER; driver_output((ErlDrvPort)port, reply, 1); } + +static void +ms_sleep(int ms) +{ + /* Important that we do not return too early... */ + ErlDrvTime time, timeout_time; + + time = erl_drv_monotonic_time(ERL_DRV_USEC); + + timeout_time = time + ((ErlDrvTime) ms)*1000; + + while (time < timeout_time) { + ErlDrvTime timeout = timeout_time - time; + +#ifdef __WIN32__ + Sleep((DWORD) (timeout / 1000)); +#else + { + struct timeval tv; + + tv.tv_sec = (long) timeout / (1000*1000); + tv.tv_usec = (long) timeout % (1000*1000); + + select(0, NULL, NULL, NULL, &tv); + } +#endif + + time = erl_drv_monotonic_time(ERL_DRV_USEC); + } + +} |