summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQuentin Carbonneaux2014-08-06 17:34:41 -0400
committerQuentin Carbonneaux2014-08-06 18:00:44 -0400
commitf34630de77662c720401e4b411dc5bf06eb8e3f9 (patch)
tree05f64102f13405b060e07efca3865e101bebeda7
parent856ef05c0a2df889a42b059b4e78bc3126282718 (diff)
add alarm support in evnt (untested)
-rw-r--r--evnt.c89
-rw-r--r--evnt.h19
-rw-r--r--exec.c4
-rw-r--r--main.c2
4 files changed, 100 insertions, 14 deletions
diff --git a/evnt.c b/evnt.c
index c1a215c..e7a54bd 100644
--- a/evnt.c
+++ b/evnt.c
@@ -3,33 +3,68 @@
#include <string.h>
#include <errno.h>
#include <sys/select.h>
+#include <sys/time.h>
#include "evnt.h"
- // mail a jb
-
void die(char *);
-
int exiting;
-static E *elist;
+static void popalrm(void);
+
+static Alrm *ah[MaxAlrms + 1];
+static int na;
+static Evnt *elist;
static int ne;
+static time_t curtime;
+
+int
+ev_alarm(Alrm a)
+{
+ Alrm *a1, *t;
+ int i, j;
+
+ if (na >= MaxAlrms)
+ return 1;
+ a1 = malloc(sizeof (Alrm));
+ assert(a1);
+ *a1 = a;
+ i = ++na;
+ ah[i] = a1;
+ while ((j = i / 2) && ah[j]->t > ah[i]->t) {
+ t = ah[j];
+ ah[j] = ah[i];
+ ah[i] = t;
+ i = j;
+ }
+ return 0;
+}
void
-ev_register(E e)
+ev_register(Evnt e)
{
- elist = realloc(elist, (ne + 1) * sizeof(E));
+ elist = realloc(elist, (ne + 1) * sizeof (Evnt));
assert(elist);
elist[ne] = e;
ne++;
}
+time_t
+ev_time()
+{
+ assert(curtime);
+ return curtime;
+}
+
void
ev_loop()
{
+ struct timeval tv;
+ Alrm *a;
fd_set rfds, wfds;
int i, maxfd, flags;
+ tv.tv_usec = 0;
while (!exiting) {
maxfd = -1;
FD_ZERO(&rfds);
@@ -42,11 +77,26 @@ ev_loop()
if (elist[i].fd > maxfd)
maxfd = elist[i].fd;
}
- if (select(maxfd+1, &rfds, &wfds, 0, 0) == -1) {
+ if (na) {
+ gettimeofday(&tv, 0);
+ if (ah[1]->t <= tv.tv_sec)
+ tv.tv_sec = 0;
+ else
+ tv.tv_sec = ah[1]->t - tv.tv_sec;
+ } else
+ tv.tv_sec = 10000;
+ if (select(maxfd+1, &rfds, &wfds, 0, &tv) == -1) {
if (errno == EINTR)
continue;
die("select error");
}
+ gettimeofday(&tv, 0);
+ curtime = tv.tv_sec;
+ while (na && (a = ah[1])->t <= curtime) {
+ popalrm();
+ a->f(a->t, a->p);
+ free(a);
+ }
for (i=0; i < ne;) {
flags = 0;
if (FD_ISSET(elist[i].fd, &rfds))
@@ -59,10 +109,33 @@ ev_loop()
}
if (elist[i].f(elist[i].fd, flags, elist[i].p)) {
ne--;
- memmove(&elist[i], &elist[i+1], (ne - i) * sizeof(E));
+ memmove(&elist[i], &elist[i+1], (ne - i) * sizeof (Evnt));
continue;
} else
i++;
}
}
}
+
+
+/* clear the first alarm out of the heap */
+static void
+popalrm()
+{
+ Alrm *t;
+ int i, j;
+
+ assert(na);
+ i = 1;
+ ah[i] = ah[na--];
+ while ((j = 2 * i) <= na) {
+ if (ah[j+1]->t < ah[j]->t)
+ j++;
+ if (ah[i]->t <= ah[j]->t)
+ return;
+ t = ah[j];
+ ah[j] = ah[i];
+ ah[i] = t;
+ i = j;
+ }
+}
diff --git a/evnt.h b/evnt.h
index 3b33f81..0c870c9 100644
--- a/evnt.h
+++ b/evnt.h
@@ -1,21 +1,34 @@
#ifndef EVNT_H
#define EVNT_H
-typedef struct e E;
+#include <sys/time.h>
enum {
ERead = 1,
EWrite = 2,
+
+ MaxAlrms = 31,
+};
+
+typedef struct alrm Alrm;
+typedef struct evnt Evnt;
+
+struct alrm {
+ time_t t;
+ void (*f)(time_t, void *);
+ void *p;
};
-struct e {
+
+struct evnt {
int fd;
int flags;
int (*f)(int, int, void *);
void *p;
};
-void ev_register(E);
+int ev_alarm(Alrm);
+void ev_register(Evnt);
void ev_loop(void);
#endif /* ndef EVNT_H */
diff --git a/exec.c b/exec.c
index 0c4661b..4c8bdff 100644
--- a/exec.c
+++ b/exec.c
@@ -462,10 +462,10 @@ run(W *w, EBuf *eb, unsigned p0)
}
eb_commit(w->eb);
if (r->ob)
- ev_register((E){pin[1], EWrite, runev, r});
+ ev_register((Evnt){pin[1], EWrite, runev, r});
else
close(pin[1]);
- ev_register((E){pout[0], ERead, runev, r});
+ ev_register((Evnt){pout[0], ERead, runev, r});
return 0;
}
diff --git a/main.c b/main.c
index c833830..0f966e5 100644
--- a/main.c
+++ b/main.c
@@ -84,7 +84,7 @@ main(int ac, char *av[])
g = &gui_x11;
guifd = g->init();
- ev_register((E){guifd, ERead, gev, 0});
+ ev_register((Evnt){guifd, ERead, gev, 0});
win_init(g);
eb = eb_new();