diff --git a/libuevent/Makefile b/libuevent/Makefile index 99c9afd..26be861 100644 --- a/libuevent/Makefile +++ b/libuevent/Makefile @@ -22,6 +22,7 @@ lua: luauevent.so libuevent.a: libuevent.o $(AR) r $@ $^ + $(CROSS_COMPILE)strip --strip-unneeded $@ libuevent.so.$(MAJOR): libuevent.o $(CC) $(LDFLAGS) -shared -o $@ $^ -Wl,-soname=libuevent @@ -30,7 +31,7 @@ luauevent.so: luauevent.o all $(CC) $(LDFLAGS) -shared -o $@ $^ -L . -l uevent -Wl,-soname=uevent test: all - $(CC) -o test test.c && test + $(CC) -g -o test -D NO_DEBUG test.c libuevent.c && ./test luatest: lua lua test.lua diff --git a/libuevent/libuevent.c b/libuevent/libuevent.c index c2b1ff4..9f2f62e 100644 --- a/libuevent/libuevent.c +++ b/libuevent/libuevent.c @@ -21,6 +21,12 @@ #include "llist.h" #include "libuevent.h" +#ifdef DEBUG +#define Debug(f, args...) printf(f "\n", ##args) +#else +#define Debug(f, args...) +#endif + static clock_t clock_tick = 0; /// Enumerate file handle direction @@ -220,12 +226,16 @@ struct LUETimerH *lueAddTimer(struct LUECtxt * ctxt, int periodMs, ent->dueTime = 0; if (nent && ent->dueTime > periodMs) { + Debug("Insert %d before %d", periodMs, ent->dueTime); lListInsert(&ctxt->timeoutHandlers, nent, ent); nent = NULL; } } - if (nent) + if (nent) + { + Debug("Append %d at end", periodMs); lListAppend(&ctxt->timeoutHandlers, nent); + } ctxt->baseTime = curTime; return ret; @@ -317,18 +327,19 @@ void lueRun(struct LUECtxt *ctxt) { curTime = ctxt->timeSet ? ctxt->setTime : times(NULL); curPeriod = (curTime - ctxt->baseTime) / clock_tick * 1000 - + ((curTime - ctxt->baseTime) % clock_tick) * 1000 / clock_tick; + + ((curTime - ctxt->baseTime) % clock_tick) * 1000 / clock_tick; + Debug("Period for timer execution %d", curPeriod); while((timer = lListHead(&ctxt->timeoutHandlers)) && timer->dueTime <= curPeriod) { timer->handler(ctxt, timer, timer->data); lueRemTimer(ctxt, timer); - // baseTime changes for every lueAddTime + // baseTime changes for every lueAddTimer curPeriod = (curTime - ctxt->baseTime) / clock_tick * 1000 + ((curTime - ctxt->baseTime) % clock_tick) * 1000 / clock_tick; } - lListPurge(&ctxt->timeRem); + lListPurge(&ctxt->timeRem); // Reap timer zombies } // Calculate waiting time @@ -337,6 +348,8 @@ void lueRun(struct LUECtxt *ctxt) else if ((timer = lListHead(&ctxt->timeoutHandlers)) && timer->dueTime > curPeriod) { + Debug("Period from timer head %d - %d -> %d", + timer->dueTime, curPeriod, timer->dueTime - curPeriod); curPeriod = timer->dueTime - curPeriod; } else if (NULL != timer) @@ -346,7 +359,7 @@ void lueRun(struct LUECtxt *ctxt) // Do pipe handlers pollRet = 0; - if (lListHead(&ctxt->fileHandlers)) + if (lListHead(&ctxt->fileHandlers) && !ctxt->exiting) { struct pollfd polls[lListLength(&ctxt->fileHandlers)]; struct LUEFileEventH *ent; @@ -360,6 +373,7 @@ void lueRun(struct LUECtxt *ctxt) polls[ix].revents = 0; ix++; } + Debug("Polling %d fds in %d ms", ix, curPeriod); pollRet = poll(polls, ix, curPeriod); if (pollRet < 0) { @@ -407,11 +421,11 @@ void lueRun(struct LUECtxt *ctxt) poll(NULL, 0, curPeriod); else break; // LUEarently were out of work! - } while (!ctxt->exiting || + } while (!ctxt->exiting); // Wont exit while there is due timers or files - ((timer = lListHead(&ctxt->timeoutHandlers)) && - timer->dueTime <= 0) || pollRet > 0); - //logdebug("LUE exiting - bye"); + //((timer = lListHead(&ctxt->timeoutHandlers)) && + //timer->dueTime <= 0) || pollRet > 0); + Debug("LUE exiting - bye"); } /** diff --git a/libuevent/llist.h b/libuevent/llist.h index e657d72..66cdb51 100644 --- a/libuevent/llist.h +++ b/libuevent/llist.h @@ -54,7 +54,7 @@ if (!(e) || (a)->head == (e)) { \ n->_llNext = (a)->head; \ n->_llPrev = NULL; \ - (a)->head = (e); \ + (a)->head = (n); \ } else { \ n->_llNext = (e); \ n->_llPrev = (e)->_llPrev; \ diff --git a/libuevent/test.c b/libuevent/test.c new file mode 100644 index 0000000..55ebc45 --- /dev/null +++ b/libuevent/test.c @@ -0,0 +1,80 @@ +/** + * @file + * Micro event library libuevent. + * Test & showcase of libuevent + * + * (C) Copyright 2012 flemming.madsen at madsensoft.dk. See libuevent.h + */ +#include +#include +#include "libuevent.h" + +static period; +static client_fd, server_fd, service_fd; +static struct LUETimerH *timeOut; +int readFd, writeFd; + +static timeOutHdl(struct LUECtxt *ctxt, struct LUETimerH *handle, void *data) +{ + timeOut = NULL; + printf("Timeout is exceeded %p\n", data); + lueRemFd(ctxt, readFd); + lueExit(ctxt); +} + +static appTimeout(struct LUECtxt *ctxt, struct LUETimerH *handle, void *data) +{ + printf("Lifetime is exceeded %p\n", data); + exit(1); +} + +static int readCb(struct LUECtxt *ctxt, struct LUEFileEventH *handle, int fd, void *data) +{ + if (timeOut) { + lueRemTimer(ctxt, timeOut); + timeOut = lueAddTimer(ctxt, 950, timeOutHdl, NULL); + } + + char msg[50]; + int cnt = read(readFd, msg, sizeof(msg)); + //printf("READ %.*s %d\n", cnt, msg, cnt); + printf("%.*s.%d ", cnt, msg, cnt); fflush(stdout); + + return 0; +} + +static writeThread(struct LUECtxt *ctxt, struct LUETimerH *handle, void *data) +{ + int cnt = (int) data; + char *msg = "TESTING"; + + write(writeFd, msg, cnt); + //printf("WRITE %.*s %d\n", cnt, msg, cnt); + printf("%d ", cnt); fflush(stdout); + period = cnt + 5; + lueAddTimer(ctxt, period * 100, writeThread, (void *) (cnt + 1)); +} + +main() +{ + struct LUECtxt *ctxt = lueCtxtCreate(); + + timeOut = lueAddTimer(ctxt, 950, timeOutHdl, (void *)1); + lueAddTimer(ctxt, 5000, appTimeout, (void *)2); + + lueAddTimer(ctxt, 500, writeThread, (void *) 1); + + int fd[2]; + pipe(fd); + readFd = fd[0]; + writeFd = fd[1]; + lueAddInput(ctxt, readFd, readCb, NULL); + + lueRun(ctxt); + lueCtxtDestroy(ctxt); + + printf("Period is %d must be 10\n", period); + exit(10 == period ? 0 : 1); +} + +// vim: set sw=3 sts=3 et: