The current implementation of nanosleep is broken on mingw for several reasons:
1) It requires linking with -lws2_32, as evidenced by these error messages:
gcc-3 -mno-cygwin -g -O2 -L/usr/local/mingw/lib -o test-nanosleep.exe
test-nanosleep.o ../gllib/libgnu.a
../gllib/libgnu.a(select.o): In function `rpl_select':
/home/bruno/testdir2/gllib/select.c:93: undefined reference to
`_wsaenumnetworkeve...@12'
/home/bruno/testdir2/gllib/select.c:360: undefined reference to
`_wsaeventsel...@12'
/home/bruno/testdir2/gllib/select.c:381: undefined reference to `_sel...@20'
/home/bruno/testdir2/gllib/select.c:434: undefined reference to
`_wsaeventsel...@12'
/home/bruno/testdir2/gllib/select.c:435: undefined reference to
`___wsafdis...@8'
/home/bruno/testdir2/gllib/select.c:437: undefined reference to
`___wsafdis...@8'
/home/bruno/testdir2/gllib/select.c:439: undefined reference to
`___wsafdis...@8'
/home/bruno/testdir2/gllib/select.c:414: undefined reference to `_sel...@20'
collect2: ld returned 1 exit status
make[4]: *** [test-nanosleep.exe] Error 1
But there is no good reason to link with a sockets library just to sleep a
certain amount of time.
2) Use of this the 'select' function in wsock2 requires a prior invocation
of WSAStartup() (contained in the 'sockets' module).
Witness: This program
===
#include winsock2.h
#include sys/time.h
#include stdlib.h
#include stdio.h
#include windows.h
int main (int argc, char *argv[])
{
int usecs = atoi (argv[1]);
LARGE_INTEGER pcfreq;
LARGE_INTEGER before, after;
struct timeval timeout;
int ret;
if (!QueryPerformanceFrequency (pcfreq))
printf (QueryPerformanceFrequency failed\n);
if (!QueryPerformanceCounter (before))
printf (QueryPerformanceCounter failed\n);
timeout.tv_sec = usecs / 100;
timeout.tv_usec = usecs % 100;
ret = select (0, NULL, NULL, NULL, timeout);
if (ret 0) printf (select failed, error = %d\n, WSAGetLastError());
if (!QueryPerformanceCounter (after))
printf (QueryPerformanceCounter failed\n);
printf (time slept: %g s\n, (double) (after.QuadPart - before.QuadPart) /
(double) pcfreq.QuadPart);
return 0;
}
===
produces the output
$ ./usleep.exe 6000
select failed, error = 10093
time slept: 6.87238e-005 s
Error 10093 is WSANOTINITIALISED.
3) Use of select without a socket descriptor, just a timeout, fails.
Witness: This program
===
#include winsock2.h
#include sys/time.h
#include stdlib.h
#include stdio.h
#include windows.h
int main (int argc, char *argv[])
{
int usecs = atoi (argv[1]);
LARGE_INTEGER pcfreq;
WSADATA data;
LARGE_INTEGER before, after;
struct timeval timeout;
int ret;
if (!QueryPerformanceFrequency (pcfreq))
printf (QueryPerformanceFrequency failed\n);
WSAStartup (0x201, data);
if (!QueryPerformanceCounter (before))
printf (QueryPerformanceCounter failed\n);
timeout.tv_sec = usecs / 100;
timeout.tv_usec = usecs % 100;
ret = select (0, NULL, NULL, NULL, timeout);
if (ret 0) printf (select failed, error = %d\n, WSAGetLastError());
if (!QueryPerformanceCounter (after))
printf (QueryPerformanceCounter failed\n);
printf (time slept: %g s\n, (double) (after.QuadPart - before.QuadPart) /
(double) pcfreq.QuadPart);
return 0;
}
===
produces the output
$ ./usleep.exe 6000
select failed, error = 10022
time slept: 0.000258971 s
Error 10022 is WSAEINVAL.
4) select sleeps for at least 6 ms.
Witness: This program
===
#include winsock2.h
#include sys/time.h
#include stdlib.h
#include stdio.h
#include windows.h
int main (int argc, char *argv[])
{
int usecs = atoi (argv[1]);
LARGE_INTEGER pcfreq;
WSADATA data;
SOCKET s;
fd_set dummy;
LARGE_INTEGER before, after;
struct timeval timeout;
int ret;
if (!QueryPerformanceFrequency (pcfreq))
printf (QueryPerformanceFrequency failed\n);
WSAStartup (0x201, data);
s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
FD_ZERO(dummy);
FD_SET(s, dummy);
if (!QueryPerformanceCounter (before))
printf (QueryPerformanceCounter failed\n);
timeout.tv_sec = usecs / 100;
timeout.tv_usec = usecs % 100;
ret = select (0, NULL, NULL, dummy, timeout);
if (ret 0) printf (select failed, error = %d\n, WSAGetLastError());
if (!QueryPerformanceCounter (after))
printf (QueryPerformanceCounter failed\n);
printf (time slept: %g s\n, (double) (after.QuadPart - before.QuadPart) /
(double) pcfreq.QuadPart);
return 0;
}