1 /*
2  * tclUnixEvent.c --
3  *
4  *	This file implements Unix specific event related routines.
5  *
6  * Copyright © 1997 Sun Microsystems, Inc.
7  *
8  * See the file "license.terms" for information on usage and redistribution of
9  * this file, and for a DISCLAIMER OF ALL WARRANTIES.
10  */
11 
12 #include "tclInt.h"
13 #ifndef HAVE_COREFOUNDATION	/* Darwin/Mac OS X CoreFoundation notifier is
14 				 * in tclMacOSXNotify.c */
15 
16 /*
17  *----------------------------------------------------------------------
18  *
19  * Tcl_Sleep --
20  *
21  *	Delay execution for the specified number of milliseconds.
22  *
23  * Results:
24  *	None.
25  *
26  * Side effects:
27  *	Time passes.
28  *
29  *----------------------------------------------------------------------
30  */
31 
32 void
Tcl_Sleep(int ms)33 Tcl_Sleep(
34     int ms)			/* Number of milliseconds to sleep. */
35 {
36     struct timeval delay;
37     Tcl_Time before, after, vdelay;
38 
39     /*
40      * The only trick here is that select appears to return early under some
41      * conditions, so we have to check to make sure that the right amount of
42      * time really has elapsed.  If it's too early, go back to sleep again.
43      */
44 
45     Tcl_GetTime(&before);
46     after = before;
47     after.sec += ms/1000;
48     after.usec += (ms%1000)*1000;
49     if (after.usec > 1000000) {
50 	after.usec -= 1000000;
51 	after.sec += 1;
52     }
53     while (1) {
54 	/*
55 	 * TIP #233: Scale from virtual time to real-time for select.
56 	 */
57 
58 	vdelay.sec  = after.sec  - before.sec;
59 	vdelay.usec = after.usec - before.usec;
60 
61 	if (vdelay.usec < 0) {
62 	    vdelay.usec += 1000000;
63 	    vdelay.sec  -= 1;
64 	}
65 
66 	if ((vdelay.sec != 0) || (vdelay.usec != 0)) {
67 	    TclScaleTime(&vdelay);
68 	}
69 
70 	delay.tv_sec  = vdelay.sec;
71 	delay.tv_usec = vdelay.usec;
72 
73 	/*
74 	 * Special note: must convert delay.tv_sec to int before comparing to
75 	 * zero, since delay.tv_usec is unsigned on some platforms.
76 	 */
77 
78 	if ((((int) delay.tv_sec) < 0)
79 		|| ((delay.tv_usec == 0) && (delay.tv_sec == 0))) {
80 	    break;
81 	}
82 	(void) select(0, (SELECT_MASK *) 0, (SELECT_MASK *) 0,
83 		(SELECT_MASK *) 0, &delay);
84 	Tcl_GetTime(&before);
85     }
86 }
87 
88 #else
89 TCL_MAC_EMPTY_FILE(unix_tclUnixEvent_c)
90 #endif /* HAVE_COREFOUNDATION */
91 /*
92  * Local Variables:
93  * mode: c
94  * c-basic-offset: 4
95  * fill-column: 78
96  * End:
97  */
98