diff options
-rw-r--r-- | jim-aio.c | 49 | ||||
-rw-r--r-- | jim-eventloop.c | 49 | ||||
-rw-r--r-- | jim-eventloop.h | 3 |
3 files changed, 63 insertions, 38 deletions
@@ -168,9 +168,6 @@ typedef struct AioFile int type; int flags; /* AIO_KEEPOPEN? keep FILE* */ int fd; - Jim_Obj *rEvent; - Jim_Obj *wEvent; - Jim_Obj *eEvent; int addr_family; void *ssl; const JimAioFopsType *fops; @@ -1355,50 +1352,26 @@ static int aio_cmd_buffering(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } #ifdef jim_ext_eventloop -static void JimAioFileEventFinalizer(Jim_Interp *interp, void *clientData) -{ - Jim_Obj **objPtrPtr = clientData; - - Jim_DecrRefCount(interp, *objPtrPtr); - *objPtrPtr = NULL; -} - -static int JimAioFileEventHandler(Jim_Interp *interp, void *clientData, int mask) -{ - Jim_Obj **objPtrPtr = clientData; - - return Jim_EvalObjBackground(interp, *objPtrPtr); -} - -static int aio_eventinfo(Jim_Interp *interp, AioFile * af, unsigned mask, Jim_Obj **scriptHandlerObj, +static int aio_eventinfo(Jim_Interp *interp, AioFile * af, unsigned mask, int argc, Jim_Obj * const *argv) { if (argc == 0) { /* Return current script */ - if (*scriptHandlerObj) { - Jim_SetResult(interp, *scriptHandlerObj); + Jim_Obj *objPtr = Jim_FindFileHandler(interp, af->fd, mask); + if (objPtr) { + Jim_SetResult(interp, objPtr); } return JIM_OK; } - if (*scriptHandlerObj) { - /* Delete old handler */ - Jim_DeleteFileHandler(interp, af->fd, mask); - } + /* Delete old handler */ + Jim_DeleteFileHandler(interp, af->fd, mask); /* Now possibly add the new script(s) */ - if (Jim_Length(argv[0]) == 0) { - /* Empty script, so done */ - return JIM_OK; + if (Jim_Length(argv[0])) { + Jim_CreateScriptFileHandler(interp, af->fd, mask, argv[0]); } - /* A new script to add */ - Jim_IncrRefCount(argv[0]); - *scriptHandlerObj = argv[0]; - - Jim_CreateFileHandler(interp, af->fd, mask, - JimAioFileEventHandler, scriptHandlerObj, JimAioFileEventFinalizer); - return JIM_OK; } @@ -1406,21 +1379,21 @@ static int aio_cmd_readable(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { AioFile *af = Jim_CmdPrivData(interp); - return aio_eventinfo(interp, af, JIM_EVENT_READABLE, &af->rEvent, argc, argv); + return aio_eventinfo(interp, af, JIM_EVENT_READABLE, argc, argv); } static int aio_cmd_writable(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { AioFile *af = Jim_CmdPrivData(interp); - return aio_eventinfo(interp, af, JIM_EVENT_WRITABLE, &af->wEvent, argc, argv); + return aio_eventinfo(interp, af, JIM_EVENT_WRITABLE, argc, argv); } static int aio_cmd_onexception(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { AioFile *af = Jim_CmdPrivData(interp); - return aio_eventinfo(interp, af, JIM_EVENT_EXCEPTION, &af->eEvent, argc, argv); + return aio_eventinfo(interp, af, JIM_EVENT_EXCEPTION, argc, argv); } #endif diff --git a/jim-eventloop.c b/jim-eventloop.c index 78aae12..1a97191 100644 --- a/jim-eventloop.c +++ b/jim-eventloop.c @@ -148,6 +148,16 @@ int Jim_EvalObjBackground(Jim_Interp *interp, Jim_Obj *scriptObjPtr) } +/** + * Register a file event handler on the given file descriptor with the given mask + * (may be 1 or more of JIM_EVENT_xxx) + * + * When the event occurs, proc is called with clientData and the mask of events that occurred. + * When the filehandler is removed, finalizerProc is called. + * + * Note that no check is made that only one handler is registered for the given + * event(s). + */ void Jim_CreateFileHandler(Jim_Interp *interp, int fd, int mask, Jim_FileProc * proc, void *clientData, Jim_EventFinalizerProc * finalizerProc) { @@ -164,6 +174,45 @@ void Jim_CreateFileHandler(Jim_Interp *interp, int fd, int mask, eventLoop->fileEventHead = fe; } +static int JimEventHandlerScript(Jim_Interp *interp, void *clientData, int mask) +{ + return Jim_EvalObjBackground(interp, (Jim_Obj *)clientData); +} + +static void JimEventHandlerScriptFinalize(Jim_Interp *interp, void *clientData) +{ + Jim_DecrRefCount(interp, (Jim_Obj *)clientData); +} + +/** + * A convenience version of Jim_CreateFileHandler() which evaluates + * scriptObj with Jim_EvalObjBackground() when the event occurs. + */ +void Jim_CreateScriptFileHandler(Jim_Interp *interp, int fd, int mask, + Jim_Obj *scriptObj) +{ + Jim_IncrRefCount(scriptObj); + Jim_CreateFileHandler(interp, fd, mask, JimEventHandlerScript, scriptObj, JimEventHandlerScriptFinalize); +} + +/** + * If there is a file handler registered with the given mask, return the clientData + * for the (first) handler. + * Otherwise return NULL. + */ +void *Jim_FindFileHandler(Jim_Interp *interp, int fd, int mask) +{ + Jim_FileEvent *fe; + Jim_EventLoop *eventLoop = Jim_GetAssocData(interp, "eventloop"); + + for (fe = eventLoop->fileEventHead; fe; fe = fe->next) { + if (fe->fd == fd && (fe->mask & mask)) { + return fe->clientData; + } + } + return NULL; +} + /** * Removes all event handlers for 'handle' that match 'mask'. */ diff --git a/jim-eventloop.h b/jim-eventloop.h index 545ef4d..f2b2abf 100644 --- a/jim-eventloop.h +++ b/jim-eventloop.h @@ -64,6 +64,8 @@ JIM_EXPORT void Jim_CreateFileHandler (Jim_Interp *interp, int fd, int mask, Jim_FileProc *proc, void *clientData, Jim_EventFinalizerProc *finalizerProc); +JIM_EXPORT void Jim_CreateScriptFileHandler(Jim_Interp *interp, + int fd, int mask, Jim_Obj *scriptObj); JIM_EXPORT void Jim_DeleteFileHandler (Jim_Interp *interp, int fd, int mask); JIM_EXPORT jim_wide Jim_CreateTimeHandler (Jim_Interp *interp, @@ -71,6 +73,7 @@ JIM_EXPORT jim_wide Jim_CreateTimeHandler (Jim_Interp *interp, Jim_TimeProc *proc, void *clientData, Jim_EventFinalizerProc *finalizerProc); JIM_EXPORT jim_wide Jim_DeleteTimeHandler (Jim_Interp *interp, jim_wide id); +JIM_EXPORT void *Jim_FindFileHandler(Jim_Interp *interp, int fd, int mask); #define JIM_FILE_EVENTS 1 #define JIM_TIME_EVENTS 2 |