aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jim-aio.c49
-rw-r--r--jim-eventloop.c49
-rw-r--r--jim-eventloop.h3
3 files changed, 63 insertions, 38 deletions
diff --git a/jim-aio.c b/jim-aio.c
index e189781..87bc042 100644
--- a/jim-aio.c
+++ b/jim-aio.c
@@ -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