aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--jim-eventloop.c130
-rw-r--r--jim-eventloop.h14
3 files changed, 118 insertions, 35 deletions
diff --git a/ChangeLog b/ChangeLog
index d73ec12..72d1944 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2008-07-07 Uwe Klein <uklein@klein-messgeraete.de>
+
+ * changes to jim-eventloop.[ch]
+ * fix negative displacement in timeout computation for select
+ * add basic support for the fileevent stuff [ used from jim-aio ]
+ * add basic support for signal handling / actions
+ * add basic support for timer [via after] restart, cancel
+ and returning the remaining time for cancled events
+
2008-07-07 oharboe
* src/jim.c: remove bogus return value from if {[expr]} {xx} when
diff --git a/jim-eventloop.c b/jim-eventloop.c
index 7fbf571..4a7acba 100644
--- a/jim-eventloop.c
+++ b/jim-eventloop.c
@@ -33,6 +33,9 @@
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
+#include <sys/select.h>
+#include <errno.h>
+ extern int errno;
/* --- */
/* File event structure */
@@ -48,6 +51,8 @@ typedef struct Jim_FileEvent {
/* Time event structure */
typedef struct Jim_TimeEvent {
jim_wide id; /* time event identifier. */
+ int mode; /* restart, repetitive .. UK */
+ long initialms; /* initial relativ timer value UK */
long when_sec; /* seconds */
long when_ms; /* milliseconds */
Jim_TimeProc *timeProc;
@@ -70,6 +75,7 @@ void Jim_CreateFileHandler(Jim_Interp *interp, void *handle, int mask,
Jim_FileEvent *fe;
Jim_EventLoop *eventLoop = Jim_GetAssocData(interp, "eventloop");
+ // fprintf(stderr,"rein\n");
fe = Jim_Alloc(sizeof(*fe));
fe->handle = handle;
fe->mask = mask;
@@ -78,6 +84,7 @@ void Jim_CreateFileHandler(Jim_Interp *interp, void *handle, int mask,
fe->clientData = clientData;
fe->next = eventLoop->fileEventHead;
eventLoop->fileEventHead = fe;
+ // fprintf(stderr,"raus\n");
}
void Jim_DeleteFileHandler(Jim_Interp *interp, void *handle)
@@ -102,6 +109,16 @@ void Jim_DeleteFileHandler(Jim_Interp *interp, void *handle)
}
}
+// The same for signals.
+void Jim_CreateSignalHandler(Jim_Interp *interp, int signum,
+ Jim_FileProc *proc, void *clientData,
+ Jim_EventFinalizerProc *finalizerProc)
+{
+}
+void Jim_DeleteSignalHandler(Jim_Interp *interp, int signum)
+{
+}
+
/* That's another part of this extension that needs to be ported
* to WIN32. */
static void JimGetTime(long *seconds, long *milliseconds)
@@ -126,6 +143,8 @@ jim_wide Jim_CreateTimeHandler(Jim_Interp *interp, jim_wide milliseconds,
te = Jim_Alloc(sizeof(*te));
te->id = id;
+ te->mode = 0;
+ te->initialms = milliseconds;
te->when_sec = cur_sec + milliseconds/1000;
te->when_ms = cur_ms + milliseconds%1000;
if (te->when_ms >= 1000) {
@@ -140,14 +159,24 @@ jim_wide Jim_CreateTimeHandler(Jim_Interp *interp, jim_wide milliseconds,
return id;
}
-int Jim_DeleteTimeHandler(Jim_Interp *interp, jim_wide id)
+jim_wide Jim_DeleteTimeHandler(Jim_Interp *interp, jim_wide id)
{
Jim_TimeEvent *te, *prev = NULL;
Jim_EventLoop *eventLoop = Jim_GetAssocData(interp, "eventloop");
+ long cur_sec, cur_ms;
+ jim_wide remain ;
+
+ JimGetTime(&cur_sec, &cur_ms);
te = eventLoop->timeEventHead;
+ if (id >= eventLoop->timeEventNextId)
+ return -2; /* wrong event ID */
while(te) {
if (te->id == id) {
+ remain = (te->when_sec - cur_sec) * 1000;
+ remain += (te->when_ms - cur_ms) ;
+ remain = (remain < 0) ? 0 : remain ;
+
if (prev == NULL)
eventLoop->timeEventHead = te->next;
else
@@ -155,12 +184,12 @@ int Jim_DeleteTimeHandler(Jim_Interp *interp, jim_wide id)
if (te->finalizerProc)
te->finalizerProc(interp, te->clientData);
Jim_Free(te);
- return JIM_OK;
+ return remain;
}
prev = te;
te = te->next;
}
- return JIM_ERR; /* NO event with the specified ID found */
+ return -1; /* NO event with the specified ID found */
}
/* Search the first timer to fire.
@@ -217,9 +246,10 @@ int Jim_ProcessEvents(Jim_Interp *interp, int flags)
/* Check file events */
while (fe != NULL) {
- int fd = (int) fe->handle;
+ int fd = fileno(fe->handle);
- if (fe->mask & JIM_EVENT_READABLE) FD_SET(fd, &rfds);
+ if (fe->mask & JIM_EVENT_READABLE)
+ FD_SET(fd, &rfds);
if (fe->mask & JIM_EVENT_WRITABLE) FD_SET(fd, &wfds);
if (fe->mask & JIM_EVENT_EXCEPTION) FD_SET(fd, &efds);
if (maxfd < fd) maxfd = fd;
@@ -234,6 +264,7 @@ int Jim_ProcessEvents(Jim_Interp *interp, int flags)
int retval;
Jim_TimeEvent *shortest;
struct timeval tv, *tvp;
+ jim_wide dt;
shortest = JimSearchNearestTimer(eventLoop);
if (shortest) {
@@ -243,22 +274,32 @@ int Jim_ProcessEvents(Jim_Interp *interp, int flags)
* timer to fire. */
JimGetTime(&now_sec, &now_ms);
tvp = &tv;
- tvp->tv_sec = shortest->when_sec - now_sec;
- if (shortest->when_ms < now_ms) {
- tvp->tv_usec = ((shortest->when_ms+1000) - now_ms)*1000;
- tvp->tv_sec --;
- } else {
- tvp->tv_usec = (shortest->when_ms - now_ms)*1000;
- }
+ dt = 1000 * (shortest->when_sec - now_sec);
+ dt += ( shortest->when_ms - now_ms);
+ if (dt < 0) {
+ dt = 1;
+ }
+ tvp->tv_sec = dt / 1000;
+ tvp->tv_usec = dt % 1000;
+ // fprintf(stderr,"Next %d.% 8d\n",(int)tvp->tv_sec,(int)tvp->tv_usec);
} else {
tvp = NULL; /* wait forever */
+ // fprintf(stderr,"No Event\n");
}
retval = select(maxfd+1, &rfds, &wfds, &efds, tvp);
- if (retval) {
+ if (retval < 0) {
+ switch (errno) {
+ case EINTR: fprintf(stderr,"select EINTR\n"); break;
+ case EINVAL: fprintf(stderr,"select EINVAL\n"); break;
+ case ENOMEM: fprintf(stderr,"select ENOMEM\n"); break;
+ }
+ } else if (retval > 0) {
fe = eventLoop->fileEventHead;
while(fe != NULL) {
- int fd = (int) fe->handle;
+ int fd = fileno(fe->handle);
+
+ // fprintf(stderr,"fd: %d mask: %02x \n",fd,fe->mask);
if ((fe->mask & JIM_EVENT_READABLE && FD_ISSET(fd, &rfds)) ||
(fe->mask & JIM_EVENT_WRITABLE && FD_ISSET(fd, &wfds)) ||
@@ -266,8 +307,11 @@ int Jim_ProcessEvents(Jim_Interp *interp, int flags)
{
int mask = 0;
- if (fe->mask & JIM_EVENT_READABLE && FD_ISSET(fd, &rfds))
+ if (fe->mask & JIM_EVENT_READABLE && FD_ISSET(fd, &rfds)) {
mask |= JIM_EVENT_READABLE;
+ if ((fe->mask & JIM_EVENT_FEOF) && feof(fe->handle))
+ mask |= JIM_EVENT_FEOF;
+ }
if (fe->mask & JIM_EVENT_WRITABLE && FD_ISSET(fd, &wfds))
mask |= JIM_EVENT_WRITABLE;
if (fe->mask & JIM_EVENT_EXCEPTION && FD_ISSET(fd, &efds))
@@ -399,23 +443,51 @@ static int JimELAfterCommand(Jim_Interp *interp, int argc,
{
jim_wide ms, id;
Jim_Obj *objPtr, *idObjPtr;
-
- if (argc != 3) {
- Jim_WrongNumArgs(interp, 1, argv, "after milliseconds script");
+ const char *options[] = {
+ "info", "cancel", "restart", "expire", NULL
+ };
+ enum {INFO, CANCEL, RESTART, EXPIRE, CREATE };
+ int option = CREATE ;
+
+ if (argc < 3) {
+ Jim_WrongNumArgs(interp, 1, argv, "<after milliseconds> script");
return JIM_ERR;
}
if (Jim_GetWide(interp, argv[1], &ms) != JIM_OK)
+ if (Jim_GetEnum(interp, argv[1], options, &option, "after options",
+ JIM_ERRMSG) != JIM_OK)
+ return JIM_ERR;
+ switch (option) {
+ case CREATE:
+ Jim_IncrRefCount(argv[2]);
+ id = Jim_CreateTimeHandler(interp, ms, JimAfterTimeHandler, argv[2],
+ JimAfterTimeEventFinalizer);
+ objPtr = Jim_NewStringObj(interp, NULL, 0);
+ Jim_AppendString(interp, objPtr, "after#", -1);
+ idObjPtr = Jim_NewIntObj(interp, id);
+ Jim_IncrRefCount(idObjPtr);
+ Jim_AppendObj(interp, objPtr, idObjPtr);
+ Jim_DecrRefCount(interp, idObjPtr);
+ Jim_SetResult(interp, objPtr);
+ return JIM_OK;
+ case CANCEL:
+ {
+ int tlen ;
+ jim_wide remain = 0;
+ const char *tok = Jim_GetString(argv[2], &tlen);
+ if ( sscanf(tok,"after#%lld",&id) == 1) {
+ remain = Jim_DeleteTimeHandler(interp, id);
+ if (remain > -2) {
+ Jim_SetResult(interp, Jim_NewIntObj(interp, remain));
+ return JIM_OK;
+ }
+ }
+ Jim_SetResultString(interp, "invalid event" , -1);
return JIM_ERR;
- Jim_IncrRefCount(argv[2]);
- id = Jim_CreateTimeHandler(interp, ms, JimAfterTimeHandler, argv[2],
- JimAfterTimeEventFinalizer);
- objPtr = Jim_NewStringObj(interp, NULL, 0);
- Jim_AppendString(interp, objPtr, "after#", -1);
- idObjPtr = Jim_NewIntObj(interp, id);
- Jim_IncrRefCount(idObjPtr);
- Jim_AppendObj(interp, objPtr, idObjPtr);
- Jim_DecrRefCount(interp, idObjPtr);
- Jim_SetResult(interp, objPtr);
+ }
+ default:
+ fprintf(stderr,"unserviced option to after %d\n",option);
+ }
return JIM_OK;
}
@@ -430,7 +502,7 @@ int Jim_OnLoad(Jim_Interp *interp)
eventLoop = Jim_Alloc(sizeof(*eventLoop));
eventLoop->fileEventHead = NULL;
eventLoop->timeEventHead = NULL;
- eventLoop->timeEventNextId = 0;
+ eventLoop->timeEventNextId = 1;
Jim_SetAssocData(interp, "eventloop", JimELAssocDataDeleProc, eventLoop);
Jim_CreateCommand(interp, "vwait", JimELVwaitCommand, NULL, NULL);
diff --git a/jim-eventloop.h b/jim-eventloop.h
index 80cf113..caf89d7 100644
--- a/jim-eventloop.h
+++ b/jim-eventloop.h
@@ -31,6 +31,7 @@
#define __JIM_EVENTLOOP_H__
typedef int Jim_FileProc(Jim_Interp *interp, void *clientData, int mask);
+typedef int Jim_SignalProc(Jim_Interp *interp, void *clientData, void *msg);
typedef void Jim_TimeProc(Jim_Interp *interp, void *clientData);
typedef void Jim_EventFinalizerProc(Jim_Interp *interp, void *clientData);
@@ -38,6 +39,7 @@ typedef void Jim_EventFinalizerProc(Jim_Interp *interp, void *clientData);
#define JIM_EVENT_READABLE 1
#define JIM_EVENT_WRITABLE 2
#define JIM_EVENT_EXCEPTION 4
+#define JIM_EVENT_FEOF 8
#ifndef __JIM_EVENTLOOP_CORE__
# if defined JIM_EXTENSION || defined JIM_EMBEDDED
@@ -62,7 +64,7 @@ JIM_STATIC jim_wide JIM_API(Jim_CreateTimeHandler) (Jim_Interp *interp,
jim_wide milliseconds,
Jim_TimeProc *proc, void *clientData,
Jim_EventFinalizerProc *finalizerProc);
-JIM_STATIC int JIM_API(Jim_DeleteTimeHandler) (Jim_Interp *interp, jim_wide id);
+JIM_STATIC jim_wide JIM_API(Jim_DeleteTimeHandler) (Jim_Interp *interp, jim_wide id);
JIM_STATIC int JIM_API(Jim_ProcessEvents) (Jim_Interp *interp, int flags);
#undef JIM_STATIC
@@ -77,11 +79,11 @@ JIM_STATIC int JIM_API(Jim_ProcessEvents) (Jim_Interp *interp, int flags);
/* This must be included "inline" inside the extension */
static void Jim_ImportEventloopAPI(Jim_Interp *interp)
{
- JIM_GET_API(Jim_CreateFileHandler);
- JIM_GET_API(Jim_DeleteFileHandler);
- JIM_GET_API(Jim_CreateTimeHandler);
- JIM_GET_API(Jim_DeleteTimeHandler);
- JIM_GET_API(Jim_ProcessEvents);
+ JIM_GET_API(CreateFileHandler);
+ JIM_GET_API(DeleteFileHandler);
+ JIM_GET_API(CreateTimeHandler);
+ JIM_GET_API(DeleteTimeHandler);
+ JIM_GET_API(ProcessEvents);
}
#endif /* defined JIM_EXTENSION || defined JIM_EMBEDDED */
#undef JIM_GET_API