diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/timeout.c	Tue Aug 26 18:40:01 2008 -0700
@@ -0,0 +1,207 @@
+/*=========================================================================*\
+* Timeout management functions
+* LuaSocket toolkit
+*
+* RCS ID: $Id: timeout.c,v 1.30 2005/10/07 04:40:59 diego Exp $
+\*=========================================================================*/
+#include <stdio.h>
+
+#include "lua.h"
+#include "lauxlib.h"
+
+#include "auxiliar.h"
+#include "timeout.h"
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <time.h>
+#include <sys/time.h>
+#endif
+
+/* min and max macros */
+#ifndef MIN
+#define MIN(x, y) ((x) < (y) ? x : y)
+#endif
+#ifndef MAX
+#define MAX(x, y) ((x) > (y) ? x : y)
+#endif
+
+/*=========================================================================*\
+* Internal function prototypes
+\*=========================================================================*/
+static int timeout_lua_gettime(lua_State *L);
+static int timeout_lua_sleep(lua_State *L);
+
+static luaL_reg func[] = {
+    { "gettime", timeout_lua_gettime },
+    { "sleep", timeout_lua_sleep },
+    { NULL, NULL }
+};
+
+/*=========================================================================*\
+* Exported functions.
+\*=========================================================================*/
+/*-------------------------------------------------------------------------*\
+* Initialize structure
+\*-------------------------------------------------------------------------*/
+void timeout_init(p_timeout tm, double block, double total) {
+    tm->block = block;
+    tm->total = total;
+}
+
+/*-------------------------------------------------------------------------*\
+* Determines how much time we have left for the next system call,
+* if the previous call was successful 
+* Input
+*   tm: timeout control structure
+* Returns
+*   the number of ms left or -1 if there is no time limit
+\*-------------------------------------------------------------------------*/
+double timeout_get(p_timeout tm) {
+    if (tm->block < 0.0 && tm->total < 0.0) {
+        return -1;
+    } else if (tm->block < 0.0) {
+        double t = tm->total - timeout_gettime() + tm->start;
+        return MAX(t, 0.0);
+    } else if (tm->total < 0.0) {
+        return tm->block;
+    } else {
+        double t = tm->total - timeout_gettime() + tm->start;
+        return MIN(tm->block, MAX(t, 0.0));
+    }
+}
+
+/*-------------------------------------------------------------------------*\
+* Returns time since start of operation
+* Input
+*   tm: timeout control structure
+* Returns
+*   start field of structure
+\*-------------------------------------------------------------------------*/
+double timeout_getstart(p_timeout tm) {
+    return tm->start;
+}
+
+/*-------------------------------------------------------------------------*\
+* Determines how much time we have left for the next system call,
+* if the previous call was a failure
+* Input
+*   tm: timeout control structure
+* Returns
+*   the number of ms left or -1 if there is no time limit
+\*-------------------------------------------------------------------------*/
+double timeout_getretry(p_timeout tm) {
+    if (tm->block < 0.0 && tm->total < 0.0) {
+        return -1;
+    } else if (tm->block < 0.0) {
+        double t = tm->total - timeout_gettime() + tm->start;
+        return MAX(t, 0.0);
+    } else if (tm->total < 0.0) {
+        double t = tm->block - timeout_gettime() + tm->start;
+        return MAX(t, 0.0);
+    } else {
+        double t = tm->total - timeout_gettime() + tm->start;
+        return MIN(tm->block, MAX(t, 0.0));
+    }
+}
+
+/*-------------------------------------------------------------------------*\
+* Marks the operation start time in structure 
+* Input
+*   tm: timeout control structure
+\*-------------------------------------------------------------------------*/
+p_timeout timeout_markstart(p_timeout tm) {
+    tm->start = timeout_gettime();
+    return tm;
+}
+
+/*-------------------------------------------------------------------------*\
+* Gets time in s, relative to January 1, 1970 (UTC) 
+* Returns
+*   time in s.
+\*-------------------------------------------------------------------------*/
+#ifdef _WIN32
+double timeout_gettime(void) {
+    FILETIME ft;
+    double t;
+    GetSystemTimeAsFileTime(&ft);
+    /* Windows file time (time since January 1, 1601 (UTC)) */
+    t  = ft.dwLowDateTime/1.0e7 + ft.dwHighDateTime*(4294967296.0/1.0e7);
+    /* convert to Unix Epoch time (time since January 1, 1970 (UTC)) */
+    return (t - 11644473600.0);
+}
+#else
+double timeout_gettime(void) {
+    struct timeval v;
+    gettimeofday(&v, (struct timezone *) NULL);
+    /* Unix Epoch time (time since January 1, 1970 (UTC)) */
+    return v.tv_sec + v.tv_usec/1.0e6;
+}
+#endif
+
+/*-------------------------------------------------------------------------*\
+* Initializes module
+\*-------------------------------------------------------------------------*/
+int timeout_open(lua_State *L) {
+    luaL_openlib(L, NULL, func, 0);
+    return 0;
+}
+
+/*-------------------------------------------------------------------------*\
+* 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 timeout_meth_settimeout(lua_State *L, p_timeout tm) {
+    double t = luaL_optnumber(L, 2, -1);
+    const char *mode = luaL_optstring(L, 3, "b");
+    switch (*mode) {
+        case 'b':
+            tm->block = t; 
+            break;
+        case 'r': case 't':
+            tm->total = t;
+            break;
+        default:
+            luaL_argcheck(L, 0, 3, "invalid timeout mode");
+            break;
+    }
+    lua_pushnumber(L, 1);
+    return 1;
+}
+
+/*=========================================================================*\
+* Test support functions
+\*=========================================================================*/
+/*-------------------------------------------------------------------------*\
+* Returns the time the system has been up, in secconds.
+\*-------------------------------------------------------------------------*/
+static int timeout_lua_gettime(lua_State *L)
+{
+    lua_pushnumber(L, timeout_gettime());
+    return 1;
+}
+
+/*-------------------------------------------------------------------------*\
+* Sleep for n seconds.
+\*-------------------------------------------------------------------------*/
+int timeout_lua_sleep(lua_State *L)
+{
+    double n = luaL_checknumber(L, 1);
+#ifdef _WIN32
+    Sleep((int)(n*1000));
+#else
+    struct timespec t, r;
+    t.tv_sec = (int) n;
+    n -= t.tv_sec;
+    t.tv_nsec = (int) (n * 1000000000);
+    if (t.tv_nsec >= 1000000000) t.tv_nsec = 999999999;
+    while (nanosleep(&t, &r) != 0) {
+        t.tv_sec = r.tv_sec;
+        t.tv_nsec = r.tv_nsec;
+    }
+#endif
+    return 0;
+}