1/*
2 * tclUnixEvent.c --
3 *
4 *	This file implements Unix specific event related routines.
5 *
6 * Copyright (c) 1997 by Sun Microsystems, Inc.
7 *
8 * See the file "license.terms" for information on usage and redistribution
9 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
10 *
11 * RCS: @(#) $Id: tclUnixEvent.c,v 1.4 2001/11/21 02:36:21 hobbs Exp $
12 */
13
14#include "tclInt.h"
15#include "tclPort.h"
16
17/*
18 *----------------------------------------------------------------------
19 *
20 * Tcl_Sleep --
21 *
22 *	Delay execution for the specified number of milliseconds.
23 *
24 * Results:
25 *	None.
26 *
27 * Side effects:
28 *	Time passes.
29 *
30 *----------------------------------------------------------------------
31 */
32
33void
34Tcl_Sleep(ms)
35    int ms;			/* Number of milliseconds to sleep. */
36{
37    struct timeval delay;
38    Tcl_Time before, after;
39
40    /*
41     * The only trick here is that select appears to return early
42     * under some conditions, so we have to check to make sure that
43     * the right amount of time really has elapsed.  If it's too
44     * early, go back to sleep again.
45     */
46
47    Tcl_GetTime(&before);
48    after = before;
49    after.sec += ms/1000;
50    after.usec += (ms%1000)*1000;
51    if (after.usec > 1000000) {
52	after.usec -= 1000000;
53	after.sec += 1;
54    }
55    while (1) {
56	delay.tv_sec = after.sec - before.sec;
57	delay.tv_usec = after.usec - before.usec;
58	if (delay.tv_usec < 0) {
59	    delay.tv_usec += 1000000;
60	    delay.tv_sec -= 1;
61	}
62
63	/*
64	 * Special note:  must convert delay.tv_sec to int before comparing
65	 * to zero, since delay.tv_usec is unsigned on some platforms.
66	 */
67
68	if ((((int) delay.tv_sec) < 0)
69		|| ((delay.tv_usec == 0) && (delay.tv_sec == 0))) {
70	    break;
71	}
72	(void) select(0, (SELECT_MASK *) 0, (SELECT_MASK *) 0,
73		(SELECT_MASK *) 0, &delay);
74	Tcl_GetTime(&before);
75    }
76}
77