aboutsummaryrefslogtreecommitdiff
path: root/src/timeout.c
blob: 266a86e0cb040209a19f33036398738a586c6ab0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*=========================================================================*\
* Timeout management functions
\*=========================================================================*/
#include <lua.h>
#include <lauxlib.h>

#include "lspriv.h"
#include "lstm.h"

#include <stdio.h>

#ifdef WIN32
#include <windows.h>
#else
#include <sys/times.h>
#include <time.h>
#include <unistd.h>
#endif

/*=========================================================================*\
* Internal function prototypes
\*=========================================================================*/
#ifdef _DEBUG
static int tm_lua_time(lua_State *L);
static int tm_lua_sleep(lua_State *L);
#endif

/*=========================================================================*\
* Exported functions.
\*=========================================================================*/
/*-------------------------------------------------------------------------*\
* Sets timeout limits
* Input
*   tm: timeout control structure
*   mode: block or return timeout
*   value: timeout value in miliseconds
\*-------------------------------------------------------------------------*/
void tm_set(p_tm tm, int tm_block, int tm_return)
{
    tm->tm_block = tm_block;
    tm->tm_return = tm_return;
}

/*-------------------------------------------------------------------------*\
* Returns timeout limits
* Input
*   tm: timeout control structure
*   mode: block or return timeout
*   value: timeout value in miliseconds
\*-------------------------------------------------------------------------*/
void tm_get(p_tm tm, int *tm_block, int *tm_return)
{
    if (tm_block) *tm_block = tm->tm_block;
    if (tm_return) *tm_return = tm->tm_return;
}

/*-------------------------------------------------------------------------*\
* Determines how much time we have left for the current io operation
* an IO write operation.
* Input
*   tm: timeout control structure
* Returns
*   the number of ms left or -1 if there is no time limit
\*-------------------------------------------------------------------------*/
int tm_getremaining(p_tm tm)
{
    /* no timeout */
    if (tm->tm_block < 0 && tm->tm_return < 0)
        return -1;
    /* there is no block timeout, we use the return timeout */
    else if (tm->tm_block < 0)
        return MAX(tm->tm_return - tm_gettime() + tm->tm_start, 0);
    /* there is no return timeout, we use the block timeout */
    else if (tm->tm_return < 0) 
        return tm->tm_block;
    /* both timeouts are specified */
    else return MIN(tm->tm_block, 
            MAX(tm->tm_return - tm_gettime() + tm->tm_start, 0));
}

/*-------------------------------------------------------------------------*\
* Marks the operation start time in sock structure
* Input
*   tm: timeout control structure
\*-------------------------------------------------------------------------*/
void tm_markstart(p_tm tm)
{
    tm->tm_start = tm_gettime();
    tm->tm_end = tm->tm_start;
}

/*-------------------------------------------------------------------------*\
* Returns the length of the operation in ms
* Input
*   tm: timeout control structure
\*-------------------------------------------------------------------------*/
int tm_getelapsed(p_tm tm)
{
    return tm->tm_end - tm->tm_start;
}

/*-------------------------------------------------------------------------*\
* Gets time in ms, relative to system startup.
* Returns
*   time in ms.
\*-------------------------------------------------------------------------*/
#ifdef WIN32
int tm_gettime(void) 
{
    return GetTickCount();
}
#else
int tm_gettime(void) 
{
    struct tms t;
    return (times(&t)*1000)/CLK_TCK;
}
#endif

/*-------------------------------------------------------------------------*\
* Initializes module
\*-------------------------------------------------------------------------*/
void tm_open(lua_State *L)
{
    (void) L;
#ifdef _DEBUG
    lua_pushcfunction(L, tm_lua_time);
    lua_setglobal(L, "_time");
    lua_pushcfunction(L, tm_lua_sleep);
    lua_setglobal(L, "_sleep");
#endif
}

/*=========================================================================*\
* Test support functions
\*=========================================================================*/
/*-------------------------------------------------------------------------*\
* Returns the time the system has been up, in secconds.
\*-------------------------------------------------------------------------*/
#ifdef _DEBUG
static int tm_lua_time(lua_State *L)
{
    lua_pushnumber(L, tm_gettime()/1000.0);
    return 1;
}

/*-------------------------------------------------------------------------*\
* Sleep for n seconds.
\*-------------------------------------------------------------------------*/
int tm_lua_sleep(lua_State *L)
{
    double n = luaL_check_number(L, 1);
#ifdef WIN32
    Sleep(n*1000);
#else
    sleep(n);
#endif
    return 0;
}
#endif