diff --git a/http/http_event.c b/http/http_event.c
index 796e860..fcb1154 100644
--- a/http/http_event.c
+++ b/http/http_event.c
@@ -23,34 +23,80 @@ s32 http_event_add (struct event *ev, s_time *time)
return event_add(ev, &tv);
}
-void http_event_callback (int fd, short events, void *arg)
+/* http_event_callback
+ expects a tag of the form
+ {fn (fd, events, socket_buf) {void},
+ arg} */
+void http_event_callback (int fd, short events, void *tag_tuple)
{
- s_call call;
+ s_tag *arg;
+ s_list *arguments;
+ s_list *events_list;
+ s_fn *fn;
+ s_tag *tag;
+ s_tag tmp;
+ tag = tag_tuple;
+ if (tag->type != TAG_TUPLE ||
+ tag->data.tuple.count != 2 ||
+ tag->data.tuple.tag[0].type != TAG_FN) {
+ err_puts("http_event_callback: invalid arg");
+ assert(! "http_event_callback: invalid arg");
+ abort();
+ }
+ fn = &tag->data.tuple.tag[0].data.fn;
+ arg = tag->data.tuple.tag + 1;
+ events_list = NULL;
+ if (events & EV_WRITE)
+ events_list = list_new_sym(&g_sym_write, events_list);
+ if (events & EV_READ)
+ events_list = list_new_sym(&g_sym_read, events_list);
+ if (events & EV_SIGNAL)
+ events_list = list_new_sym(&g_sym_signal, events_list);
+ if (events & EV_TIMEOUT)
+ events_list = list_new_sym(&g_sym_timeout, events_list);
+ arguments = list_new_s32(fd, list_new_list
+ (events_list, list_new_tag_copy
+ (arg, NULL)));
+ if (! env_eval_call_fn_args(&g_kc3_env, fn, arguments, &tmp)) {
+ err_puts("http_event_callback: callback failed");
+ assert(! "http_event_callback: callback failed");
+ abort();
+ }
+ tag_clean(&tmp);
}
struct event * http_event_new (s32 fd, const s_list *events,
- const s_fn *fn, s_tag *arg)
+ const s_fn *callback, s_tag *arg)
{
const s_list *e;
struct event *ev;
+ s_tag *tag;
ev = alloc(sizeof(*ev));
if (! ev)
return NULL;
events_s16 = 0;
e = events;
while (e) {
- if (e->tag.type != TAG_SYM) {
- err_write_1("http_event_new: invalid event list: ");
- err_inspect_list(&events);
- assert(! "http_event_new: invalid event list");
- return NULL;
- }
- if (e->tag.data.sym ==
+ if (e->tag.type != TAG_SYM)
+ goto invalid_event_list;
+ if (e->tag.data.sym == &g_sym_read)
+ e |= EV_READ;
+ else if (e->tag.data.sym == &g_sym_write)
+ e |= EV_WRITE;
+ else
+ goto invalid_event_list;
e = list_next(e);
}
- event_set(ev, fd, events_s16, (void (*) (int, short, void *)) cfn->ptr.f,
- arg);
+ tag = tag_new_tuple(2);
+ tag_init_fn_copy(tag->data.tuple.tag, callback);
+ tag_init_copy(tag->data.tuple.tag + 1, tag);
+ event_set(ev, fd, events_s16, http_event_callback, tag);
return ev;
+ invalid_event_list:
+ err_write_1("http_event_new: invalid event list: ");
+ err_inspect_list(&events);
+ assert(! "http_event_new: invalid event list");
+ return NULL;
}
/*
diff --git a/http/http_event.h b/http/http_event.h
index fa22bb4..c6caf8b 100644
--- a/http/http_event.h
+++ b/http/http_event.h
@@ -17,7 +17,7 @@
/* Heap-allocation functions, call http_event_delete after use. */
void http_event_delete (struct event *ev);
-struct event * http_event_new (s32 fd, s16 event, const s_cfn *cfn,
+struct event * http_event_new (s32 fd, s_list *events, const s_fn *fn,
s_tag *arg);
s32 http_event_add (struct event *ev, s_time *time);
diff --git a/libkc3/sym.c b/libkc3/sym.c
index 0182b99..4ccfa4e 100644
--- a/libkc3/sym.c
+++ b/libkc3/sym.c
@@ -101,10 +101,12 @@ const s_sym g_sym_operator_pin = {{{NULL}, 12, {"operator_pin"}}};
const s_sym g_sym_operator_precedence =
{{{NULL}, 19, {"operator_precedence"}}};
const s_sym g_sym_r = {{{NULL}, 1, {"r"}}};
+const s_sym g_sym_read = {{{NULL}, 4, {"read"}}};
const s_sym g_sym_right = {{{NULL}, 5, {"right"}}};
const s_sym g_sym_rw = {{{NULL}, 2, {"rw"}}};
const s_sym g_sym_rwx = {{{NULL}, 3, {"rwx"}}};
const s_sym g_sym_rx = {{{NULL}, 2, {"rx"}}};
+const s_sym g_sym_signal = {{{NULL}, 6, {"signal"}}};
const s_sym g_sym_special_operator =
{{{NULL}, 16, {"special_operator"}}};
const s_sym g_sym_str = {{{NULL}, 3, {"str"}}};
@@ -113,7 +115,9 @@ const s_sym g_sym_sym = {{{NULL}, 3, {"sym"}}};
const s_sym g_sym_symbol = {{{NULL}, 6, {"symbol"}}};
const s_sym g_sym_symbol_value = {{{NULL}, 12, {"symbol_value"}}};
const s_sym g_sym_then = {{{NULL}, 4, {"then"}}};
+const s_sym g_sym_timeout = {{{NULL}, 7, {"timeout"}}};
const s_sym g_sym_w = {{{NULL}, 1, {"w"}}};
+const s_sym g_sym_write = {{{NULL}, 5, {"write"}}};
const s_sym g_sym_wx = {{{NULL}, 2, {"wx"}}};
const s_sym g_sym_x = {{{NULL}, 1, {"x"}}};
@@ -407,10 +411,12 @@ void sym_init_g_sym (void)
sym_register(&g_sym_operator_pin, NULL);
sym_register(&g_sym_operator_precedence, NULL);
sym_register(&g_sym_r, NULL);
+ sym_register(&g_sym_read, NULL);
sym_register(&g_sym_right, NULL);
sym_register(&g_sym_rw, NULL);
sym_register(&g_sym_rwx, NULL);
sym_register(&g_sym_rx, NULL);
+ sym_register(&g_sym_signal, NULL);
sym_register(&g_sym_special_operator, NULL);
sym_register(&g_sym_str, NULL);
sym_register(&g_sym_struct_type, NULL);
@@ -418,7 +424,9 @@ void sym_init_g_sym (void)
sym_register(&g_sym_symbol, NULL);
sym_register(&g_sym_symbol_value, NULL);
sym_register(&g_sym_then, NULL);
+ sym_register(&g_sym_timeout, NULL);
sym_register(&g_sym_w, NULL);
+ sym_register(&g_sym_write, NULL);
sym_register(&g_sym_wx, NULL);
sym_register(&g_sym_x, NULL);
diff --git a/libkc3/sym.h b/libkc3/sym.h
index 657c012..a6f8ac8 100644
--- a/libkc3/sym.h
+++ b/libkc3/sym.h
@@ -103,10 +103,12 @@ extern const s_sym g_sym_operator_equal;
extern const s_sym g_sym_operator_pin;
extern const s_sym g_sym_operator_precedence;
extern const s_sym g_sym_r;
+extern const s_sym g_sym_read;
extern const s_sym g_sym_right;
extern const s_sym g_sym_rw;
extern const s_sym g_sym_rwx;
extern const s_sym g_sym_rx;
+extern const s_sym g_sym_signal;
extern const s_sym g_sym_special_operator;
extern const s_sym g_sym_str;
extern const s_sym g_sym_struct_type;
@@ -114,7 +116,9 @@ extern const s_sym g_sym_sym;
extern const s_sym g_sym_symbol;
extern const s_sym g_sym_symbol_value;
extern const s_sym g_sym_then;
+extern const s_sym g_sym_timeout;
extern const s_sym g_sym_w;
+extern const s_sym g_sym_write;
extern const s_sym g_sym_wx;
extern const s_sym g_sym_x;