Commit 05a6a4d654f65e82285b224756bc1af79910d556

Thomas de Grivel 2024-08-08T14:58:00

wip http_event

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;