luasocket/src/timeout.c

171 lines
5.0 KiB
C
Raw Normal View History

2002-07-03 21:06:54 +02:00
/*=========================================================================*\
* Timeout management functions
* LuaSocket toolkit
2003-03-28 22:08:50 +01:00
*
* RCS ID: $Id$
2002-07-03 21:06:54 +02:00
\*=========================================================================*/
2003-05-25 03:54:13 +02:00
#include <stdio.h>
2002-07-03 21:06:54 +02:00
#include <lua.h>
#include <lauxlib.h>
2003-05-25 03:54:13 +02:00
#include "luasocket.h"
#include "auxiliar.h"
#include "timeout.h"
2002-07-03 21:06:54 +02:00
#ifdef WIN32
#include <windows.h>
#else
#include <sys/times.h>
#include <time.h>
#include <unistd.h>
#endif
/*=========================================================================*\
* Internal function prototypes
\*=========================================================================*/
static int tm_lua_time(lua_State *L);
static int tm_lua_sleep(lua_State *L);
2003-05-25 03:54:13 +02:00
static luaL_reg func[] = {
{ "time", tm_lua_time },
{ "sleep", tm_lua_sleep },
{ NULL, NULL }
};
2002-07-03 21:06:54 +02:00
/*=========================================================================*\
* Exported functions.
\*=========================================================================*/
/*-------------------------------------------------------------------------*\
2003-05-25 03:54:13 +02:00
* Initialize structure
2002-07-03 21:06:54 +02:00
\*-------------------------------------------------------------------------*/
2003-05-25 03:54:13 +02:00
void tm_init(p_tm tm, int block, int total)
2002-07-03 21:06:54 +02:00
{
2003-05-25 03:54:13 +02:00
tm->block = block;
tm->total = total;
2002-07-03 21:06:54 +02:00
}
/*-------------------------------------------------------------------------*\
2003-05-25 03:54:13 +02:00
* Set and get timeout limits
2002-07-03 21:06:54 +02:00
\*-------------------------------------------------------------------------*/
2003-05-25 03:54:13 +02:00
void tm_setblock(p_tm tm, int block)
{ tm->block = block; }
void tm_settotal(p_tm tm, int total)
{ tm->total = total; }
int tm_getblock(p_tm tm)
{ return tm->block; }
int tm_gettotal(p_tm tm)
{ return tm->total; }
int tm_getstart(p_tm tm)
{ return tm->start; }
2002-07-03 21:06:54 +02:00
/*-------------------------------------------------------------------------*\
2003-05-25 03:54:13 +02:00
* Determines how much time we have left for the current operation
2002-07-03 21:06:54 +02:00
* Input
* tm: timeout control structure
* Returns
* the number of ms left or -1 if there is no time limit
\*-------------------------------------------------------------------------*/
2003-05-25 03:54:13 +02:00
int tm_get(p_tm tm)
2002-07-03 21:06:54 +02:00
{
/* no timeout */
2003-05-25 03:54:13 +02:00
if (tm->block < 0 && tm->total < 0)
2002-07-03 21:06:54 +02:00
return -1;
/* there is no block timeout, we use the return timeout */
2003-05-25 03:54:13 +02:00
else if (tm->block < 0)
return MAX(tm->total - tm_gettime() + tm->start, 0);
2002-07-03 21:06:54 +02:00
/* there is no return timeout, we use the block timeout */
2003-05-25 03:54:13 +02:00
else if (tm->total < 0)
return tm->block;
2002-07-03 21:06:54 +02:00
/* both timeouts are specified */
2003-05-25 03:54:13 +02:00
else return MIN(tm->block,
MAX(tm->total - tm_gettime() + tm->start, 0));
2002-07-03 21:06:54 +02:00
}
/*-------------------------------------------------------------------------*\
2003-05-25 03:54:13 +02:00
* Marks the operation start time in structure
2002-07-03 21:06:54 +02:00
* Input
* tm: timeout control structure
\*-------------------------------------------------------------------------*/
void tm_markstart(p_tm tm)
{
2003-05-25 03:54:13 +02:00
tm->start = tm_gettime();
2002-07-03 21:06:54 +02:00
}
/*-------------------------------------------------------------------------*\
* 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)
{
2003-05-25 03:54:13 +02:00
luaL_openlib(L, LUASOCKET_LIBNAME, func, 0);
lua_pop(L, 1);
2003-05-25 03:54:13 +02:00
}
/*-------------------------------------------------------------------------*\
* Sets timeout values for IO operations
* Lua Input: base, time [, mode]
* time: time out value in seconds
* mode: "b" for block timeout, "t" for total timeout. (default: b)
\*-------------------------------------------------------------------------*/
int tm_meth_timeout(lua_State *L, p_tm tm)
{
int ms = lua_isnil(L, 2) ? -1 : (int) (luaL_checknumber(L, 2)*1000.0);
const char *mode = luaL_optstring(L, 3, "b");
switch (*mode) {
case 'b':
tm_setblock(tm, ms);
break;
case 'r': case 't':
tm_settotal(tm, ms);
break;
default:
luaL_argcheck(L, 0, 3, "invalid timeout mode");
break;
}
return 0;
2002-07-03 21:06:54 +02:00
}
/*=========================================================================*\
* Test support functions
\*=========================================================================*/
/*-------------------------------------------------------------------------*\
* Returns the time the system has been up, in secconds.
\*-------------------------------------------------------------------------*/
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)
{
2003-03-21 00:11:25 +01:00
double n = luaL_checknumber(L, 1);
2002-07-03 21:06:54 +02:00
#ifdef WIN32
2003-03-21 02:07:23 +01:00
Sleep((int)n*1000);
2002-07-03 21:06:54 +02:00
#else
2003-03-21 02:07:23 +01:00
sleep((int)n);
2002-07-03 21:06:54 +02:00
#endif
return 0;
}