diff --git a/http/http_event.c b/http/http_event.c
index 5135f16..9b13bbe 100644
--- a/http/http_event.c
+++ b/http/http_event.c
@@ -37,8 +37,9 @@ void http_event_callback (int fd, short events, void *tag_tuple)
s_tag tmp;
tag = tag_tuple;
if (tag->type != TAG_TUPLE ||
- tag->data.tuple.count != 2 ||
- tag->data.tuple.tag[0].type != TAG_FN) {
+ tag->data.tuple.count != 3 ||
+ tag->data.tuple.tag[0].type != TAG_FN ||
+ tag->data.tuple.tag[1].type != TAG_PTR) {
err_puts("http_event_callback: invalid arg");
assert(! "http_event_callback: invalid arg");
abort();
@@ -70,7 +71,7 @@ s32 http_event_dispatch (void)
return event_dispatch();
}
-struct event * http_event_new (s32 fd, const s_list *events,
+struct event * http_event_new (s32 fd, const s_list * const *events,
const s_fn *callback, s_tag *arg)
{
const s_list *e;
@@ -81,7 +82,7 @@ struct event * http_event_new (s32 fd, const s_list *events,
if (! ev)
return NULL;
events_s16 = 0;
- e = events;
+ e = *events;
while (e) {
if (e->tag.type != TAG_SYM)
goto invalid_event_list;
@@ -89,18 +90,21 @@ struct event * http_event_new (s32 fd, const s_list *events,
events_s16 |= EV_READ;
else if (e->tag.data.sym == &g_sym_write)
events_s16 |= EV_WRITE;
+ else if (e->tag.data.sym == &g_sym_persist)
+ events_s16 |= EV_PERSIST;
else
goto invalid_event_list;
e = list_next(e);
}
- tag = tag_new_tuple(2);
+ tag = tag_new_tuple(3);
tag_init_fn_copy(tag->data.tuple.tag, callback);
- tag_init_copy(tag->data.tuple.tag + 1, arg);
+ tag_init_ptr(tag->data.tuple.tag + 1, ev);
+ tag_init_copy(tag->data.tuple.tag + 2, arg);
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);
+ 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 049d4ec..26ed7b9 100644
--- a/http/http_event.h
+++ b/http/http_event.h
@@ -17,8 +17,8 @@
/* Heap-allocation functions, call http_event_delete after use. */
void http_event_delete (struct event *ev);
-struct event * http_event_new (s32 fd, const s_list *events, const s_fn *fn,
- s_tag *arg);
+struct event * http_event_new (s32 fd, const s_list * const *events,
+ const s_fn *fn, s_tag *arg);
/* Operators. */
s32 http_event_add (struct event *ev, s_time *time);
diff --git a/lib/kc3/0.1/kc3.facts b/lib/kc3/0.1/kc3.facts
index 4e2bb26..20d2518 100644
--- a/lib/kc3/0.1/kc3.facts
+++ b/lib/kc3/0.1/kc3.facts
@@ -268,5 +268,8 @@ replace {KC3.while, :arity, 2}
replace {KC3.while, :is_a, :special_operator}
replace {KC3.while, :symbol_value, cfn Tag "kc3_while" (Tag, Tag, Result)}
add {KC3, :symbol, KC3.str}
-replace {KC3.str, :arity, 1}
replace {KC3.str, :symbol_value, cfn Str "kc3_str" (Tag, Result)}
+add {KC3, :symbol, KC3.errno}
+replace {KC3.errno, :symbol_value, cfn Sw "kc3_errno" ()}
+add {KC3, :symbol, KC3.strerror}
+replace {KC3.strerror, :symbol_value, cfn Str "kc3_strerror" (Sw, Result)}
diff --git a/lib/kc3/0.1/time.kc3 b/lib/kc3/0.1/time.kc3
index 3854f9c..70b0a39 100644
--- a/lib/kc3/0.1/time.kc3
+++ b/lib/kc3/0.1/time.kc3
@@ -2,4 +2,6 @@ defmodule Time do
defstruct [tv_sec: (Sw) 0, tv_nsec: (Sw) 0, tag: (Ptr) 0]
+ def now = cfn Time "time_init_now" (Result)
+
end
diff --git a/libkc3/list_init.c b/libkc3/list_init.c
index 239d532..980680e 100644
--- a/libkc3/list_init.c
+++ b/libkc3/list_init.c
@@ -533,6 +533,18 @@ s_list * list_init_tuple_2 (s_list *list, const s_tag *a,
return list;
}
+s_list * list_init_time_add (s_list *list, const s_time *a,
+ const s_time *b, s_list *next)
+{
+ s_list tmp = {0};
+ assert(list);
+ list_init(&tmp, next);
+ if (! tag_init_time_add(&tmp.tag, a, b))
+ return NULL;
+ *list = tmp;
+ return list;
+}
+
s_list * list_init_time_now (s_list *list, s_list *next)
{
s_list tmp = {0};
@@ -1201,6 +1213,20 @@ s_list * list_new_tuple_2 (const s_tag *a, const s_tag *b, s_list *next)
return list;
}
+s_list * list_new_time_add (const s_time *a, const s_time *b,
+ s_list *next)
+{
+ s_list *list;
+ list = list_new(next);
+ if (! list)
+ return NULL;
+ if (! tag_init_time_add(&list->tag, a, b)) {
+ free(list);
+ return NULL;
+ }
+ return list;
+}
+
s_list * list_new_time_now (s_list *next)
{
s_list *list;
diff --git a/libkc3/list_init.h b/libkc3/list_init.h
index 027dcbc..f7eb9bf 100644
--- a/libkc3/list_init.h
+++ b/libkc3/list_init.h
@@ -85,6 +85,8 @@ s_list * list_init_tuple (s_list *list, uw count, s_list *next);
s_list * list_init_tuple_2 (s_list *list, const s_tag *a,
const s_tag *b, s_list *next);
s_list * list_init_time (s_list *list, s_list *next);
+s_list * list_init_time_add (s_list *list, const s_time *a,
+ const s_time *b, s_list *next);
s_list * list_init_time_now (s_list *list, s_list *next);
s_list * list_init_u8 (s_list *list, u8 i, s_list *next);
s_list * list_init_u16 (s_list *list, u16 i, s_list *next);
@@ -153,6 +155,8 @@ s_list * list_new_tuple (uw count, s_list *next);
s_list * list_new_tuple_2 (const s_tag *a, const s_tag *b,
s_list *next);
s_list * list_new_time (s_list *next);
+s_list * list_new_time_add (const s_time *a, const s_time *b,
+ s_list *next);
s_list * list_new_time_now (s_list *next);
s_list * list_new_u8 (u8 i, s_list *next);
s_list * list_new_u16 (u16 i, s_list *next);
@@ -216,6 +220,7 @@ s_list * list_sym (s_list *list, const s_sym *sym);
s_list * list_tuple (s_list *list, uw count);
s_list * list_tuple_2 (s_list *list, const s_tag *a, const s_tag *b);
s_list * list_time (s_list *list);
+s_list * list_time_add (s_list *list, const s_time *a, const s_time *b);
s_list * list_time_now (s_list *list);
s_list * list_u8 (s_list *list, u8 i);
s_list * list_u16 (s_list *list, u16 i);
diff --git a/libkc3/sym.c b/libkc3/sym.c
index a44f71f..18e3bb4 100644
--- a/libkc3/sym.c
+++ b/libkc3/sym.c
@@ -101,6 +101,7 @@ const s_sym g_sym_operator_equal = {{{NULL}, 14, {"operator_equal"}}};
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_persist = {{{NULL}, 7, {"persist"}}};
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"}}};
@@ -412,6 +413,7 @@ void sym_init_g_sym (void)
sym_register(&g_sym_operator_equal, NULL);
sym_register(&g_sym_operator_pin, NULL);
sym_register(&g_sym_operator_precedence, NULL);
+ sym_register(&g_sym_persist, NULL);
sym_register(&g_sym_r, NULL);
sym_register(&g_sym_read, NULL);
sym_register(&g_sym_right, NULL);
diff --git a/libkc3/sym.h b/libkc3/sym.h
index b3ff915..d938762 100644
--- a/libkc3/sym.h
+++ b/libkc3/sym.h
@@ -103,6 +103,7 @@ extern const s_sym g_sym_operator_associativity;
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_persist;
extern const s_sym g_sym_r;
extern const s_sym g_sym_read;
extern const s_sym g_sym_right;
diff --git a/libkc3/tag_add.c b/libkc3/tag_add.c
index 524bcbb..cb141c6 100644
--- a/libkc3/tag_add.c
+++ b/libkc3/tag_add.c
@@ -1340,6 +1340,13 @@ s_tag * tag_add (const s_tag *a, const s_tag *b, s_tag *dest)
default:
goto ko;
}
+ case TAG_TIME:
+ switch (b->type) {
+ case TAG_TIME:
+ return tag_init_time_add(dest, &a->data.time, &b->data.time);
+ default:
+ goto ko;
+ }
default:
goto ko;
}
diff --git a/libkc3/tag_init.c b/libkc3/tag_init.c
index f76f4d6..577c2b5 100644
--- a/libkc3/tag_init.c
+++ b/libkc3/tag_init.c
@@ -518,6 +518,17 @@ s_tag * tag_init_tuple_2 (s_tag *tag, const s_tag *a, const s_tag *b)
return tag;
}
+s_tag * tag_init_time_add (s_tag *tag, const s_time *a, const s_time *b)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_TIME;
+ if (! time_init_add(&tmp.data.time, a, b))
+ return NULL;
+ *tag = tmp;
+ return tag;
+}
+
s_tag * tag_init_time_now (s_tag *tag)
{
s_tag tmp = {0};
@@ -1189,6 +1200,20 @@ s_tag * tag_new_tuple_2 (const s_tag *a, const s_tag *b)
return tag;
}
+s_tag * tag_new_time_add (const s_time *a, const s_time *b)
+{
+ s_tag *tag;
+ tag = alloc(sizeof(s_tag));
+ if (! tag)
+ return NULL;
+ tag->type = TAG_TIME;
+ if (! time_init_add(&tag->data.time, a, b)) {
+ free(tag);
+ return NULL;
+ }
+ return tag;
+}
+
s_tag * tag_new_time_now (void)
{
s_tag *tag;
@@ -1816,6 +1841,18 @@ s_tag * tag_tuple_2 (s_tag *tag, const s_tag *a, const s_tag *b)
return tag;
}
+s_tag * tag_time_add (s_tag *tag, const s_time *a, const s_time *b)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_TIME;
+ if (! time_init_add(&tmp.data.time, a, b))
+ return NULL;
+ *tag = tmp;
+ return tag;
+}
+
s_tag * tag_time_now (s_tag *tag)
{
s_tag tmp = {0};
diff --git a/libkc3/tag_init.h b/libkc3/tag_init.h
index 230ae94..38c7c39 100644
--- a/libkc3/tag_init.h
+++ b/libkc3/tag_init.h
@@ -68,6 +68,8 @@ s_tag * tag_init_sym (s_tag *tag, const s_sym *sym);
s_tag * tag_init_tuple (s_tag *tag, uw count);
s_tag * tag_init_tuple_2 (s_tag *tag, const s_tag *a, const s_tag *b);
s_tag * tag_init_time (s_tag *tag);
+s_tag * tag_init_time_add (s_tag *tag, const s_time *a,
+ const s_time *b);
s_tag * tag_init_time_now (s_tag *tag);
s_tag * tag_init_u8 (s_tag *tag, u8 i);
s_tag * tag_init_u16 (s_tag *tag, u16 i);
@@ -128,6 +130,7 @@ s_tag * tag_new_sym (const s_sym *sym);
s_tag * tag_new_tuple (uw count);
s_tag * tag_new_tuple_2 (const s_tag *a, const s_tag *b);
s_tag * tag_new_time (void);
+s_tag * tag_new_time_add (const s_time *a, const s_time *b);
s_tag * tag_new_time_now (void);
s_tag * tag_new_u8 (u8 i);
s_tag * tag_new_u16 (u16 i);
@@ -191,6 +194,7 @@ s_tag * tag_sym (s_tag *tag, const s_sym *sym);
s_tag * tag_tuple (s_tag *tag, uw count);
s_tag * tag_tuple_2 (s_tag *tag, const s_tag *a, const s_tag *b);
s_tag * tag_time (s_tag *tag);
+s_tag * tag_time_add (s_tag *tag, const s_time *a, const s_time *b);
s_tag * tag_time_now (s_tag *tag);
s_tag * tag_u8 (s_tag *tag, u8 i);
s_tag * tag_u16 (s_tag *tag, u16 i);
diff --git a/libkc3/tag_init.rb b/libkc3/tag_init.rb
index f46e8c0..0c44e65 100644
--- a/libkc3/tag_init.rb
+++ b/libkc3/tag_init.rb
@@ -401,6 +401,9 @@ class TagInitList
[Arg.new("const s_tag *", "a"),
Arg.new("const s_tag *", "b")]),
TagInitProto.new("time", "TAG_TIME", :init_mode_none, []),
+ TagInit.new("time", "add", "TAG_TIME", :init_mode_init,
+ [Arg.new("const s_time *", "a"),
+ Arg.new("const s_time *", "b")]),
TagInit.new("time", "now", "TAG_TIME", :init_mode_init, []),
TagInit.new("u8", "TAG_U8", :init_mode_direct,
[Arg.new("u8", "i")]),
diff --git a/libkc3/time.c b/libkc3/time.c
index 5c1219e..8e4585a 100644
--- a/libkc3/time.c
+++ b/libkc3/time.c
@@ -40,6 +40,28 @@ s_time * time_init (s_time *time)
return time;
}
+s_time * time_init_add (s_time *time, const s_time *a, const s_time *b)
+{
+ s_time tmp = {0}
+ assert(time);
+ assert(a);
+ assert(b);
+ assert(! a->tag);
+ assert(! b->tag);
+ tmp.tv_sec = a->tv_sec + b->tv_sec;
+ tmp.tv_nsec = a->tv_nsec + b->tv_nsec;
+ while (tmp.tv_nsec < 0) {
+ tmp.tv_sec--;
+ tmp.tv_nsec += 1000000000;
+ }
+ while (tmp.tv_nsec > 1000000000) {
+ tmp.tv_sec++;
+ tmp.tv_nsec -= 1000000000;
+ }
+ *time = tmp;
+ return time;
+}
+
s_time * time_init_copy (s_time *time, const s_time *src)
{
s_time tmp = {0};
diff --git a/libkc3/time.h b/libkc3/time.h
index fcaf013..e432e63 100644
--- a/libkc3/time.h
+++ b/libkc3/time.h
@@ -24,6 +24,7 @@
time_init argument allocate was true. */
void time_clean (s_time *time);
s_time * time_init (s_time *time);
+s_time * time_init_add (s_time *time, const s_time *a, const s_time *b);
s_time * time_init_copy (s_time *time, const s_time *src);
s_time * time_init_now (s_time *time);
diff --git a/test/http/07_event_echo.kc3 b/test/http/07_event_echo.kc3
index 98304c5..527ed6d 100644
--- a/test/http/07_event_echo.kc3
+++ b/test/http/07_event_echo.kc3
@@ -2,19 +2,33 @@ quote event_base = HTTP.Event.init()
event_base = HTTP.Event.init()
quote socket = Socket.listen("0.0.0.0", "57000")
socket = Socket.listen("0.0.0.0", "57000")
-echo_client = fn (socket, events, client) do
+echo_client = fn (socket, events, client_ev, client) do
if List.has?(events, :read) && List.has(events, :write) do
Buf.refill(client.buf_rw.r)
str = Buf.read_to_str(client.buf_rw.r)
Buf.write_str(client.buf_rw.w, str)
+
end
end
-acceptor = fn (server, events, void) do
+acceptor = fn (server_socket, events, acceptor_ev, void) do
if List.has?(events, :read) do
- client = Socket.Buf.accept(server)
- acceptor_ev = HTTP.Event.new(client.sockfd, [:read, :write],
+ client = Socket.Buf.accept(server_socket)
+ client_ev = HTTP.Event.new(client.sockfd, [:read, :write],
echo_client, client)
+ HTTP.Event.add(client_ev, Time.now() + %Time{tv_sec: 30})
end
end
-quote HTTP.Event.dispatch()
-HTTP.Event.dispatch()
+quote acceptor_ev = HTTP.Event.new(socket.fd, [:read, :persist], acceptor,
+ void)
+acceptor_ev = HTTP.Event.new(socket.fd, [:read, :persist], acceptor,
+ void)
+quote r = HTTP.Event.dispatch()
+r = HTTP.Event.dispatch()
+quote if r do
+ e = errno()
+ puts("HTTP.Event.dispatch: #{r}: #{strerror(e)}")
+end
+if r do
+ e = errno()
+ puts("HTTP.Event.dispatch: #{r}: #{strerror(e)}")
+end