comparison src/timeout.c @ 0:4b915342e2a8

LuaSocket 2.0.2 + CMake build description.
author Eric Wing <ewing . public |-at-| gmail . com>
date Tue, 26 Aug 2008 18:40:01 -0700
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4b915342e2a8
1 /*=========================================================================*\
2 * Timeout management functions
3 * LuaSocket toolkit
4 *
5 * RCS ID: $Id: timeout.c,v 1.30 2005/10/07 04:40:59 diego Exp $
6 \*=========================================================================*/
7 #include <stdio.h>
8
9 #include "lua.h"
10 #include "lauxlib.h"
11
12 #include "auxiliar.h"
13 #include "timeout.h"
14
15 #ifdef _WIN32
16 #include <windows.h>
17 #else
18 #include <time.h>
19 #include <sys/time.h>
20 #endif
21
22 /* min and max macros */
23 #ifndef MIN
24 #define MIN(x, y) ((x) < (y) ? x : y)
25 #endif
26 #ifndef MAX
27 #define MAX(x, y) ((x) > (y) ? x : y)
28 #endif
29
30 /*=========================================================================*\
31 * Internal function prototypes
32 \*=========================================================================*/
33 static int timeout_lua_gettime(lua_State *L);
34 static int timeout_lua_sleep(lua_State *L);
35
36 static luaL_reg func[] = {
37 { "gettime", timeout_lua_gettime },
38 { "sleep", timeout_lua_sleep },
39 { NULL, NULL }
40 };
41
42 /*=========================================================================*\
43 * Exported functions.
44 \*=========================================================================*/
45 /*-------------------------------------------------------------------------*\
46 * Initialize structure
47 \*-------------------------------------------------------------------------*/
48 void timeout_init(p_timeout tm, double block, double total) {
49 tm->block = block;
50 tm->total = total;
51 }
52
53 /*-------------------------------------------------------------------------*\
54 * Determines how much time we have left for the next system call,
55 * if the previous call was successful
56 * Input
57 * tm: timeout control structure
58 * Returns
59 * the number of ms left or -1 if there is no time limit
60 \*-------------------------------------------------------------------------*/
61 double timeout_get(p_timeout tm) {
62 if (tm->block < 0.0 && tm->total < 0.0) {
63 return -1;
64 } else if (tm->block < 0.0) {
65 double t = tm->total - timeout_gettime() + tm->start;
66 return MAX(t, 0.0);
67 } else if (tm->total < 0.0) {
68 return tm->block;
69 } else {
70 double t = tm->total - timeout_gettime() + tm->start;
71 return MIN(tm->block, MAX(t, 0.0));
72 }
73 }
74
75 /*-------------------------------------------------------------------------*\
76 * Returns time since start of operation
77 * Input
78 * tm: timeout control structure
79 * Returns
80 * start field of structure
81 \*-------------------------------------------------------------------------*/
82 double timeout_getstart(p_timeout tm) {
83 return tm->start;
84 }
85
86 /*-------------------------------------------------------------------------*\
87 * Determines how much time we have left for the next system call,
88 * if the previous call was a failure
89 * Input
90 * tm: timeout control structure
91 * Returns
92 * the number of ms left or -1 if there is no time limit
93 \*-------------------------------------------------------------------------*/
94 double timeout_getretry(p_timeout tm) {
95 if (tm->block < 0.0 && tm->total < 0.0) {
96 return -1;
97 } else if (tm->block < 0.0) {
98 double t = tm->total - timeout_gettime() + tm->start;
99 return MAX(t, 0.0);
100 } else if (tm->total < 0.0) {
101 double t = tm->block - timeout_gettime() + tm->start;
102 return MAX(t, 0.0);
103 } else {
104 double t = tm->total - timeout_gettime() + tm->start;
105 return MIN(tm->block, MAX(t, 0.0));
106 }
107 }
108
109 /*-------------------------------------------------------------------------*\
110 * Marks the operation start time in structure
111 * Input
112 * tm: timeout control structure
113 \*-------------------------------------------------------------------------*/
114 p_timeout timeout_markstart(p_timeout tm) {
115 tm->start = timeout_gettime();
116 return tm;
117 }
118
119 /*-------------------------------------------------------------------------*\
120 * Gets time in s, relative to January 1, 1970 (UTC)
121 * Returns
122 * time in s.
123 \*-------------------------------------------------------------------------*/
124 #ifdef _WIN32
125 double timeout_gettime(void) {
126 FILETIME ft;
127 double t;
128 GetSystemTimeAsFileTime(&ft);
129 /* Windows file time (time since January 1, 1601 (UTC)) */
130 t = ft.dwLowDateTime/1.0e7 + ft.dwHighDateTime*(4294967296.0/1.0e7);
131 /* convert to Unix Epoch time (time since January 1, 1970 (UTC)) */
132 return (t - 11644473600.0);
133 }
134 #else
135 double timeout_gettime(void) {
136 struct timeval v;
137 gettimeofday(&v, (struct timezone *) NULL);
138 /* Unix Epoch time (time since January 1, 1970 (UTC)) */
139 return v.tv_sec + v.tv_usec/1.0e6;
140 }
141 #endif
142
143 /*-------------------------------------------------------------------------*\
144 * Initializes module
145 \*-------------------------------------------------------------------------*/
146 int timeout_open(lua_State *L) {
147 luaL_openlib(L, NULL, func, 0);
148 return 0;
149 }
150
151 /*-------------------------------------------------------------------------*\
152 * Sets timeout values for IO operations
153 * Lua Input: base, time [, mode]
154 * time: time out value in seconds
155 * mode: "b" for block timeout, "t" for total timeout. (default: b)
156 \*-------------------------------------------------------------------------*/
157 int timeout_meth_settimeout(lua_State *L, p_timeout tm) {
158 double t = luaL_optnumber(L, 2, -1);
159 const char *mode = luaL_optstring(L, 3, "b");
160 switch (*mode) {
161 case 'b':
162 tm->block = t;
163 break;
164 case 'r': case 't':
165 tm->total = t;
166 break;
167 default:
168 luaL_argcheck(L, 0, 3, "invalid timeout mode");
169 break;
170 }
171 lua_pushnumber(L, 1);
172 return 1;
173 }
174
175 /*=========================================================================*\
176 * Test support functions
177 \*=========================================================================*/
178 /*-------------------------------------------------------------------------*\
179 * Returns the time the system has been up, in secconds.
180 \*-------------------------------------------------------------------------*/
181 static int timeout_lua_gettime(lua_State *L)
182 {
183 lua_pushnumber(L, timeout_gettime());
184 return 1;
185 }
186
187 /*-------------------------------------------------------------------------*\
188 * Sleep for n seconds.
189 \*-------------------------------------------------------------------------*/
190 int timeout_lua_sleep(lua_State *L)
191 {
192 double n = luaL_checknumber(L, 1);
193 #ifdef _WIN32
194 Sleep((int)(n*1000));
195 #else
196 struct timespec t, r;
197 t.tv_sec = (int) n;
198 n -= t.tv_sec;
199 t.tv_nsec = (int) (n * 1000000000);
200 if (t.tv_nsec >= 1000000000) t.tv_nsec = 999999999;
201 while (nanosleep(&t, &r) != 0) {
202 t.tv_sec = r.tv_sec;
203 t.tv_nsec = r.tv_nsec;
204 }
205 #endif
206 return 0;
207 }