src/timeout.c

changeset 0
f7d2d78eb424
equal deleted inserted replaced
-1:000000000000 0:f7d2d78eb424
1 /*=========================================================================*\
2 * LuaSocket 2.0.2
3 * Copyright (C) 2004-2007 Diego Nehab
4 *
5 * Timeout management functions
6 *
7 * RCS ID: $Id: timeout.c,v 1.30 2005/10/07 04:40:59 diego Exp $
8 \*=========================================================================*/
9 #include <stdio.h>
10
11 #ifdef _WIN32
12 #include <windows.h>
13 #else
14 #include <time.h>
15 #include <sys/time.h>
16 #endif
17
18 #include <lua.h>
19 #include <lauxlib.h>
20
21 #include "timeout.h"
22
23 /* min and max macros */
24 #ifndef MIN
25 #define MIN(x, y) ((x) < (y) ? x : y)
26 #endif
27 #ifndef MAX
28 #define MAX(x, y) ((x) > (y) ? x : y)
29 #endif
30
31 /*=========================================================================*\
32 * Exported functions.
33 \*=========================================================================*/
34 /*-------------------------------------------------------------------------*\
35 * Initialize structure
36 \*-------------------------------------------------------------------------*/
37 void timeout_init(p_timeout tm, double block, double total) {
38 tm->block = block;
39 tm->total = total;
40 }
41
42 /*-------------------------------------------------------------------------*\
43 * Determines how much time we have left for the next system call,
44 * if the previous call was successful
45 * Input
46 * tm: timeout control structure
47 * Returns
48 * the number of ms left or -1 if there is no time limit
49 \*-------------------------------------------------------------------------*/
50 double timeout_get(p_timeout tm) {
51 if (tm->block < 0.0 && tm->total < 0.0) {
52 return -1;
53 } else if (tm->block < 0.0) {
54 double t = tm->total - timeout_gettime() + tm->start;
55 return MAX(t, 0.0);
56 } else if (tm->total < 0.0) {
57 return tm->block;
58 } else {
59 double t = tm->total - timeout_gettime() + tm->start;
60 return MIN(tm->block, MAX(t, 0.0));
61 }
62 }
63
64 /*-------------------------------------------------------------------------*\
65 * Returns time since start of operation
66 * Input
67 * tm: timeout control structure
68 * Returns
69 * start field of structure
70 \*-------------------------------------------------------------------------*/
71 double timeout_getstart(p_timeout tm) {
72 return tm->start;
73 }
74
75 /*-------------------------------------------------------------------------*\
76 * Determines how much time we have left for the next system call,
77 * if the previous call was a failure
78 * Input
79 * tm: timeout control structure
80 * Returns
81 * the number of ms left or -1 if there is no time limit
82 \*-------------------------------------------------------------------------*/
83 double timeout_getretry(p_timeout tm) {
84 if (tm->block < 0.0 && tm->total < 0.0) {
85 return -1;
86 } else if (tm->block < 0.0) {
87 double t = tm->total - timeout_gettime() + tm->start;
88 return MAX(t, 0.0);
89 } else if (tm->total < 0.0) {
90 double t = tm->block - timeout_gettime() + tm->start;
91 return MAX(t, 0.0);
92 } else {
93 double t = tm->total - timeout_gettime() + tm->start;
94 return MIN(tm->block, MAX(t, 0.0));
95 }
96 }
97
98 /*-------------------------------------------------------------------------*\
99 * Marks the operation start time in structure
100 * Input
101 * tm: timeout control structure
102 \*-------------------------------------------------------------------------*/
103 p_timeout timeout_markstart(p_timeout tm) {
104 tm->start = timeout_gettime();
105 return tm;
106 }
107
108 /*-------------------------------------------------------------------------*\
109 * Gets time in s, relative to January 1, 1970 (UTC)
110 * Returns
111 * time in s.
112 \*-------------------------------------------------------------------------*/
113 #ifdef _WIN32
114 double timeout_gettime(void) {
115 FILETIME ft;
116 double t;
117 GetSystemTimeAsFileTime(&ft);
118 /* Windows file time (time since January 1, 1601 (UTC)) */
119 t = ft.dwLowDateTime/1.0e7 + ft.dwHighDateTime*(4294967296.0/1.0e7);
120 /* convert to Unix Epoch time (time since January 1, 1970 (UTC)) */
121 return (t - 11644473600.0);
122 }
123 #else
124 double timeout_gettime(void) {
125 struct timeval v;
126 gettimeofday(&v, (struct timezone *) NULL);
127 /* Unix Epoch time (time since January 1, 1970 (UTC)) */
128 return v.tv_sec + v.tv_usec/1.0e6;
129 }
130 #endif
131
132 /*-------------------------------------------------------------------------*\
133 * Sets timeout values for IO operations
134 * Lua Input: base, time [, mode]
135 * time: time out value in seconds
136 * mode: "b" for block timeout, "t" for total timeout. (default: b)
137 \*-------------------------------------------------------------------------*/
138 int timeout_meth_settimeout(lua_State *L, p_timeout tm) {
139 double t = luaL_optnumber(L, 2, -1);
140 const char *mode = luaL_optstring(L, 3, "b");
141 switch (*mode) {
142 case 'b':
143 tm->block = t;
144 break;
145 case 'r': case 't':
146 tm->total = t;
147 break;
148 default:
149 luaL_argcheck(L, 0, 3, "invalid timeout mode");
150 break;
151 }
152 lua_pushnumber(L, 1);
153 return 1;
154 }
155

mercurial