src/timeout.c

changeset 0
f7d2d78eb424
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/timeout.c	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,155 @@
+/*=========================================================================*\
+* LuaSocket 2.0.2
+* Copyright (C) 2004-2007 Diego Nehab
+*
+* Timeout management functions
+*
+* RCS ID: $Id: timeout.c,v 1.30 2005/10/07 04:40:59 diego Exp $
+\*=========================================================================*/
+#include <stdio.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <time.h>
+#include <sys/time.h>
+#endif
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "timeout.h"
+
+/* 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
+
+/*=========================================================================*\
+* 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
+
+/*-------------------------------------------------------------------------*\
+* 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;
+}
+

mercurial