p2  0.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
aio.c
Go to the documentation of this file.
1 
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <uv.h>
17 #ifdef P2
18 # include "p2.h"
19 #else
20 # include "potion.h"
21 #endif
22 
28 
29 //with wrapped callback
30 #define DEF_AIO_CB_WRAP(T) \
31  DEF_AIO_CB_WRAP1(T,T,T)
32 #define DEF_AIO_CB_WRAP1(T,H,C) \
33 typedef struct aio_##T##_s aio_##T##_t; \
34 struct aio_##T##_s { \
35  struct uv_##H##_s r; \
36  Potion *P; \
37  struct PNClosure *cb; \
38 }
39 //without
40 #define DEF_AIO_HANDLE_WRAP(T) \
41 typedef struct aio_##T##_s aio_##T##_t; \
42 struct aio_##T##_s { \
43  uv_##T##_t h; \
44  Potion *P; \
45  struct PNClosure *cb; \
46 }
47 typedef uv_buf_t aio_buf_t;
48 DEF_AIO_CB_WRAP(write);
49 DEF_AIO_CB_WRAP(connect);
50 DEF_AIO_CB_WRAP(shutdown);
51 DEF_AIO_CB_WRAP1(connection,stream,connection);
52 DEF_AIO_CB_WRAP1(close,handle,close);
53 //DEF_AIO_CB_WRAP(poll);
54 DEF_AIO_CB_WRAP(timer);
55 DEF_AIO_CB_WRAP(async);
56 DEF_AIO_CB_WRAP(prepare);
57 DEF_AIO_CB_WRAP(check);
58 DEF_AIO_CB_WRAP(idle);
59 DEF_AIO_CB_WRAP1(exit,process,exit);
60 DEF_AIO_CB_WRAP1(walk,handle,walk);
61 #ifndef SANDBOX
62 DEF_AIO_CB_WRAP(fs);
63 DEF_AIO_CB_WRAP(fs_poll);
64 DEF_AIO_CB_WRAP(fs_event);
65 DEF_AIO_HANDLE_WRAP(process);
66 #endif
67 DEF_AIO_CB_WRAP(work);
68 DEF_AIO_CB_WRAP1(after_work,work,after_work);
69 DEF_AIO_CB_WRAP(getaddrinfo);
70 DEF_AIO_CB_WRAP(signal);
71 DEF_AIO_HANDLE_WRAP(handle);
73 DEF_AIO_CB_WRAP(pipe);
74 DEF_AIO_HANDLE_WRAP(stdio_container);
75 DEF_AIO_HANDLE_WRAP(process_options);
76 DEF_AIO_CB_WRAP1(stream,stream,read);
78 DEF_AIO_CB_WRAP(req);
79 DEF_AIO_CB_WRAP1(tcp,tcp,read);
80 DEF_AIO_CB_WRAP1(udp,udp,udp_recv);
81 DEF_AIO_CB_WRAP(udp_send);
82 DEF_AIO_HANDLE_WRAP(cpu_info);
83 DEF_AIO_HANDLE_WRAP(interface_address);
85 DEF_AIO_HANDLE_WRAP(barrier);
87 DEF_AIO_HANDLE_WRAP(mutex);
88 DEF_AIO_HANDLE_WRAP(rwlock);
89 #undef DEF_AIO_CB_WRAP
90 #undef DEF_AIO_HANDLE_WRAP
91 #undef DEF_AIO_CB_WRAP1
92 
93 #ifndef SANDBOX
94 
100 static void
101 aio_fs_event_cb(uv_fs_event_t* handle, const char* filename, int events, int status) {
102  struct aio_fs_event_s* wrap = (struct aio_fs_event_s*)handle;
103  vPN(Closure) cb = PN_CLOSURE(wrap->cb);
104  char *data = (char*)(&wrap - sizeof(struct PNData) + sizeof(char*));
105  if (cb) cb->method(wrap->P, (PN)cb, (PN)data, potion_str(wrap->P, filename),
106  PN_NUM(events), PN_NUM(status));
107 }
108 #endif
109 
110 static PN aio_error(Potion *P, char *name, int status) {
111  return potion_error(P, potion_str_format(P, "Error %s: %s", name,
112  uv_strerror(status)), 0, 0, 0);
113 }
114 
115 #define DEF_AIO_NEW(T) \
116  uv_##T##_t *handle; \
117  struct PNData * volatile data = potion_data_alloc(P, sizeof(aio_##T##_t)); \
118  data->vt = aio_##T##_type; \
119  handle = (uv_##T##_t*)PN_DATA(data); \
120  ((aio_##T##_t*)handle)->P = P
121 #define DEF_AIO_NEW_LOOP(T) \
122  uv_loop_t* l; \
123  DEF_AIO_NEW(T); \
124  if (!loop) l = uv_default_loop(); \
125  else if (PN_VTYPE(loop) == aio_loop_type) \
126  l = (uv_loop_t*)PN_DATA(loop); \
127  else return potion_type_error(P, loop);
128 #define DEF_AIO_NEW_LOOP_INIT(T) \
129  DEF_AIO_NEW_LOOP(T); \
130  int r = uv_##T##_init(l, handle); \
131  return r ? aio_error(P, "Aio_"_XSTR(T), r) : (PN)data;
132 #define AIO_CB_SET(T,ARG) \
133  uv_##T##_cb T##_cb; \
134  if (PN_IS_CLOSURE(cb)) { \
135  (ARG)->cb = PN_CLOSURE(cb); \
136  T##_cb = aio_##T##_cb; \
137  } \
138  else if (PN_IS_FFIPTR(cb)) \
139  T##_cb = (uv_##T##_cb)cb; \
140  else T##_cb = aio_##T##_cb
141 #define AIO_CB_SET_CAST(T,ARG) \
142  uv_##T##_cb T##_cb; \
143  if (PN_IS_CLOSURE(cb)) { \
144  ((aio_##T##_t*)ARG)->cb = PN_CLOSURE(cb); \
145  T##_cb = aio_##T##_cb; \
146  } \
147  else if (PN_IS_FFIPTR(cb)) \
148  T##_cb = (uv_##T##_cb)cb; \
149  else T##_cb = aio_##T##_cb
150 
151 //checks inheritence
152 #define CHECK_AIO_TYPE(self, T) \
153  if (!potion_bind(P, self, PN_STR("Aio_"_XSTR(T)))) return potion_type_error_want(P, "self", self, ""_XSTR(T))
154 #define CHECK_AIO_STREAM(stream) \
155  { \
156  PNType _t = PN_VTYPE(stream); \
157  if (_t != aio_stream_type && \
158  _t != aio_tcp_type && \
159  _t != aio_udp_type && \
160  _t != aio_pipe_type && \
161  _t != aio_tty_type && \
162  !potion_bind(P, stream, PN_STR("listen"))) \
163  return potion_type_error_want(P, "stream", stream, "Aio_stream"); \
164  }
165 //if (PN_VTYPE(self) != aio_##T##_type) {
166 #define FATAL_AIO_TYPE(self, T) \
167  if (!potion_bind(P, self, PN_STR("Aio_"_XSTR(T)))) { \
168  fprintf(stderr, "** Invalid type %s, expected %s", \
169  PN_IS_PTR(self)? AS_STR(potion_send(PN_VTABLE(self), PN_name)) \
170  : PN_IS_NIL(self) ? NIL_NAME \
171  : PN_IS_INT(self) ? "Integer" : "Boolean", "Aio_"_XSTR(T)); \
172  exit(1); \
173  }
174 #define FATAL_AIO_STREAM(stream) \
175  { \
176  PNType _t = PN_VTYPE(stream); \
177  if (_t != aio_stream_type && \
178  _t != aio_tcp_type && \
179  _t != aio_udp_type && \
180  _t != aio_pipe_type && \
181  _t != aio_tty_type && \
182  !potion_bind(P, stream, PN_STR("listen"))) \
183  { \
184  fprintf(stderr, "** Invalid type %s, expected %s", \
185  PN_IS_PTR(stream)? AS_STR(potion_send(PN_VTABLE(stream), PN_name)) \
186  : PN_IS_NIL(stream) ? NIL_NAME \
187  : PN_IS_INT(stream) ? "Integer" : "Boolean", "Aio_stream");\
188  exit(1); \
189  } \
190  }
191 
192 #define AIO_DATA(T,ARG) \
193  (aio_##T##_t*)PN_DATA(potion_fwd(ARG)); \
194  CHECK_AIO_TYPE(ARG,T)
195 #define AIO_STREAM(ARG) \
196  (aio_stream_t*)PN_DATA(potion_fwd(ARG)); \
197  CHECK_AIO_STREAM(ARG)
198 
199 //cb wrappers
200 #define DEF_AIO_CB(T) \
201  aio_##T##_t* wrap = (aio_##T##_t*)req; \
202  vPN(Closure) cb = PN_CLOSURE(wrap->cb); \
203  PN data = (PN)((char*)wrap - sizeof(struct PNData)); \
204  Potion *P = wrap->P; \
205  FATAL_AIO_TYPE(data,T); \
206  if (cb) cb->method(P, (PN)cb, data, PN_NUM(status))
207 #define DEF_AIO_CB_NOSTATUS(T) \
208  aio_##T##_t* wrap = (aio_##T##_t*)req; \
209  vPN(Closure) cb = PN_CLOSURE(wrap->cb); \
210  PN data = (PN)((char*)wrap - sizeof(struct PNData)); \
211  Potion *P = wrap->P; \
212  FATAL_AIO_TYPE(data,T); \
213  if (cb) cb->method(P, (PN)cb, data)
214 
215 static void
216 aio_getaddrinfo_cb(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
217  aio_getaddrinfo_t* wrap = (aio_getaddrinfo_t*)req;
218  vPN(Closure) cb = PN_CLOSURE(wrap->cb);
219  PN data = (PN)((char*)wrap - sizeof(struct PNData));
220  Potion *P = wrap->P;
221  FATAL_AIO_TYPE(data,getaddrinfo);
222  if (!PN_IS_INT(status))
223  potion_fatal("status not a Integer");
224  if (cb) cb->method(P, (PN)cb, (PN)data, PN_NUM(status), potion_ref(wrap->P, (PN)res));
225 }
226 
231 static PN aio_tcp_new(Potion *P, PN cl, PN self, PN loop) {
232 #ifndef DEBUG
234 #else
235  int r;
236  uv_loop_t* l;
237  uv_tcp_t *handle;
238  struct PNData * volatile data = potion_data_alloc(P, sizeof(aio_tcp_t));
239  data->vt = aio_tcp_type;
240  handle = (uv_tcp_t*)PN_DATA(data);
241  ((aio_tcp_t*)handle)->P = P;
242  if (!loop) l = uv_default_loop();
243  else if (PN_VTYPE(loop) == aio_loop_type)
244  l = (uv_loop_t*)PN_DATA(loop);
245  else return potion_type_error(P, loop);
246  r = uv_tcp_init(l, handle);
247  if (r) return aio_error(P, "Aio_tcp", r);
248  return (PN)data;
249 #endif
250 }
255 static PN aio_udp_new(Potion *P, PN cl, PN self, PN loop) {
256 #ifndef DEBUG
258 #else
259  int r;
260  uv_loop_t* l;
261  uv_udp_t *handle;
262  struct PNData * volatile data = potion_data_alloc(P, sizeof(aio_udp_t));
263  data->vt = aio_udp_type;
264  handle = (uv_udp_t*)PN_DATA(data);
265  ((aio_udp_t*)handle)->P = P;
266  if (!loop) l = uv_default_loop();
267  else if (PN_VTYPE(loop) == aio_loop_type)
268  l = (uv_loop_t*)PN_DATA(loop);
269  else return potion_type_error(P, loop);
270  r = uv_udp_init(l, handle);
271  if (r) return aio_error(P, "Aio_udp", r);
272  //TODO: init ivars from struct
273  return (PN)data;
274 #endif
275 }
280 static PN aio_udp_get(Potion *P, PN cl, PN self, PN key, PN value) {
281  CHECK_AIO_TYPE(self,udp);
282  PN_CHECK_STR(key);
283  PN v = potion_obj_get(P, 0, self, key);
284  return v ? v : potion_error(P, potion_str_format(P, "Invalid key %s",
285  PN_STR_PTR(key)),
286  0, 0, 0);
287 }
293 static PN aio_udp_set(Potion *P, PN cl, PN self, PN key, PN value) {
294  uv_udp_t *udp;
295  udp = (uv_udp_t*)PN_DATA(potion_fwd(self));
296  CHECK_AIO_TYPE(self,udp);
297  PN_CHECK_STR(key);
298  char *k = PN_STR_PTR(key);
299  if (!strcmp(k, "broadcast")) {
300  PN_CHECK_BOOL(value);
301  if (!uv_udp_set_broadcast(udp, value == PN_TRUE ? 1 : 0))
302  potion_obj_set(P, 0, self, key, value);
303  }
304  else if (!strcmp(k, "multicast_loop")) {
305  PN_CHECK_BOOL(value);
306  if (!uv_udp_set_multicast_loop(udp, value == PN_TRUE ? 1 : 0))
307  potion_obj_set(P, 0, self, key, value);
308  }
309  else if (!strcmp(k, "multicast_ttl")) {
310  PN_CHECK_INT(value);
311  if (!uv_udp_set_multicast_ttl(udp, PN_INT(value)))
312  potion_obj_set(P, 0, self, key, value);
313  }
314  else if (!strcmp(k, "ttl")) {
315  PN_CHECK_INT(value);
316  if (!uv_udp_set_ttl(udp, PN_INT(value)))
317  potion_obj_set(P, 0, self, key, value);
318  }
319  else if (!strcmp(k, "membership")) {
320  PN_CHECK_TUPLE(value);
321  vPN(Tuple) t = PN_GET_TUPLE(value);
322  PN_CHECK_STR(t->set[0]);
323  PN_CHECK_STR(t->set[1]);
324  PN_CHECK_INT(t->set[2]);
325  if (!uv_udp_set_membership(udp, PN_STR_PTR(PN_TUPLE_AT(t, 0)),
326  PN_STR_PTR(PN_TUPLE_AT(t, 1)),
327  (uv_membership)PN_INT(PN_TUPLE_AT(t, 2)))) //0 or 1
328  potion_obj_set(P, 0, self, key, value);
329  }
330  else {
331  return potion_error(P, potion_str_format(P, "Invalid key %s",
332  PN_STR_PTR(key)),
333  0, 0, 0);
334  }
335  return (PN)self;
336 }
343 static PN aio_prepare_new(Potion *P, PN cl, PN self, PN loop) {
344  DEF_AIO_NEW_LOOP_INIT(prepare);
345 }
349 static PN aio_check_new(Potion *P, PN cl, PN self, PN loop) {
350  DEF_AIO_NEW_LOOP_INIT(check);
351 }
355 static PN aio_idle_new(Potion *P, PN cl, PN self, PN loop) {
356  DEF_AIO_NEW_LOOP_INIT(idle);
357 }
362 static PN aio_timer_new(Potion *P, PN cl, PN self, PN loop) {
363  DEF_AIO_NEW_LOOP_INIT(timer);
364 }
404 static PN aio_signal_new(Potion *P, PN cl, PN self, PN loop) {
405  DEF_AIO_NEW_LOOP_INIT(signal);
406 }
410 static PN aio_loop_new(Potion *P, PN cl, PN self) {
411  uv_loop_t *l;
412  uv_loop_t *def;
413  struct PNData *data = potion_data_alloc(P,sizeof(aio_loop_t));
414  ((struct aio_loop_s*)data)->P = P;
415  l = (uv_loop_t*)PN_DATA(data);
416  def = uv_default_loop();
417  memcpy(l, def, sizeof(uv_loop_t));
418  return (PN)data;
419 }
422 static PN aio_handle_new(Potion *P, PN cl, PN self) {
423  DEF_AIO_NEW(handle);
424  return (PN)data;
425 }
428 static PN aio_stream_new(Potion *P, PN cl, PN self) {
429  DEF_AIO_NEW(stream);
430  return (PN)data;
431 }
434 static PN aio_req_new(Potion *P, PN cl, PN self) {
435  DEF_AIO_NEW(req);
436  return (PN)data;
437 }
440 static PN aio_connect_new(Potion *P, PN cl, PN self) {
441  DEF_AIO_NEW(connect);
442  return (PN)data;
443 }
446 static PN aio_write_new(Potion *P, PN cl, PN self) {
447  DEF_AIO_NEW(write);
448  return (PN)data;
449 }
452 static PN aio_shutdown_new(Potion *P, PN cl, PN self) {
453  DEF_AIO_NEW(shutdown);
454  return (PN)data;
455 }
458 static PN aio_udp_send_new(Potion *P, PN cl, PN self) {
459  DEF_AIO_NEW(udp_send);
460  return (PN)data;
461 }
462 
463 #ifndef SANDBOX
464 
469 static PN aio_fs_poll_new(Potion *P, PN cl, PN self, PN loop) {
470  DEF_AIO_NEW_LOOP_INIT(fs_poll);
471 }
486 static PN aio_fs_new(Potion *P, PN cl, PN self) {
487  DEF_AIO_NEW(fs);
488  return (PN)data;
489 }
492 static PN aio_fs_event_new(Potion *P, PN cl, PN self, PN loop) {
493  DEF_AIO_NEW_LOOP_INIT(fs_event);
494 }
500 static PN aio_fs_event_start(Potion *P, PN cl, PN self, PN cb, PN filename, PN flags) {
501  aio_fs_event_t *handle = AIO_DATA(fs_event,self);
502  AIO_CB_SET(fs_event,handle);
503  PN_CHECK_STR(filename);
504  PN_CHECK_INT(flags);
505  int r = uv_fs_event_start(&handle->r, fs_event_cb, PN_STR_PTR(filename), PN_NUM(flags));
506  return r ? aio_error(P, "fs_event start", r) : self;
507 }
509 static PN
510 aio_fs_event_stop(Potion *P, PN cl, PN self) {
511  aio_fs_event_t *handle = AIO_DATA(fs_event,self);
512  int r = uv_fs_event_stop(&handle->r);
513  return r ? aio_error(P, "fs_event stop", r) : self;
514 }
515 
516 static PN aio_process_options(Potion *P, PN cl, PN self)
517 {
518  DEF_AIO_NEW(process_options);
519  return (PN)data;
520 }
521 #endif /* SANDBOX */
522 
525 static PN aio_work_new(Potion *P, PN cl, PN self) {
526  DEF_AIO_NEW(work);
527  return (PN)data;
528 }
542 static PN aio_getaddrinfo_new(Potion *P, PN cl, PN self,
543  PN cb, PN node, PN service, PN hints, PN loop)
544 {
545  DEF_AIO_NEW_LOOP(getaddrinfo);
546  AIO_CB_SET_CAST(getaddrinfo,handle);
547 
548  const char *node_c = PN_IS_STR(node) ? PN_STR_PTR(node) : NULL;
549  const char *service_c = PN_IS_STR(service) ? PN_STR_PTR(service) : NULL;
550  struct addrinfo* hints_c = (struct addrinfo*)PN_DATA(hints);
551  if (!node_c && !service_c) {
552  return potion_type_error_want(P, "node or service", !node_c ? node : service, "String");
553  }
554  int r = uv_getaddrinfo(l, handle, getaddrinfo_cb, node_c, service_c, (const struct addrinfo*)hints_c);
555  if (r) return aio_error(P, "Aio_getaddrinfo", r);
556  return (PN)data;
557 }
558 static PN aio_cpu_info_new(Potion *P, PN cl, PN self) {
559  DEF_AIO_NEW(cpu_info);
560  return (PN)data;
561 }
562 static PN aio_interface_address_new(Potion *P, PN cl, PN self) {
563  DEF_AIO_NEW(interface_address);
564  return (PN)data;
565 }
572 static PN aio_tty_new(Potion *P, PN cl, PN self, PN file, PN readable, PN loop) {
573  DEF_AIO_NEW_LOOP(tty);
574  PN_CHECK_INT((PN)PN_DATA(file));
575  PN_CHECK_INT(readable);
576  int r = uv_tty_init(l, handle, PN_NUM(PN_DATA(file)), PN_NUM(readable));
577  if (r) return aio_error(P, "Aio_tty", r);
578  return (PN)data;
579 }
585 static PN aio_pipe_new(Potion *P, PN cl, PN self, PN ipc, PN loop) {
586  DEF_AIO_NEW_LOOP(pipe);
587  PN_CHECK_INT(ipc);
588  int r = uv_pipe_init(l, handle, PN_NUM(ipc));
589  if (r) return aio_error(P, "Aio_pipe", r);
590  return (PN)data;
591 }
592 /*static PN aio_poll_new(Potion *P, PN cl, PN self, PN fd, PN loop) {
593  DEF_AIO_NEW_LOOP(poll);
594  int r = uv_poll_init((uv_loop_t*)loop, handle, PN_NUM(fd));
595  return r ? aio_error(P, "Aio_poll", r) ? (PN)data;
596  }*/
601 static PN aio_barrier_new(Potion *P, PN cl, PN self, PN count) {
602  DEF_AIO_NEW(barrier);
603  PN_CHECK_INT(count);
604  if (uv_barrier_init(handle, PN_NUM(count)))
605  return potion_io_error(P, "Aio_barrier");
606  return (PN)data;
607 }
611 static PN aio_sem_new(Potion *P, PN cl, PN self, PN value) {
612  DEF_AIO_NEW(sem);
613  PN_CHECK_INT(value);
614  if (uv_sem_init(handle, PN_NUM(value)))
615  return potion_io_error(P, "Aio_sem");
616  return (PN)data;
617 }
618 static void
619 aio_async_cb(uv_async_t* req) {
620  DEF_AIO_CB_NOSTATUS(async);
621 }
622 static PN aio_async_new(Potion *P, PN cl, PN self, PN cb, PN loop) {
623  DEF_AIO_NEW_LOOP(async);
624  AIO_CB_SET(async,(aio_tcp_t*)data);
625  int r = uv_async_init(l, handle, async_cb);
626  if (r) return aio_error(P, "Aio_async", r);
627  return (PN)data;
628 }
629 static PN aio_cond_new(Potion *P, PN cl, PN self) {
630  DEF_AIO_NEW(cond);
631  if (uv_cond_init(handle))
632  return potion_io_error(P, "Aio_cond");
633  return (PN)data;
634 }
635 static PN aio_mutex_new(Potion *P, PN cl, PN self) {
636  DEF_AIO_NEW(mutex);
637  if (uv_mutex_init(handle))
638  return potion_io_error(P, "Aio_mutex");
639  return (PN)data;
640 }
641 static PN aio_rwlock_new(Potion *P, PN cl, PN self) {
642  DEF_AIO_NEW(rwlock);
643  if (uv_rwlock_init(handle))
644  return potion_io_error(P, "Aio_rwlock");
645  return (PN)data;
646 }
647 
648 static void
649 aio_write_cb(uv_write_t* req, int status) {
650  DEF_AIO_CB(write);
651 }
652 static void
653 aio_connect_cb(uv_connect_t* req, int status) {
654 #ifndef DEBUG
655  DEF_AIO_CB(connect);
656 #else
657  aio_connect_t* wrap = (aio_connect_t*)req;
658  vPN(Closure) cb = PN_CLOSURE(wrap->cb);
659  PN data = (PN)((char*)wrap - sizeof(struct PNData));
660  Potion *P = wrap->P;
661  //FATAL_AIO_TYPE(data,connect); //=>
662  if (!potion_bind(P, data, PN_STR("Aio_connect"))) {
663  fprintf(stderr, "** Invalid type %s, expected %s",
665  : PN_IS_NIL(data) ? NIL_NAME
666  : PN_IS_INT(data) ? "Integer" : "Boolean", "Aio_connect");
667  exit(1);
668  }
669  if (cb) cb->method(P, (PN)cb, data, PN_NUM(status));
670 #endif
671 }
672 static void
673 aio_shutdown_cb(uv_shutdown_t* req, int status) {
674  DEF_AIO_CB(shutdown);
675 }
676 static void
677 aio_prepare_cb(uv_prepare_t* req) {
678  DEF_AIO_CB_NOSTATUS(prepare);
679 }
680 static void
681 aio_check_cb(uv_check_t* req) {
682  DEF_AIO_CB_NOSTATUS(check);
683 }
684 static void
685 aio_connection_cb(uv_stream_t* req, int status) {
686  DEF_AIO_CB(stream);
687 }
688 static void
689 aio_udp_send_cb(uv_udp_send_t* req, int status) {
690  DEF_AIO_CB(udp_send);
691 }
692 static void
693 aio_idle_cb(uv_idle_t* req) {
694  DEF_AIO_CB_NOSTATUS(idle);
695 }
696 static void
697 aio_timer_cb(uv_timer_t* req) {
698  DEF_AIO_CB_NOSTATUS(timer);
699 }
700 static void
701 aio_signal_cb(uv_signal_t* req, int status) { //signum really
702  DEF_AIO_CB(signal);
703 }
704 
705 #ifndef SANDBOX
706 #if 0 //yet unused
707 static void
708 aio_fs_poll_cb(uv_fs_poll_t* handle, int status, const uv_stat_t* prev, const uv_stat_t* curr) {
709  aio_fs_poll_t* wrap = (aio_fs_poll_t*)handle;
710  vPN(Closure) cb = PN_CLOSURE(wrap->cb);
711  PN data = (PN)((char*)wrap - sizeof(struct PNData));
712  Potion *P = wrap->P;
713  CHECK_AIO_TYPE(data,fs_poll);
714  CHECK_AIO_TYPE(prev,stat);
715  CHECK_AIO_TYPE(curr,stat);
716  PN_CHECK_INT(status);
717  if (cb) cb->method(P, (PN)cb, (PN)data, PN_NUM(status),
718  potion_ref(wrap->P, (PN)prev), potion_ref(wrap->P, (PN)curr));
719 }
720 #endif
721 static void
722 aio_fs_cb(uv_fs_t* req) {
723  aio_fs_t* wrap = (aio_fs_t*)req;
724  vPN(Closure) cb = PN_CLOSURE(wrap->cb);
725  PN data = (PN)((char*)wrap - sizeof(struct PNData));
726  Potion *P = wrap->P;
727  FATAL_AIO_TYPE(data,fs);
728  if (cb) cb->method(P, (PN)cb, (PN)data);
729 }
730 #endif
731 
732 static void
733 aio_read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
734  aio_stream_t* wrap = (aio_stream_t*)stream;
735  vPN(Closure) cb = PN_CLOSURE(wrap->cb);
736  PN data = (PN)((char*)wrap - sizeof(struct PNData));
737  Potion *P = wrap->P;
738  FATAL_AIO_STREAM(data);
739  if (cb)
740  cb->method(P, (PN)cb, (PN)data, PN_NUM(nread),
741  potion_byte_str2(wrap->P, buf->base, buf->len));
742 }
743 static void
744 aio_walk_cb(uv_handle_t* handle, void *arg) {
745  aio_handle_t* wrap = (aio_handle_t*)handle;
746  vPN(Closure) cb = PN_CLOSURE(wrap->cb);
747  PN data = (PN)((char*)wrap - sizeof(struct PNData));
748  Potion *P = wrap->P;
749  FATAL_AIO_TYPE(data,handle);
750  if (cb) cb->method(P, (PN)cb, (PN)data, (PN)arg);
751 }
752 static void
753 aio_close_cb(uv_handle_t* handle) {
754  aio_handle_t* wrap = (aio_handle_t*)handle;
755  vPN(Closure) cb = PN_CLOSURE(wrap->cb);
756  PN data = (PN)((char*)wrap - sizeof(struct PNData));
757  Potion *P = wrap->P;
758  FATAL_AIO_TYPE(data,handle);
759  if (cb) cb->method(P, (PN)cb, (PN)data);
760 }
765 static PN
766 aio_version(Potion *P, PN cl, PN self) {
767  return PN_NUM(uv_version());
768 }
772 static PN
774  return PN_STR(uv_version_string());
775 }
776 static PN aio_size(Potion *P, PN cl, PN self) {
777  struct PNData* data = (struct PNData*)potion_fwd(self);
778  return data->siz;
779 }
780 
782 static PN
783 aio_run(Potion *P, PN cl, PN self, PN loop, PN mode) {
784  uv_loop_t* l;
785  if (!loop) l = uv_default_loop();
786  else if (PN_VTYPE(loop) == aio_loop_type)
787  l = (uv_loop_t*)PN_DATA(loop);
788  else return potion_type_error(P, loop);
789  if (mode) PN_CHECK_TYPE(mode,PN_TNUMBER);
790  int r = uv_run(l, mode ? (uv_run_mode)PN_INT(mode) : UV_RUN_DEFAULT);
791  return r ? aio_error(P, "run", r) : self;
792 }
795 static PN
796 aio_walk(Potion *P, PN cl, PN self, PN loop, PN cb, PN arg) {
797  uv_loop_t* l;
798  if (!loop) l = uv_default_loop();
799  else if (PN_VTYPE(loop) == aio_loop_type)
800  l = (uv_loop_t*)PN_DATA(loop);
801  else return potion_type_error(P, loop);
802 
803  AIO_CB_SET(walk,(aio_loop_t*)l);
804 
805  uv_walk(l, walk_cb, (void *)arg);
806  return self;
807 }
808 
810 static PN
811 aio_tcp_open(Potion *P, PN cl, PN tcp, PN sock) {
812  aio_tcp_t *handle = AIO_DATA(tcp,tcp);
813  PN_CHECK_INT(sock);
814  int r = uv_tcp_open(&handle->r, PN_INT(sock));
815  return r ? aio_error(P, "tcp open", r) : tcp;
816 }
818 static PN
819 aio_tcp_nodelay(Potion *P, PN cl, PN tcp, PN enable) {
820  aio_tcp_t *handle = AIO_DATA(tcp,tcp);
821  PN_CHECK_BOOL(enable);
822  int r = uv_tcp_nodelay(&handle->r, enable == PN_TRUE ? PN_INT(1) : PN_INT(0));
823  return r ? aio_error(P, "tcp nodelay", r) : tcp;
824 }
826 static PN
827 aio_tcp_keepalive(Potion *P, PN cl, PN tcp, PN enable, PN delay) {
828  aio_tcp_t *handle = AIO_DATA(tcp,tcp);
829  PN_CHECK_BOOL(enable);
830  PN_CHECK_INT(delay);
831  int r = uv_tcp_keepalive(&handle->r, enable == PN_TRUE ? PN_INT(1) : PN_INT(0), PN_INT(delay));
832  return r ? aio_error(P, "tcp keepalive", r) : tcp;
833 }
835 static PN
837  aio_tcp_t *handle = AIO_DATA(tcp,tcp);
838  PN_CHECK_BOOL(enable);
839  int r = uv_tcp_simultaneous_accepts(&handle->r, enable == PN_TRUE ? PN_INT(1) : PN_INT(0));
840  return r ? aio_error(P, "tcp simultaneous_accepts", r) : tcp;
841 }
843 static PN
844 aio_tcp_bind(Potion *P, PN cl, PN tcp, PN addr, PN port) {
845  aio_tcp_t *handle = AIO_DATA(tcp,tcp);
846  PN_CHECK_STR(addr);
847  PN_CHECK_INT(port);
848  struct sockaddr_in ip4;
849  //detect ip6
850  if (uv_ip4_addr(PN_STR_PTR(addr), PN_INT(port), &ip4)) {
851  struct sockaddr_in6 ip6;
852  if (uv_ip6_addr(PN_STR_PTR(addr), PN_INT(port), &ip6))
853  return aio_error(P, "ip_addr", 89); //EDESTADDRREQ
854  else {
855  int r = uv_tcp_bind(&handle->r, (const struct sockaddr*) &ip6, 1);
856  return r ? aio_error(P, "tcp bind6", r) : tcp;
857  }
858  }
859  int r = uv_tcp_bind(&handle->r, (const struct sockaddr*) &ip4, 0);
860  return r ? aio_error(P, "tcp bind", r) : tcp;
861 }
863 static PN
864 aio_tcp_bind6(Potion *P, PN cl, PN tcp, PN addr, PN port) {
865  aio_tcp_t *handle = AIO_DATA(tcp,tcp);
866  PN_CHECK_STR(addr);
867  PN_CHECK_INT(port);
868  struct sockaddr_in6 ip6;
869  if (uv_ip6_addr(PN_STR_PTR(addr), PN_INT(port), &ip6))
870  return aio_error(P, "ip6_addr", 89); //EDESTADDRREQ
871  int r = uv_tcp_bind(&handle->r, (const struct sockaddr*) &ip6, 1);
872  return r ? aio_error(P, "tcp bind6", r) : tcp;
873 }
875 static PN
877  struct sockaddr sock; int len;
878  aio_tcp_t *handle = AIO_DATA(tcp,tcp);
879  int r = uv_tcp_getsockname(&handle->r, &sock, &len);
880  return r ? aio_error(P, "tcp getsockname", r) : potion_str2(P, sock.sa_data, len);
881 }
883 static PN
885  struct sockaddr sock; int len;
886  aio_tcp_t *handle = AIO_DATA(tcp,tcp);
887  int r = uv_tcp_getpeername(&handle->r, &sock, &len);
888  return r ? aio_error(P, "tcp getpeername", r) : potion_str2(P, sock.sa_data, len);
889 }
891 static PN
892 aio_tcp_connect(Potion *P, PN cl, PN tcp, PN req, PN addr, PN port, PN cb) {
893  aio_tcp_t *handle = AIO_DATA(tcp,tcp);
894  aio_connect_t *request = (aio_connect_t*)PN_DATA(potion_fwd(req));
895  PN_CHECK_STR(addr);
896  PN_CHECK_INT(port);
897  struct sockaddr_in ip4;
898  if (uv_ip4_addr(PN_STR_PTR(addr), PN_INT(port), &ip4)) {
899  struct sockaddr_in6 ip6;
900  if (uv_ip6_addr(PN_STR_PTR(addr), PN_INT(port), &ip6))
901  return aio_error(P, "ip_addr", 89); //EDESTADDRREQ
902  else {
903  AIO_CB_SET(connect,request);
904  int r = uv_tcp_connect(&request->r, &handle->r, (const struct sockaddr*) &ip6, connect_cb);
905  return r ? aio_error(P, "tcp connect6", r) : tcp;
906  }
907  }
908  AIO_CB_SET(connect,request);
909  int r = uv_tcp_connect(&request->r, &handle->r, (const struct sockaddr*) &ip4, connect_cb);
910  return r ? aio_error(P, "tcp connect", r) : tcp;
911 }
913 static PN
914 aio_tcp_connect6(Potion *P, PN cl, PN tcp, PN req, PN addr, PN port, PN cb) {
915  aio_tcp_t *handle = AIO_DATA(tcp,tcp);
916  aio_connect_t *request = (aio_connect_t*)PN_DATA(potion_fwd(req));
917  PN_CHECK_STR(addr);
918  PN_CHECK_INT(port);
919  struct sockaddr_in6 ip6;
920  if (uv_ip6_addr(PN_STR_PTR(addr), PN_INT(port), &ip6))
921  return aio_error(P, "ip6_addr", 89); //EDESTADDRREQ
922  AIO_CB_SET(connect,request);
923  int r = uv_tcp_connect(&request->r, &handle->r, (const struct sockaddr*) &ip6, connect_cb);
924  return r ? aio_error(P, "tcp connect6", r)
925  : tcp;
926 }
929 static PN
930 aio_udp_open(Potion *P, PN cl, PN udp, PN sockfd) {
931  aio_udp_t *handle = AIO_DATA(udp,udp);
932  PN_CHECK_INT(sockfd);
933  int r = uv_udp_open(&handle->r, PN_INT(sockfd));
934  return r ? aio_error(P, "udp open", r) : udp;
935 }
937 static PN
938 aio_udp_bind(Potion *P, PN cl, PN udp, PN addr, PN port, PN flags) {
939  aio_udp_t *handle = AIO_DATA(udp,udp);
940  struct sockaddr_in ip4;
941  PN_CHECK_STR(addr);
942  PN_CHECK_INT(port);
943  PN_CHECK_INT(flags);
944  if (uv_ip4_addr(PN_STR_PTR(addr), PN_INT(port), &ip4)) {
945  struct sockaddr_in6 ip6;
946  if (uv_ip6_addr(PN_STR_PTR(addr), PN_INT(port), &ip6))
947  return aio_error(P, "ip_addr", 89); //EDESTADDRREQ
948  else {
949  int r = uv_udp_bind(&handle->r, (const struct sockaddr*) &ip6, PN_INT(flags));
950  return r ? aio_error(P, "udp bind6", r) : udp;
951  }
952  }
953  int r = uv_udp_bind(&handle->r, (const struct sockaddr*) &ip4, PN_INT(flags));
954  return r ? aio_error(P, "udp bind", r) : udp;
955 }
957 static PN
958 aio_udp_bind6(Potion *P, PN cl, PN udp, PN addr, PN port, PN flags) {
959  aio_udp_t *handle = AIO_DATA(udp,udp);
960  struct sockaddr_in6 ip6;
961  PN_CHECK_STR(addr);
962  PN_CHECK_INT(port);
963  PN_CHECK_INT(flags);
964  if (uv_ip6_addr(PN_STR_PTR(addr), PN_INT(port), &ip6))
965  return aio_error(P, "ip6_addr", 89); //EDESTADDRREQ
966  int r = uv_udp_bind(&handle->r, (const struct sockaddr*) &ip6, PN_INT(flags));
967  return r ? aio_error(P, "udp bind6", r) : udp;
968 }
970 static PN
972  struct sockaddr sock; int len;
973  aio_udp_t *handle = AIO_DATA(udp,udp);
974  int r = uv_udp_getsockname(&handle->r, &sock, &len);
975  return r ? aio_error(P, "udp getsockname", r) : potion_str2(P, sock.sa_data, len);
976 }
978 static PN
979 aio_udp_set_membership(Potion *P, PN cl, PN udp, PN mcaddr, PN ifaddr, PN membership) {
980  aio_udp_t *handle = AIO_DATA(udp,udp);
981  PN_CHECK_STR(mcaddr);
982  PN_CHECK_STR(ifaddr);
983  PN_CHECK_INT(membership);
984  potion_obj_set(P, cl, udp, PN_STR("membership"),
985  PN_PUSH(PN_PUSH(PN_PUSH(PN_TUP0(), mcaddr), ifaddr), membership));
986  int r = uv_udp_set_membership(&handle->r, PN_STR_PTR(mcaddr), PN_STR_PTR(ifaddr),
987  (uv_membership)PN_NUM(membership));
988  return r ? aio_error(P, "udp set_membership", r) : udp;
989 }
991 static PN
993  aio_udp_t *handle = AIO_DATA(udp,udp);
994  PN_CHECK_INT(on); //TODO boolean
995  potion_obj_set(P, cl, udp, PN_STR("multicast_loop"),
996  on == PN_ZERO ? PN_FALSE : PN_TRUE);
997  int r = uv_udp_set_multicast_loop(&handle->r, PN_NUM(on));
998  return r ? aio_error(P, "udp set_multicast_loop", r) : udp;
999 }
1001 static PN
1003  aio_udp_t *handle = AIO_DATA(udp,udp);
1004  PN_CHECK_INT(ttl);
1005  potion_obj_set(P, cl, udp, PN_STR("multicast_ttl"), ttl);
1006  int r = uv_udp_set_multicast_ttl(&handle->r, PN_NUM(ttl));
1007  return r ? aio_error(P, "udp set_multicast_ttl", r) : udp;
1008 }
1010 static PN
1012  aio_udp_t *handle = AIO_DATA(udp,udp);
1013  PN_CHECK_INT(on); //TODO boolean
1014  potion_obj_set(P, cl, udp, PN_STR("broadcast"),
1015  on == PN_ZERO ? PN_FALSE : PN_TRUE);
1016  int r = uv_udp_set_broadcast(&handle->r, PN_NUM(on));
1017  return r ? aio_error(P, "udp set_broadcast", r) : udp;
1018 }
1020 static PN
1021 aio_udp_set_ttl(Potion *P, PN cl, PN udp, PN ttl) {
1022  aio_udp_t *handle = AIO_DATA(udp,udp);
1023  PN_CHECK_INT(ttl);
1024  potion_obj_set(P, cl, udp, PN_STR("ttl"), ttl);
1025  int r = uv_udp_set_ttl(&handle->r, PN_NUM(ttl));
1026  return r ? aio_error(P, "udp set_ttl", r) : udp;
1027 }
1028 
1030 static PN
1031 aio_udp_send(Potion *P, PN cl, PN udp, PN req, PN buf, PN bufcnt, PN addr, PN port, PN cb) {
1032  aio_udp_t *handle = AIO_DATA(udp,udp);
1033  aio_udp_send_t *request = AIO_DATA(udp_send,req);
1034  aio_buf_t bufs;
1035  struct sockaddr_in ip4;
1036  PN_CHECK_STRB(buf);
1037  bufs.base = PN_STR_PTR(buf);
1038  bufs.len = PN_STR_LEN(buf);
1039  PN_CHECK_INT(bufcnt);
1040  PN_CHECK_STR(addr);
1041  PN_CHECK_INT(port);
1042  if (uv_ip4_addr(PN_STR_PTR(addr), PN_INT(port), &ip4))
1043  return aio_error(P, "ip_addr", 89); //EDESTADDRREQ
1044  AIO_CB_SET(udp_send,request);
1045  int r = uv_udp_send(&request->r, &handle->r, &bufs, bufcnt, (const struct sockaddr*) &ip4, udp_send_cb);
1046  return r ? aio_error(P, "udp send", r) : udp;
1047 }
1049 static PN
1050 aio_udp_send6(Potion *P, PN cl, PN udp, PN req, PN buf, PN bufcnt, PN addr, PN port, PN cb) {
1051  aio_udp_t *handle = AIO_DATA(udp,udp);
1052  //aio_udp_send_t *request = AIO_DATA(udp_send, req);
1053  aio_udp_send_t *request = (aio_udp_send_t*)PN_DATA(potion_fwd(req));
1054  aio_buf_t bufs;
1055  struct sockaddr_in6 ip6;
1056  PN_CHECK_STRB(buf);
1057  bufs.base = PN_STR_PTR(buf);
1058  bufs.len = PN_STR_LEN(buf);
1059  PN_CHECK_INT(bufcnt);
1060  PN_CHECK_STR(addr);
1061  PN_CHECK_INT(port);
1062  if (uv_ip6_addr(PN_STR_PTR(addr), PN_INT(port), &ip6))
1063  return aio_error(P, "ip6_addr", 89); //EDESTADDRREQ
1064  AIO_CB_SET(udp_send,request);
1065  int r = uv_udp_send(&request->r, &handle->r, &bufs, bufcnt, (const struct sockaddr*) &ip6, udp_send_cb);
1066  return r ? aio_error(P, "udp send6", r) : udp;
1067 }
1068 
1069 static void
1070 aio_alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t *buf) {
1071  aio_handle_t* wrap = (aio_handle_t*)handle;
1072  struct PNBytes *b = potion_gc_alloc(wrap->P, PN_TBYTES, suggested_size);
1073  *buf = uv_buf_init(b->chars, suggested_size);
1074 }
1075 
1089 static void
1090 aio_udp_recv_cb(uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf,
1091  const struct sockaddr* addr, unsigned flags)
1092 {
1093  struct aio_udp_s* wrap = (struct aio_udp_s*)handle;
1094  char ip[46];
1095  int port;
1096  struct sockaddr_in* addr_in = (struct sockaddr_in*)addr;
1097  vPN(Closure) cb = PN_CLOSURE(wrap->r.recv_cb);
1098  char *data = (char*)(wrap - sizeof(struct PNData));
1099  if (addr_in->sin_family == AF_INET6) {
1100  uv_ip6_name((struct sockaddr_in6*)addr, ip, 46);
1101  port = ((struct sockaddr_in6*)addr)->sin6_port;
1102  } else {
1103  uv_ip4_name(addr_in, ip, 46);
1104  port = addr_in->sin_port;
1105  }
1106  //TODO: maybe reuse PNBytes with buf structure
1107  if (cb)
1108  cb->method(wrap->P, (PN)cb, (PN)data, PN_NUM(nread),
1109  potion_byte_str2(wrap->P, buf->base, buf->len),
1110  potion_byte_str(wrap->P, ip),
1111  PN_NUM(port), PN_NUM(flags));
1112 }
1113 
1115 static PN
1116 aio_udp_recv_start(Potion *P, PN cl, PN udp, PN cb) {
1117  aio_udp_t *handle = AIO_DATA(udp,udp);
1118  AIO_CB_SET(udp_recv,handle);
1119  int r = uv_udp_recv_start(&handle->r, aio_alloc_cb, udp_recv_cb);
1120  return r ? aio_error(P, "udp recv_start", r) : udp;
1121 }
1123 static PN
1125  aio_udp_t *handle = AIO_DATA(udp,udp);
1126  int r = uv_udp_recv_stop(&handle->r);
1127  return r ? aio_error(P, "udp recv_stop", r) : udp;
1128 }
1130 static PN
1131 aio_prepare_start(Potion *P, PN cl, PN self, PN cb) {
1132  aio_prepare_t *handle = AIO_DATA(prepare,self);
1133  AIO_CB_SET(prepare,handle);
1134  int r = uv_prepare_start(&handle->r, prepare_cb);
1135  return r ? aio_error(P, "prepare start", r) : self;
1136 }
1138 static PN
1139 aio_prepare_stop(Potion *P, PN cl, PN self) {
1140  aio_prepare_t *handle = AIO_DATA(prepare,self);
1141  int r = uv_prepare_stop(&handle->r);
1142  return r ? aio_error(P, "prepare stop", r) : self;
1143 }
1145 static PN
1146 aio_check_start(Potion *P, PN cl, PN self, PN cb) {
1147  aio_check_t *handle = AIO_DATA(check, self);
1148  AIO_CB_SET(check,handle);
1149  int r = uv_check_start(&handle->r, check_cb);
1150  return r ? aio_error(P, "check start", r) : self;
1151 }
1152 static PN
1153 aio_check_stop(Potion *P, PN cl, PN self) {
1154  aio_check_t *handle = AIO_DATA(check, self);
1155  int r = uv_check_stop(&handle->r);
1156  return r ? aio_error(P, "check stop", r) : self;
1157 }
1159 static PN
1160 aio_idle_start(Potion *P, PN cl, PN self, PN cb) {
1161  aio_idle_t *handle = AIO_DATA(idle, self);
1162  AIO_CB_SET(idle,handle);
1163  int r = uv_idle_start(&handle->r, idle_cb);
1164  return r ? aio_error(P, "idle start", r) : self;
1165 }
1167 static PN
1168 aio_idle_stop(Potion *P, PN cl, PN self) {
1169  aio_idle_t *handle = AIO_DATA(idle, self);
1170  int r = uv_idle_stop(&handle->r);
1171  return r ? aio_error(P, "idle stop", r) : self;
1172 }
1173 
1176 static PN
1177 aio_tty_set_mode(Potion *P, PN cl, PN tty, PN mode) {
1178  aio_tty_t *handle = AIO_DATA(tty,tty);
1179  PN_CHECK_INT(mode);
1180  int r = uv_tty_set_mode(&handle->h, PN_INT(mode));
1181  return r ? aio_error(P, "tty set_mode", r) : tty;
1182 }
1186 static PN
1188  uv_tty_reset_mode();
1189  return tty;
1190 }
1192 static PN
1194  aio_tty_t *handle = AIO_DATA(tty,tty);
1195  int width, height;
1196  int r = uv_tty_get_winsize(&handle->h, &width, &height);
1197  return r ? aio_error(P, "tty get_winsize", r) :
1198  PN_PUSH(PN_PUSH(PN_TUP0(), PN_NUM(width)), PN_NUM(height));
1199 }
1201 static PN
1202 aio_guess_handle(Potion *P, PN cl, PN file) {
1203  PN_CHECK_INT(file);
1204  uv_handle_type r = uv_guess_handle(PN_INT(file));
1205  return PN_NUM(r);
1206 }
1207 
1209 static PN
1210 aio_pipe_open(Potion *P, PN cl, PN pipe, PN file) {
1211  aio_pipe_t *handle = AIO_DATA(pipe,pipe);
1212  PN_CHECK_INT(file);
1213  int r = uv_pipe_open(&handle->r, PN_INT(file));
1214  return r ? aio_error(P, "pipe open", r) : pipe;
1215 }
1217 static PN
1218 aio_pipe_bind(Potion *P, PN cl, PN pipe, PN name) {
1219  aio_pipe_t *handle = AIO_DATA(pipe,pipe);
1220  PN_CHECK_STR(name);
1221  int r = uv_pipe_bind(&handle->r, PN_STR_PTR(name));
1222  return r ? aio_error(P, "pipe bind", r) : pipe;
1223 }
1225 static PN
1226 aio_pipe_connect(Potion *P, PN cl, PN pipe, PN req, PN name, PN cb) {
1227  aio_pipe_t *handle = AIO_DATA(pipe,pipe);
1228  aio_connect_t *request = AIO_DATA(connect,req);
1229  AIO_CB_SET(connect,request);
1230  PN_CHECK_STR(name);
1231  uv_pipe_connect(&request->r, &handle->r, PN_STR_PTR(name), connect_cb);
1232  return pipe;
1233 }
1235 // Windows only
1236 static PN
1237 aio_pipe_pending_instances(Potion *P, PN cl, PN pipe, PN count) {
1238  aio_pipe_t *handle = AIO_DATA(pipe,pipe);
1239  PN_CHECK_INT(count);
1240  uv_pipe_pending_instances(&handle->r, PN_INT(count));
1241  return pipe;
1242 }
1244 static PN
1245 aio_shutdown(Potion *P, PN cl, PN stream, PN req, PN cb) {
1246  aio_stream_t *handle = AIO_DATA(stream,stream);
1247  aio_shutdown_t *request = AIO_DATA(shutdown,req);
1248  AIO_CB_SET(shutdown,request);
1249  int r = uv_shutdown(&request->r, &handle->r, shutdown_cb);
1250  return r ? aio_error(P, "shutdown", r) : stream;
1251 }
1252 
1257 static PN
1258 aio_write(Potion *P, PN cl, PN stream, PN req, PN buf, PN bufcnt, PN cb) {
1259  PN_CHECK_INT(bufcnt);
1260  aio_stream_t *stm = AIO_DATA(stream,stream);
1261  aio_write_t *request = AIO_DATA(write,req);
1262  aio_buf_t bufs;
1263  PN_CHECK_STRB(buf);
1264  bufs.base = PN_STR_PTR(buf);
1265  bufs.len = PN_STR_LEN(buf);
1266  AIO_CB_SET(write,request);
1267  int r = uv_write(&request->r, &stm->r, &bufs, PN_INT(bufcnt), write_cb);
1268  return r ? aio_error(P, "write", r) : stream;
1269 }
1271 static PN
1272 aio_listen(Potion *P, PN cl, PN stream, PN backlog, PN cb) {
1273  aio_stream_t *request = AIO_STREAM(stream);
1274  AIO_CB_SET(connection,request);
1275  PN_CHECK_INT(backlog);
1276  int r = uv_listen(&request->r, PN_INT(backlog), connection_cb);
1277  return r ? aio_error(P, "listen", r) : stream;
1278 }
1288 static PN
1289 aio_accept(Potion *P, PN cl, PN stream, PN client) {
1290  aio_stream_t *stream_u = AIO_STREAM(stream);
1291  aio_stream_t *client_u = AIO_STREAM(client);
1292  int r = uv_accept(&stream_u->r, &client_u->r);
1293  return r ? aio_error(P, "accept", r) : stream;
1294 }
1305 static PN
1306 aio_read_start(Potion *P, PN cl, PN self, PN cb) {
1307  aio_stream_t *handle = AIO_STREAM(self);
1308  AIO_CB_SET(read,handle);
1309  int r = uv_read_start(&handle->r, aio_alloc_cb, read_cb);
1310  return r ? aio_error(P, "read start", r) : self;
1311 }
1313 static PN
1314 aio_read_stop(Potion *P, PN cl, PN self) {
1315  aio_stream_t *handle = AIO_STREAM(self);
1316  int r = uv_read_stop(&handle->r);
1317  return r ? aio_error(P, "read stop", r) : self;
1318 }
1326 static PN
1327 aio_write2(Potion *P, PN cl, PN stream, PN req, PN buf, PN bufcnt, PN send_handle, PN cb) {
1328  aio_stream_t *stm = AIO_STREAM(stream);
1329  aio_write_t *request = AIO_DATA(write,req);
1330  aio_stream_t *handle = AIO_STREAM(send_handle);
1331  aio_buf_t bufs;
1332  PN_CHECK_INT(bufcnt);
1333  PN_CHECK_STRB(buf);
1334  bufs.base = PN_STR_PTR(buf);
1335  bufs.len = PN_STR_LEN(buf);
1336  AIO_CB_SET(write,request);
1337  int r = uv_write2(&request->r, &stm->r, &bufs, PN_INT(bufcnt), &handle->r, write_cb);
1338  return r ? aio_error(P, "write", r) : stream;
1339 }
1342 static PN
1343 aio_is_readable(Potion *P, PN cl, PN stream) {
1344  const aio_stream_t *handle = AIO_STREAM(stream);
1345  return uv_is_readable(&handle->r) ? PN_TRUE : PN_FALSE;
1346 }
1349 static PN
1350 aio_is_writable(Potion *P, PN cl, PN stream) {
1351  const aio_stream_t *handle = AIO_STREAM(stream);
1352  return uv_is_writable(&handle->r) ? PN_TRUE : PN_FALSE;
1353 }
1361 static PN
1362 aio_is_closing(Potion *P, PN cl, PN stream) {
1363  const aio_stream_t *handle = AIO_STREAM(stream);
1364  return uv_is_closing((const uv_handle_t*)&handle->r) ? PN_TRUE : PN_FALSE;
1365 }
1370 static PN
1371 aio_is_active(Potion *P, PN cl, PN self) {
1372  const aio_handle_t *handle = AIO_DATA(handle,self);
1373  return uv_is_active((const uv_handle_t*)&handle->h) ? PN_TRUE : PN_FALSE;
1374 }
1375 
1379 static PN
1380 aio_async_send(Potion *P, PN cl, PN self) {
1381  aio_async_t *handle = AIO_DATA(async,self);
1382  return PN_NUM(uv_async_send(&handle->r));
1383 }
1385 static PN
1386 aio_timer_start(Potion *P, PN cl, PN self, PN cb, PN timeout, PN repeat) {
1387  aio_timer_t *handle = AIO_DATA(timer,self);
1388  PN_CHECK_INT(timeout);
1389  PN_CHECK_INT(repeat);
1390  AIO_CB_SET(timer,handle);
1391  int r = uv_timer_start(&handle->r, timer_cb, PN_INT(timeout), PN_INT(repeat));
1392  return r ? aio_error(P, "timer start", r) : self;
1393 }
1395 static PN
1396 aio_timer_stop(Potion *P, PN cl, PN self) {
1397  aio_timer_t *handle = AIO_DATA(timer,self);
1398  int r = uv_timer_stop(&handle->r);
1399  return r ? aio_error(P, "timer stop", r) : self;
1400 }
1406 static PN
1407 aio_timer_again(Potion *P, PN cl, PN self) {
1408  aio_timer_t *handle = AIO_DATA(timer,self);
1409  int r = uv_timer_again(&handle->r);
1410  return r ? aio_error(P, "timer again", r) : self;
1411 }
1413 //TODO get/set as object ivar
1414 static PN
1416  aio_timer_t *handle = AIO_DATA(timer,self);
1417  return PN_NUM(uv_timer_get_repeat(&handle->r));
1418 }
1425 static PN
1426 aio_timer_set_repeat(Potion *P, PN cl, PN self, PN repeat) {
1427  aio_timer_t *handle = AIO_DATA(timer,self);
1428  PN_CHECK_INT(repeat);
1429  uv_timer_set_repeat(&handle->r, PN_INT(repeat));
1430  return self;
1431 }
1437 static PN
1439  aio_handle_t *handle = AIO_DATA(handle,self);
1440  return PN_NUM(uv_handle_size(handle->h.type));
1441 }
1445 static PN
1446 aio_req_uvsize(Potion *P, PN cl, PN self) {
1447  aio_req_t *req = AIO_DATA(req,self);
1448  return PN_NUM(uv_req_size(req->r.type));
1449 }
1450 
1462 static PN
1463 aio_close(Potion *P, PN cl, PN self, PN cb) {
1464  aio_handle_t* handle = AIO_DATA(handle,self);
1465  AIO_CB_SET(close, handle);
1466  uv_close(&handle->h, close_cb);
1467  return self;
1468 }
1469 
1471 static PN
1472 aio_signal_start(Potion *P, PN cl, PN self, PN cb, PN signum) {
1473  aio_signal_t *handle = AIO_DATA(signal,self);
1474  PN_CHECK_INT(signum);
1475  AIO_CB_SET(signal,handle);
1476  int r = uv_signal_start(&handle->r, signal_cb, PN_INT(signum));
1477  return r ? aio_error(P, "signal start", r) : self;
1478 }
1480 static PN
1481 aio_signal_stop(Potion *P, PN cl, PN self) {
1482  aio_signal_t *handle = AIO_DATA(signal,self);
1483  int r = uv_signal_stop(&handle->r);
1484  return r ? aio_error(P, "signal stop", r) : self;
1485 }
1486 #ifndef SANDBOX
1487 
1492 static PN aio_process_options_get(Potion *P, PN cl, PN self, PN key) {
1493  CHECK_AIO_TYPE(self,process_options);
1494  PN_CHECK_STR(key);
1495  PN v = potion_obj_get(P, 0, self, key);
1496  return v ? v : potion_error(P, potion_str_format(P, "Invalid key %s",
1497  PN_STR_PTR(key)),
1498  0, 0, 0);
1499 }
1506 static PN aio_process_options_set(Potion *P, PN cl, PN self, PN key, PN value) {
1507  CHECK_AIO_TYPE(self,process_options);
1508  PN_CHECK_STR(key);
1509  char *k = PN_STR_PTR(key);
1510  if (!strcmp(k, "file")) { PN_CHECK_STR(value); }
1511  else if (!strcmp(k, "cwd")) { PN_CHECK_STR(value); }
1512  else if (!strcmp(k, "gid")) { PN_CHECK_INT(value); } //fails on windows!
1513  else if (!strcmp(k, "uid")) { PN_CHECK_INT(value); } //fails on windows!
1514  else if (!strcmp(k, "flags")) { PN_CHECK_INT(value); }
1515  else if (!strcmp(k, "args")) {
1516  if (!value || !PN_IS_TUPLE(value)) return potion_type_error_want(P, "value", value, "Tuple");
1517  vPN(Tuple) t = PN_GET_TUPLE(value);
1518  PN_TUPLE_EACH(t, i, v, { PN_CHECK_STR(v); });
1519  }
1520  else if (!strcmp(k, "env")) {
1521  if (!value || !PN_IS_TUPLE(value)) return potion_type_error_want(P, "value", value, "Tuple");
1522  vPN(Tuple) t = PN_GET_TUPLE(value);
1523  PN_TUPLE_EACH(t, i, v, { PN_CHECK_STR(v); });
1524  }
1525  else if (!strcmp(k, "stdio")) {
1526  if (!value || !PN_IS_TUPLE(value)) return potion_type_error_want(P, "value", value, "Tuple");
1527  vPN(Tuple) t = PN_GET_TUPLE(value); //all must be numbers
1528  PN_TUPLE_EACH(t, i, v, { PN_CHECK_INT(v); });
1529  }
1530  else {
1531  return potion_error(P, potion_str_format(P, "Invalid key %s",
1532  PN_STR_PTR(key)),
1533  0, 0, 0);
1534  }
1535  potion_obj_set(P, 0, self, key, value);
1536  return (PN)self;
1537 }
1545 static PN aio_spawn(Potion *P, PN cl, PN self, PN options, PN loop) {
1546  DEF_AIO_NEW_LOOP(process);
1547  options = potion_fwd(options);
1548  CHECK_AIO_TYPE(options,process_options);
1549  //create opts from ivars
1550  uv_process_options_t opts; PN v;
1551  //"args", "cwd", "env", "exit_cb", "flags",
1552  //"gid", "stdio_count", "stdio", "uid"
1553  v = potion_obj_get(P, cl, options, PN_STR("args"));
1554  if (v) { //tuple of strings to char**
1555  int size = 0;
1556  vPN(Tuple) t = PN_GET_TUPLE(v);
1557  PN_TUPLE_EACH(t, i, v, { size += PN_STR_LEN(v) + 1; });
1558  PN args = potion_bytes(P, size);
1559  PN_TUPLE_EACH(t, i, v, { args = potion_bytes_append(P, 0, args, v); });
1560  opts.args = (char **)PN_STR_PTR(args);
1561  }
1562  if (uv_spawn(l, handle, (const uv_process_options_t*) &opts))
1563  return potion_io_error(P, "aio_spawn");
1564  return (PN)data;
1565 }
1569 static PN aio_process_kill(Potion *P, PN cl, PN self, PN signum) {
1570  aio_process_t *handle = AIO_DATA(process,self);
1571  PN_CHECK_INT(signum);
1572  int r = uv_process_kill(&handle->h, PN_INT(signum));
1573  return r ? aio_error(P, "process kill", r) : self;
1574 }
1578 static PN aio_kill(Potion *P, PN cl, PN self, PN pid, PN signum) {
1579  PN_CHECK_INT(pid);
1580  PN_CHECK_INT(signum);
1581  return PN_NUM(uv_kill(PN_INT(pid), PN_INT(signum)));
1582 }
1583 
1587 static PN aio_fs_cleanup(Potion *P, PN cl, PN self) {
1588  aio_fs_t *req = AIO_DATA(fs,self);
1589  uv_fs_req_cleanup(&req->r);
1590  return PN_TRUE;
1591 }
1596 static PN aio_fs_close(Potion *P, PN cl, PN self, PN fd, PN cb, PN loop) {
1597  DEF_AIO_NEW_LOOP(fs);
1598  aio_fs_t* req = (aio_fs_t*)handle;
1599  PN_CHECK_INT(fd);
1600  AIO_CB_SET(fs,req);
1601  int r = uv_fs_close(l, &req->r, PN_INT(fd), fs_cb);
1602  return r ? aio_error(P, "fs close", r) : self;
1603 }
1610 static PN aio_fs_open(Potion *P, PN cl, PN self, PN path, PN flags, PN mode, PN cb, PN loop) {
1611  DEF_AIO_NEW_LOOP(fs);
1612  aio_fs_t* req = (aio_fs_t*)handle;
1613  PN_CHECK_INT(flags);
1614  PN_CHECK_INT(mode);
1615  AIO_CB_SET(fs,req);
1616  int r = uv_fs_open(l, &req->r, PN_STR_PTR(path), PN_INT(flags), PN_INT(mode), fs_cb);
1617  return r ? aio_error(P, "fs open", r) : self;
1618 }
1627 static PN aio_fs_read(Potion *P, PN cl, PN self, PN fd, PN buf, PN nbufs,
1628  PN offset, PN cb, PN loop) {
1629  DEF_AIO_NEW_LOOP(fs);
1630  aio_fs_t* req = (aio_fs_t*)handle;
1631  aio_buf_t bufs;
1632  PN_CHECK_INT(fd);
1633  PN_CHECK_STRB(buf);
1634  bufs.base = PN_STR_PTR(buf);
1635  bufs.len = PN_STR_LEN(buf);
1636  PN_CHECK_STR(nbufs);
1637  PN_CHECK_INT(offset);
1638  AIO_CB_SET(fs,req);
1639  int r = uv_fs_read(l, &req->r, (uv_file)PN_INT(fd),
1640  &bufs, PN_INT(nbufs), (int64_t)PN_INT(offset), fs_cb);
1641  return r ? aio_error(P, "fs read", r) : self;
1642 }
1648 static PN aio_fs_write(Potion *P, PN cl, PN self, PN fd, PN buf, PN nbufs,
1649  PN offset, PN cb, PN loop) {
1650  DEF_AIO_NEW_LOOP(fs);
1651  aio_fs_t* req = (aio_fs_t*)handle;
1652  aio_buf_t bufs;
1653  PN_CHECK_INT(fd);
1654  PN_CHECK_STRB(buf);
1655  bufs.base = PN_STR_PTR(buf);
1656  bufs.len = PN_STR_LEN(buf);
1657  PN_CHECK_INT(offset);
1658  AIO_CB_SET(fs,req);
1659  int r = uv_fs_write(l, &req->r, PN_INT(fd), &bufs, PN_INT(nbufs), PN_INT(offset), fs_cb);
1660  return r ? aio_error(P, "fs write", r) : self;
1661 }
1666 static PN aio_fs_unlink(Potion *P, PN cl, PN self, PN path, PN cb, PN loop) {
1667  DEF_AIO_NEW_LOOP(fs);
1668  aio_fs_t* req = (aio_fs_t*)handle;
1669  PN_CHECK_STR(path);
1670  AIO_CB_SET(fs,req);
1671  int r = uv_fs_unlink(l, &req->r, PN_STR_PTR(path), fs_cb);
1672  return r ? aio_error(P, "fs open", r) : self;
1673 }
1679 static PN aio_fs_mkdir(Potion *P, PN cl, PN self, PN path, PN mode, PN cb, PN loop) {
1680  DEF_AIO_NEW_LOOP(fs);
1681  aio_fs_t* req = (aio_fs_t*)handle;
1682  PN_CHECK_STR(path);
1683  PN_CHECK_INT(mode);
1684  AIO_CB_SET(fs,req);
1685  int r = uv_fs_mkdir(l, &req->r, PN_STR_PTR(path), PN_INT(mode), fs_cb);
1686  return r ? aio_error(P, "fs mkdir", r) : self;
1687 }
1692 static PN aio_fs_mkdtemp(Potion *P, PN cl, PN self, PN tpl, PN cb, PN loop) {
1693  DEF_AIO_NEW_LOOP(fs);
1694  aio_fs_t* req = (aio_fs_t*)handle;
1695  PN_CHECK_STR(tpl);
1696  AIO_CB_SET(fs,req);
1697  int r = uv_fs_mkdtemp(l, &req->r, PN_STR_PTR(tpl), fs_cb);
1698  return r ? aio_error(P, "fs mkdtemp", r) : self;
1699 }
1704 static PN aio_fs_rmdir(Potion *P, PN cl, PN self, PN path, PN cb, PN loop) {
1705  DEF_AIO_NEW_LOOP(fs);
1706  aio_fs_t* req = (aio_fs_t*)handle;
1707  PN_CHECK_STR(path);
1708  AIO_CB_SET(fs,req);
1709  int r = uv_fs_rmdir(l, &req->r, PN_STR_PTR(path), fs_cb);
1710  return r ? aio_error(P, "fs rmdir", r) : self;
1711 }
1717 static PN aio_fs_scandir(Potion *P, PN cl, PN self, PN path, PN flags, PN cb, PN loop) {
1718  DEF_AIO_NEW_LOOP(fs);
1719  aio_fs_t* req = (aio_fs_t*)handle;
1720  PN_CHECK_STR(path);
1721  PN_CHECK_INT(flags);
1722  AIO_CB_SET(fs,req);
1723  int r = uv_fs_scandir(l, &req->r, PN_STR_PTR(path), PN_INT(flags), fs_cb);
1724  return r ? aio_error(P, "fs readdir", r) : self;
1725 }
1729 static PN aio_fs_scandir_next(Potion *P, PN cl, PN self) {
1730  aio_fs_t *req = AIO_DATA(fs,self);
1731  uv_dirent_t dent;
1732  int r = uv_fs_scandir_next(&req->r, &dent);
1733  PN retval = potion_tuple_with_size(P, 2); //uv_dirent_t
1734  vPN(Tuple) t = PN_GET_TUPLE(retval);
1735  t->set[0] = r ? PN_STR0 : PN_STR(dent.name);
1736  t->set[1] = PN_NUM(r ? -1 : dent.type); // UV_EOF
1737  return retval;
1738 }
1743 static PN aio_fs_stat(Potion *P, PN cl, PN self, PN path, PN cb, PN loop) {
1744  DEF_AIO_NEW_LOOP(fs);
1745  aio_fs_t* req = (aio_fs_t*)handle;
1746  PN_CHECK_STR(path);
1747  AIO_CB_SET(fs,req);
1748  int r = uv_fs_stat(l, &req->r, PN_STR_PTR(path), fs_cb);
1749  return r ? aio_error(P, "fs stat", r) : self;
1750 }
1755 static PN aio_fs_fstat(Potion *P, PN cl, PN self, PN fd, PN cb, PN loop) {
1756  DEF_AIO_NEW_LOOP(fs);
1757  aio_fs_t* req = (aio_fs_t*)handle;
1758  PN_CHECK_INT(fd);
1759  AIO_CB_SET(fs,req);
1760  int r = uv_fs_fstat(l, &req->r, PN_INT(fd), fs_cb);
1761  return r ? aio_error(P, "fs fstat", r) : self;
1762 }
1769 static PN aio_fs_rename(Potion *P, PN cl, PN self, PN path, PN newpath, PN cb, PN loop) {
1770  DEF_AIO_NEW_LOOP(fs);
1771  aio_fs_t* req = (aio_fs_t*)handle;
1772  PN_CHECK_STR(path);
1773  PN_CHECK_STR(newpath);
1774  AIO_CB_SET(fs,req);
1775  int r = uv_fs_rename(l, &req->r, PN_STR_PTR(path), PN_STR_PTR(newpath), fs_cb);
1776  return r ? aio_error(P, "fs rename", r) : self;
1777 }
1782 static PN aio_fs_fsync(Potion *P, PN cl, PN self, PN fd, PN cb, PN loop) {
1783  DEF_AIO_NEW_LOOP(fs);
1784  aio_fs_t* req = (aio_fs_t*)handle;
1785  PN_CHECK_INT(fd);
1786  AIO_CB_SET(fs,req);
1787  int r = uv_fs_fsync(l, &req->r, PN_INT(fd), fs_cb);
1788  return r ? aio_error(P, "fs fsync", r) : self;
1789 }
1794 static PN aio_fs_fdatasync(Potion *P, PN cl, PN self, PN fd, PN cb, PN loop) {
1795  DEF_AIO_NEW_LOOP(fs);
1796  aio_fs_t* req = (aio_fs_t*)handle;
1797  PN_CHECK_INT(fd);
1798  AIO_CB_SET(fs,req);
1799  int r = uv_fs_fdatasync(l, &req->r, PN_INT(fd), fs_cb);
1800  return r ? aio_error(P, "fs fdatasync", r) : self;
1801 }
1802 #endif /* SANDBOX */
1803 
1804 #undef DEF_AIO_NEW
1805 #undef DEF_AIO_NEW_LOOP
1806 #undef AIO_CB_SET
1807 
1808 DLLEXPORT
1810  PN aio_vt = potion_class(P, 0, 0, 0);
1811  aio_type = potion_class_type(P, aio_vt);
1812  potion_define_global(P, PN_STR("Aio"), aio_vt);
1813 #define DEF_AIO__VT(T,paren) \
1814  PN aio_##T##_vt = potion_class(P, 0, paren##_vt, 0); \
1815  aio_##T##_type = potion_class_type(P, aio_##T##_vt); \
1816  potion_define_global(P, PN_STR("Aio_" _XSTR(T)), aio_##T##_vt); \
1817  potion_method(aio_##T##_vt, ""_XSTR(T), aio_##T##_new, 0)
1818 #define DEF_AIO_CTOR(T) \
1819  potion_type_constructor_is(aio_##T##_vt, PN_FUNC(aio_##T##_new, 0));
1820 #define DEF_AIO_VT(T,paren) \
1821  PN aio_##T##_vt = potion_class(P, 0, paren##_vt, 0); \
1822  aio_##T##_type = potion_class_type(P, aio_##T##_vt); \
1823  DEF_AIO_CTOR(T); \
1824  potion_define_global(P, PN_STR("Aio_" _XSTR(T)), aio_##T##_vt); \
1825  potion_method(aio_##T##_vt, ""_XSTR(T), aio_##T##_new, 0)
1826 #define DEF_AIO_GLOBAL_VT(T,paren,args) \
1827  DEF_AIO__VT(T,paren); \
1828  potion_type_constructor_is(aio_##T##_vt, PN_FUNC(aio_##T##_new, args)); \
1829  potion_method(P->lobby, "Aio_"_XSTR(T), aio_##T##_new, args)
1830 #define DEF_AIO_NUM_GLOBAL(name) \
1831  potion_define_global(P, PN_STR("AIO_"_XSTR(name)), PN_NUM(UV_##name))
1832 
1833  DEF_AIO_NUM_GLOBAL(UDP_IPV6ONLY);
1834  DEF_AIO_NUM_GLOBAL(UDP_PARTIAL);
1835  DEF_AIO_NUM_GLOBAL(LEAVE_GROUP); //udp /membership
1836  DEF_AIO_NUM_GLOBAL(JOIN_GROUP); //udp /membership
1837 #ifndef SANDBOX
1838  DEF_AIO_NUM_GLOBAL(RUN_DEFAULT);
1839  DEF_AIO_NUM_GLOBAL(RUN_ONCE);
1840  DEF_AIO_NUM_GLOBAL(RUN_NOWAIT);
1841  DEF_AIO_NUM_GLOBAL(IGNORE); //spawn stdio_flags
1842  DEF_AIO_NUM_GLOBAL(CREATE_PIPE); //spawn
1843  DEF_AIO_NUM_GLOBAL(INHERIT_FD); //spawn
1844  DEF_AIO_NUM_GLOBAL(INHERIT_STREAM); //spawn
1845  DEF_AIO_NUM_GLOBAL(READABLE_PIPE); //spawn
1846  DEF_AIO_NUM_GLOBAL(WRITABLE_PIPE); //spawn
1847  DEF_AIO_NUM_GLOBAL(PROCESS_SETUID);
1848  DEF_AIO_NUM_GLOBAL(PROCESS_SETGID);
1849  DEF_AIO_NUM_GLOBAL(PROCESS_WINDOWS_VERBATIM_ARGUMENTS);
1850  DEF_AIO_NUM_GLOBAL(PROCESS_DETACHED);
1851  DEF_AIO_NUM_GLOBAL(PROCESS_WINDOWS_HIDE);
1852  DEF_AIO_NUM_GLOBAL(RENAME); //fs_event
1853  DEF_AIO_NUM_GLOBAL(CHANGE); //fs_event
1854  DEF_AIO_NUM_GLOBAL(FS_UNKNOWN);
1855  DEF_AIO_NUM_GLOBAL(FS_CUSTOM);
1856  DEF_AIO_NUM_GLOBAL(FS_OPEN);
1857  DEF_AIO_NUM_GLOBAL(FS_CLOSE);
1858  DEF_AIO_NUM_GLOBAL(FS_READ);
1859  DEF_AIO_NUM_GLOBAL(FS_WRITE);
1860  DEF_AIO_NUM_GLOBAL(FS_SENDFILE);
1861  DEF_AIO_NUM_GLOBAL(FS_STAT);
1862  DEF_AIO_NUM_GLOBAL(FS_LSTAT);
1863  DEF_AIO_NUM_GLOBAL(FS_FSTAT);
1864  DEF_AIO_NUM_GLOBAL(FS_FTRUNCATE);
1865  DEF_AIO_NUM_GLOBAL(FS_UTIME);
1866  DEF_AIO_NUM_GLOBAL(FS_FUTIME);
1867  DEF_AIO_NUM_GLOBAL(FS_ACCESS);
1868  DEF_AIO_NUM_GLOBAL(FS_CHMOD);
1869  DEF_AIO_NUM_GLOBAL(FS_FCHMOD);
1870  DEF_AIO_NUM_GLOBAL(FS_FSYNC);
1871  DEF_AIO_NUM_GLOBAL(FS_FDATASYNC);
1872  DEF_AIO_NUM_GLOBAL(FS_UNLINK);
1873  DEF_AIO_NUM_GLOBAL(FS_RMDIR);
1874  DEF_AIO_NUM_GLOBAL(FS_MKDIR);
1875  DEF_AIO_NUM_GLOBAL(FS_MKDTEMP);
1876  DEF_AIO_NUM_GLOBAL(FS_RENAME);
1877  DEF_AIO_NUM_GLOBAL(FS_SCANDIR);
1878  DEF_AIO_NUM_GLOBAL(FS_LINK);
1879  DEF_AIO_NUM_GLOBAL(FS_SYMLINK);
1880  DEF_AIO_NUM_GLOBAL(FS_READLINK);
1881  DEF_AIO_NUM_GLOBAL(FS_CHOWN);
1882  DEF_AIO_NUM_GLOBAL(FS_FCHOWN);
1883  DEF_AIO_NUM_GLOBAL(DIRENT_UNKNOWN);
1884  DEF_AIO_NUM_GLOBAL(DIRENT_FILE);
1885  DEF_AIO_NUM_GLOBAL(DIRENT_DIR);
1886  DEF_AIO_NUM_GLOBAL(DIRENT_LINK);
1887  DEF_AIO_NUM_GLOBAL(DIRENT_FIFO);
1888  DEF_AIO_NUM_GLOBAL(DIRENT_SOCKET);
1889  DEF_AIO_NUM_GLOBAL(DIRENT_CHAR);
1890  DEF_AIO_NUM_GLOBAL(DIRENT_BLOCK);
1891 #endif /* SANDBOX */
1892 
1893  potion_method(P->lobby, "Aio_version", aio_version, 0);
1894  potion_method(P->lobby, "Aio_version_string", aio_version_string, 0);
1895  potion_method(aio_vt, "version", aio_version, 0);
1896  potion_method(aio_vt, "version_string", aio_version_string, 0);
1897 
1898  DEF_AIO_VT(handle,aio);
1899  DEF_AIO_VT(req,aio);
1900  DEF_AIO_VT(stream,aio);
1901  DEF_AIO_GLOBAL_VT(tcp,aio_stream,"|loop=o");
1902  //DEF_AIO_GLOBAL_VT(udp,aio_stream,"|loop=o");
1903  PN udp_ivars = potion_tuple_with_size(P, 5); //sorted list of path names
1904  int i = 0;
1905  vPN(Tuple) t = PN_GET_TUPLE(udp_ivars);
1906  t->set[i++] = PN_STR("broadcast");
1907  t->set[i++] = PN_STR("membership");
1908  t->set[i++] = PN_STR("multicast_loop");
1909  t->set[i++] = PN_STR("multicast_ttl");
1910  t->set[i++] = PN_STR("ttl");
1911  PN aio_udp_vt = potion_class(P, 0, aio_stream_vt, udp_ivars);
1912  aio_udp_type = potion_class_type(P, aio_udp_vt);
1913  potion_define_global(P, PN_STR("Aio_udp"), aio_udp_vt);
1914  //potion_method(aio_udp_vt, "udp", aio_udp_new, 0);
1915  potion_type_call_is(aio_udp_vt, PN_FUNC(aio_udp_get, "key=S"));
1916  potion_type_callset_is(aio_udp_vt, PN_FUNC(aio_udp_set, "key=S,value=o"));
1917  potion_type_constructor_is(aio_udp_vt, PN_FUNC(aio_udp_new, "|loop=o"));
1918  potion_method(P->lobby, "Aio_udp", aio_udp_new, "|loop=o");
1919 
1920 #ifndef SANDBOX
1921  PN po_ivars = potion_tuple_with_size(P, 5); //sorted list of path names
1922  t = PN_GET_TUPLE(po_ivars); i = 0;
1923  t->set[i++] = PN_STR("args");
1924  t->set[i++] = PN_STR("cwd");
1925  t->set[i++] = PN_STR("env");
1926  t->set[i++] = PN_STR("exit_cb");
1927  t->set[i++] = PN_STR("flags");
1928  t->set[i++] = PN_STR("gid");
1929  t->set[i++] = PN_STR("stdio");
1930  t->set[i++] = PN_STR("uid");
1931  PN aio_po_vt = potion_class(P, 0, aio_vt, po_ivars);
1933  potion_define_global(P, PN_STR("Aio_process_options"), aio_po_vt);
1934  potion_type_call_is(aio_po_vt, PN_FUNC(aio_process_options_get, "key=S"));
1935  potion_type_callset_is(aio_po_vt, PN_FUNC(aio_process_options_set, "key=S,value=o"));
1937  potion_method(P->lobby, "Aio_process_options", aio_process_options, 0);
1938 
1939  PN aio_process_vt = potion_class(P, 0, aio_vt, 0); // with spawn as ctor
1940  aio_process_type = potion_class_type(P, aio_process_vt);
1941  potion_define_global(P, PN_STR("Aio_process"), aio_process_vt);
1942  potion_type_constructor_is(aio_process_vt, PN_FUNC(aio_spawn, "options=o|loop=o"));
1943  potion_method(P->lobby, "aio_spawn", aio_spawn, "options=o|loop=o");
1944  DEF_AIO_GLOBAL_VT(fs_event,aio,"|loop=o"); //"filename=S,cb=o,flags=N");
1945  DEF_AIO_GLOBAL_VT(fs_poll,aio,"|loop=o");
1946  DEF_AIO_GLOBAL_VT(fs,aio_req,0);
1947 #endif
1948 
1949  DEF_AIO_GLOBAL_VT(tty,aio_stream,"file=o,readable=N|loop=o");
1950  DEF_AIO_GLOBAL_VT(pipe,aio_stream,"ipc=N|loop=o");
1951  DEF_AIO_GLOBAL_VT(prepare,aio,"|loop=o");
1952  DEF_AIO_GLOBAL_VT(check,aio,"|loop=o");
1953  DEF_AIO_GLOBAL_VT(idle,aio,"|loop=o");
1954  DEF_AIO_GLOBAL_VT(timer,aio,"|loop=o");
1955  DEF_AIO_GLOBAL_VT(signal,aio,"|loop=o");
1956  //DEF_AIO_GLOBAL_VT(poll,aio,"fd=N|loop=o");
1957  DEF_AIO_GLOBAL_VT(async,aio,"cb=o|loop=o");
1958  DEF_AIO_GLOBAL_VT(mutex,aio,0);
1959  DEF_AIO_GLOBAL_VT(rwlock,aio,0);
1960  DEF_AIO_GLOBAL_VT(cond,aio,0);
1961  DEF_AIO_GLOBAL_VT(sem,aio,"value=N");
1962  DEF_AIO_GLOBAL_VT(barrier,aio,"count=N");
1963  DEF_AIO_GLOBAL_VT(loop,aio,0);
1964  //DEF_AIO_GLOBAL_VT(process,aio,0);
1965  //tcp,udp have connect so we need a global Aio_connect method
1966  DEF_AIO_GLOBAL_VT(connect,aio_stream,0);
1967  DEF_AIO_VT(write,aio);
1968  DEF_AIO_VT(shutdown,aio);
1969  DEF_AIO_VT(udp_send,aio_udp);
1970  DEF_AIO_VT(work,aio);
1971  DEF_AIO_GLOBAL_VT(getaddrinfo,aio,"cb=&,node=S,service=S,hints=o|loop=o");
1972  DEF_AIO_VT(cpu_info,aio);
1973  DEF_AIO_VT(interface_address,aio);
1974 
1975 #undef DEF_AIO_VT_1
1976 #undef DEF_AIO_CTOR
1977 #undef DEF_AIO_VT
1978 #undef DEF_AIO_GLOBAL_VT
1979 
1980  potion_method(aio_vt, "size", aio_size, 0);
1981  potion_method(aio_req_vt, "uvsize", aio_req_uvsize, 0);
1982  potion_method(aio_handle_vt, "uvsize", aio_handle_uvsize, 0);
1983  potion_method(aio_handle_vt, "close", aio_close, "|cb=&");
1984  potion_method(aio_vt, "walk", aio_walk, "|loop=o,fun=&,arg=o");
1985  potion_method(aio_vt, "run", aio_run, "|loop=o,mode=N");
1986  potion_method(aio_stream_vt, "write", aio_write, "req=o,buf=b,bufcnt=N|write_cb=&");
1987  potion_method(aio_stream_vt, "shutdown", aio_shutdown, "req=o|shutdown_cb=&");
1988  //potion_method(aio_shutdown_vt, "shutdown", aio_shutdown, "stream=o|cb=&");
1989  potion_method(aio_tcp_vt, "open", aio_tcp_open, "sock=N");
1990  potion_method(aio_tcp_vt, "nodelay", aio_tcp_nodelay, "enable=N");
1991  potion_method(aio_tcp_vt, "keepalive", aio_tcp_keepalive, "enable=N|delay:=0");
1992  potion_method(aio_tcp_vt, "simultaneous_accepts", aio_tcp_simultaneous_accepts, "enable=N");
1993  potion_method(aio_tcp_vt, "bind", aio_tcp_bind, "addr=S,port=N");
1994  potion_method(aio_tcp_vt, "bind6", aio_tcp_bind6, "addr=S,port=N");
1995  potion_method(aio_tcp_vt, "getsockname", aio_tcp_getsockname, 0);
1996  potion_method(aio_tcp_vt, "getpeername", aio_tcp_getpeername, 0);
1997  potion_method(aio_tcp_vt, "connect", aio_tcp_connect, "req=o,addr=S,port=N|connect_cb=&");
1998  potion_method(aio_tcp_vt, "connect6", aio_tcp_connect6, "req=o,addr=S,port=N|connect_cb=&");
1999  potion_method(aio_udp_vt, "open", aio_udp_open, "sockfd=N");
2000  potion_method(aio_udp_vt, "bind", aio_udp_bind, "addr=S,port=N");
2001  potion_method(aio_udp_vt, "bind6", aio_udp_bind6, "addr=S,port=N|ipv6only:=0");
2002  potion_method(aio_udp_vt, "getsockname", aio_udp_getsockname, 0);
2003  potion_method(aio_udp_vt, "set_membership", aio_udp_set_membership, "mcaddr=S,ifaddr=S,memb=N");
2004  potion_method(aio_udp_vt, "set_multicast_loop", aio_udp_set_multicast_loop, "on=N");
2005  potion_method(aio_udp_vt, "set_multicast_ttl", aio_udp_set_multicast_ttl, "ttl=N");
2006  potion_method(aio_udp_vt, "set_broadcast", aio_udp_set_broadcast, "on=N");
2007  potion_method(aio_udp_vt, "set_ttl", aio_udp_set_ttl, "ttl=N");
2008  potion_method(aio_udp_vt, "send", aio_udp_send, "req=o,buf=b,bufcnt=N,addr=S,port=N|send_cb=&");
2009  potion_method(aio_udp_vt, "send6", aio_udp_send6, "req=o,buf=b,bufcnt=N,addr=S,port=N|send_cb=&");
2010  potion_method(aio_udp_vt, "recv_start", aio_udp_recv_start, "recv_cb=&");
2011  potion_method(aio_udp_vt, "recv_stop", aio_udp_recv_stop, 0);
2012  potion_method(aio_tty_vt, "set_mode", aio_tty_set_mode, "mode=N");
2013  potion_method(aio_tty_vt, "reset_mode", aio_tty_reset_mode, 0);
2014  potion_method(aio_tty_vt, "get_winsize", aio_tty_get_winsize, 0);
2015  potion_method(aio_vt, "guess_handle", aio_guess_handle, "filefd=N");
2016  potion_method(aio_pipe_vt, "open", aio_pipe_open, "fd=N");
2017  potion_method(aio_pipe_vt, "bind", aio_pipe_bind, "name=S");
2018  potion_method(aio_pipe_vt, "connect", aio_pipe_connect, "req=o,name=S|connect_cb=&");
2019  potion_method(aio_pipe_vt, "start", aio_read_start, "cb=&");
2020  potion_method(aio_pipe_vt, "stop", aio_read_stop, 0);
2021  potion_method(aio_pipe_vt, "write", aio_write2, "req=o,buf=b,bufcnt=N|write_cb=&");
2022  potion_method(aio_pipe_vt, "pending_instances", aio_pipe_pending_instances, "count=N");
2023 
2024 #ifndef SANDBOX
2025  potion_method(aio_fs_event_vt, "start", aio_fs_event_start, "cb=&,filename=S,flags=N");
2026  potion_method(aio_fs_event_vt, "stop", aio_fs_event_stop, 0);
2027  potion_method(aio_fs_vt, "close", aio_fs_close, "fd=N,cb=&|loop=o");
2028  potion_method(aio_fs_vt, "open", aio_fs_open, "path=S,flags=N,mode=N,cb=&|loop=o");
2029  potion_method(aio_fs_vt, "read", aio_fs_read, "fd=N,buf=o,length=N,offset=N,cb=&|loop=o");
2030  potion_method(aio_fs_vt, "unlink", aio_fs_unlink, "path=S,cb=&|loop=o");
2031  potion_method(aio_fs_vt, "write", aio_fs_write, "fd=N,buf=o,length=N,offset=N,cb=&|loop=o");
2032  potion_method(aio_fs_vt, "mkdir", aio_fs_mkdir, "path=S,mode=N,cb=&|loop=o");
2033  potion_method(aio_fs_vt, "mkdtemp", aio_fs_mkdtemp, "tpl=S,cb=&|loop=o");
2034  potion_method(aio_fs_vt, "rmdir", aio_fs_rmdir, "path=S,cb=&|loop=o");
2035  //potion_method(aio_fs_vt, "readdir", aio_fs_readdir, "path=S,flags=N,cb=&|loop=o");
2036  potion_method(aio_fs_vt, "scandir", aio_fs_scandir, "path=S,flags=N,cb=&|loop=o");
2037  potion_method(aio_fs_vt, "scandir_next", aio_fs_scandir_next, "dirent=o,cb=&|loop=o");
2038  potion_method(aio_fs_vt, "stat", aio_fs_stat, "path=S,cb=&|loop=o");
2039  potion_method(aio_fs_vt, "fstat", aio_fs_fstat, "fd=N,cb=&|loop=o");
2040  potion_method(aio_fs_vt, "rename", aio_fs_rename, "path=S,newpath=S,cb=&|loop=o");
2041  potion_method(aio_fs_vt, "fsync", aio_fs_fsync, "fd=N,cb=&|loop=o");
2042  potion_method(aio_fs_vt, "fdatasync", aio_fs_fdatasync, "fd=N,cb=&|loop=o");
2043  potion_method(aio_fs_vt, "cleanup", aio_fs_cleanup, 0);
2044  potion_method(aio_process_vt, "kill", aio_process_kill, "signum=N");
2045  potion_method(P->lobby, "aio_kill", aio_kill, "pid=N,signum=N");
2046 #endif
2047  potion_method(aio_prepare_vt, "start", aio_prepare_start, "cb=&");
2048  potion_method(aio_prepare_vt, "stop", aio_prepare_stop, 0);
2049  potion_method(aio_check_vt, "start", aio_check_start, "cb=&");
2050  potion_method(aio_check_vt, "stop", aio_check_stop, 0);
2051  potion_method(aio_idle_vt, "start", aio_idle_start, "cb=&");
2052  potion_method(aio_idle_vt, "stop", aio_idle_stop, 0);
2053  potion_method(aio_async_vt, "send", aio_async_send, 0);
2054  potion_method(aio_timer_vt, "start", aio_timer_start, "cb=&,timeout=N,repeat=N");
2055  potion_method(aio_timer_vt, "stop", aio_timer_stop, 0);
2056  potion_method(aio_timer_vt, "again", aio_timer_again, 0);
2057  potion_method(aio_timer_vt, "set_repeat", aio_timer_set_repeat, "repeat=N");
2058  potion_method(aio_timer_vt, "repeat", aio_timer_get_repeat, 0);
2059  potion_method(aio_stream_vt, "listen", aio_listen, "backlog=N|cb=&");
2060  potion_method(aio_stream_vt, "accept", aio_accept, "client=o");
2061  potion_method(aio_stream_vt, "start", aio_read_start, "cb=&");
2062  potion_method(aio_stream_vt, "stop", aio_read_stop, 0);
2063 #ifdef P2
2064  potion_method(aio_handle_vt, "is_active", aio_is_active, 0);
2065  potion_method(aio_stream_vt, "is_readable", aio_is_readable, 0);
2066  potion_method(aio_stream_vt, "is_writable", aio_is_writable, 0);
2067  potion_method(aio_stream_vt, "is_closing", aio_is_closing, 0);
2068 #else
2069  potion_method(aio_handle_vt, "active?", aio_is_active, 0);
2070  potion_method(aio_stream_vt, "readable?", aio_is_readable, 0);
2071  potion_method(aio_stream_vt, "writable?", aio_is_writable, 0);
2072  potion_method(aio_stream_vt, "closing?", aio_is_closing, 0);
2073 #endif
2074  potion_method(aio_signal_vt, "start", aio_signal_start, "cb=&");
2075  potion_method(aio_signal_vt, "stop", aio_signal_stop, 0);
2076 }
#define PN_TUPLE_AT(t, n)
Definition: potion.h:278
static PN aio_udp_recv_start(Potion *P, PN cl, PN udp, PN cb)
Definition: aio.c:1116
static PN aio_cond_new(Potion *P, PN cl, PN self)
Definition: aio.c:629
static PN aio_fs_stat(Potion *P, PN cl, PN self, PN path, PN cb, PN loop)
Definition: aio.c:1743
#define PN_IS_STR(v)
Definition: potion.h:175
PN potion_bytes(Potion *, size_t)
Definition: string.c:342
PNType aio_sem_type
Definition: aio.c:23
static PN aio_is_closing(Potion *P, PN cl, PN stream)
Definition: aio.c:1362
static PN aio_handle_uvsize(Potion *P, PN cl, PN self)
Definition: aio.c:1438
PN potion_class(Potion *P, PN cl, PN self, PN ivars)
create a user-class (ie type)
Definition: objmodel.c:257
PN potion_str(Potion *, const char *)
Definition: string.c:33
static void aio_alloc_cb(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)
Definition: aio.c:1070
static PN aio_timer_stop(Potion *P, PN cl, PN self)
Definition: aio.c:1396
byte strings are raw character data, volatile, may be appended/changed.
Definition: potion.h:347
#define FATAL_AIO_STREAM(stream)
Definition: aio.c:174
static PN aio_pipe_new(Potion *P, PN cl, PN self, PN ipc, PN loop)
Definition: aio.c:585
static void aio_timer_cb(uv_timer_t *req)
Definition: aio.c:697
#define PN_CLOSURE(x)
Definition: potion.h:225
static PN aio_barrier_new(Potion *P, PN cl, PN self, PN count)
Definition: aio.c:601
#define DEF_AIO_CB(T)
Definition: aio.c:200
char data[]
Definition: potion.h:329
PNType aio_interface_address_type
Definition: aio.c:23
PNType aio_cpu_info_type
Definition: aio.c:23
static PN aio_udp_recv_stop(Potion *P, PN cl, PN udp)
Definition: aio.c:1124
static PN aio_run(Potion *P, PN cl, PN self, PN loop, PN mode)
Definition: aio.c:783
PNType aio_mutex_type
Definition: aio.c:23
PN potion_bind(Potion *P, PN rcv, PN msg)
find method for given receiver and message (method lookup)
Definition: objmodel.c:408
static PN aio_tcp_connect6(Potion *P, PN cl, PN tcp, PN req, PN addr, PN port, PN cb)
Definition: aio.c:914
PN potion_obj_set(Potion *P, PN cl, PN self, PN ivar, PN value)
implements OP_SETPATH
Definition: objmodel.c:334
#define NIL_NAME
Definition: potion.h:149
static PN aio_pipe_pending_instances(Potion *P, PN cl, PN pipe, PN count)
Definition: aio.c:1237
static PN aio_tcp_keepalive(Potion *P, PN cl, PN tcp, PN enable, PN delay)
Definition: aio.c:827
static PN aio_udp_bind(Potion *P, PN cl, PN udp, PN addr, PN port, PN flags)
Definition: aio.c:938
static PN aio_udp_new(Potion *P, PN cl, PN self, PN loop)
Definition: aio.c:255
static PN aio_shutdown_new(Potion *P, PN cl, PN self)
Definition: aio.c:452
static PN aio_udp_set_ttl(Potion *P, PN cl, PN udp, PN ttl)
Definition: aio.c:1021
static PN aio_fs_fdatasync(Potion *P, PN cl, PN self, PN fd, PN cb, PN loop)
Definition: aio.c:1794
struct to wrap arbitrary data that we may want to allocate from Potion.
Definition: potion.h:326
static PN aio_udp_send6(Potion *P, PN cl, PN udp, PN req, PN buf, PN bufcnt, PN addr, PN port, PN cb)
Definition: aio.c:1050
static PN aio_udp_set_multicast_ttl(Potion *P, PN cl, PN udp, PN ttl)
Definition: aio.c:1002
PNType aio_process_options_type
Definition: aio.c:23
PN PN potion_byte_str(Potion *, const char *)
Definition: string.c:331
#define potion_method(RCV, MSG, FN, SIG)
Definition: potion.h:789
PNType aio_check_type
Definition: aio.c:23
PNType aio_fs_type
Definition: aio.c:23
static PN aio_timer_get_repeat(Potion *P, PN cl, PN self)
Definition: aio.c:1415
static PN aio_read_stop(Potion *P, PN cl, PN self)
Definition: aio.c:1314
static PN aio_udp_set_broadcast(Potion *P, PN cl, PN udp, PN on)
Definition: aio.c:1011
PN potion_bytes_append(Potion *P, PN cl, PN self, PN str)
Definition: string.c:392
static PN aio_fs_mkdir(Potion *P, PN cl, PN self, PN path, PN mode, PN cb, PN loop)
Definition: aio.c:1679
#define AS_STR(x)
Definition: potion.h:249
PN potion_ref(Potion *P, PN data)
Definition: objmodel.c:473
PN potion_byte_str2(Potion *, const char *, size_t len)
Definition: string.c:335
unsigned int PNType
Definition: potion.h:79
static struct PNData * potion_data_alloc(Potion *P, int siz)
Definition: potion.h:765
#define PN_PUSH(T, X)
Definition: potion.h:272
PNType aio_cond_type
Definition: aio.c:23
static PN aio_fs_event_stop(Potion *P, PN cl, PN self)
Definition: aio.c:510
#define PN_STR_LEN(x)
Definition: potion.h:223
static PN potion_fwd(PN)
the potion type is the 't' in the vtable tuple (m,t)
Definition: potion.h:570
static PN aio_timer_set_repeat(Potion *P, PN cl, PN self, PN repeat)
Definition: aio.c:1426
static PN aio_fs_new(Potion *P, PN cl, PN self)
Definition: aio.c:486
static void aio_udp_send_cb(uv_udp_send_t *req, int status)
Definition: aio.c:689
static PN aio_req_new(Potion *P, PN cl, PN self)
Definition: aio.c:434
static void * potion_gc_alloc(Potion *P, PNType vt, int siz)
quick inline allocation
Definition: potion.h:700
static PN aio_udp_bind6(Potion *P, PN cl, PN udp, PN addr, PN port, PN flags)
Definition: aio.c:958
void potion_type_call_is(PN vt, PN cl)
sets the default call method of the PNVtable
Definition: objmodel.c:230
static PN aio_getaddrinfo_new(Potion *P, PN cl, PN self, PN cb, PN node, PN service, PN hints, PN loop)
Definition: aio.c:542
uv_buf_t aio_buf_t
Definition: aio.c:47
static PN aio_tty_get_winsize(Potion *P, PN cl, PN tty)
Definition: aio.c:1193
static PN aio_tcp_connect(Potion *P, PN cl, PN tcp, PN req, PN addr, PN port, PN cb)
Definition: aio.c:892
#define DEF_AIO_CB_NOSTATUS(T)
Definition: aio.c:207
#define PN_TBYTES
Definition: potion.h:121
#define PN_STR(x)
Definition: potion.h:219
PNType potion_class_type(Potion *P, PN class)
Definition: objmodel.c:290
#define PN_INT(x)
Definition: potion.h:214
#define PN_ZERO
Definition: potion.h:140
#define PN_NUM(i)
Definition: potion.h:213
static PN aio_tcp_getsockname(Potion *P, PN cl, PN tcp)
Definition: aio.c:876
static PN aio_tty_reset_mode(Potion *P, PN cl, PN tty)
Definition: aio.c:1187
static void aio_read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
Definition: aio.c:733
PNType aio_tty_type
Definition: aio.c:23
static PN aio_tcp_bind(Potion *P, PN cl, PN tcp, PN addr, PN port)
Definition: aio.c:844
static PN aio_udp_getsockname(Potion *P, PN cl, PN udp)
Definition: aio.c:971
static PN aio_sem_new(Potion *P, PN cl, PN self, PN value)
Definition: aio.c:611
static PN aio_write_new(Potion *P, PN cl, PN self)
Definition: aio.c:446
#define PN_IS_NIL(v)
Definition: potion.h:169
static PN aio_tty_set_mode(Potion *P, PN cl, PN tty, PN mode)
Definition: aio.c:1177
static PN aio_work_new(Potion *P, PN cl, PN self)
Definition: aio.c:525
static void aio_fs_cb(uv_fs_t *req)
Definition: aio.c:722
#define PN_CHECK_STR(obj)
Definition: potion.h:184
static PN aio_fs_rename(Potion *P, PN cl, PN self, PN path, PN newpath, PN cb, PN loop)
Definition: aio.c:1769
static PN aio_fs_event_start(Potion *P, PN cl, PN self, PN cb, PN filename, PN flags)
Definition: aio.c:500
PN lobby
root namespace
Definition: potion.h:657
void potion_type_callset_is(PN vt, PN cl)
set default writer
Definition: objmodel.c:240
static void aio_prepare_cb(uv_prepare_t *req)
Definition: aio.c:677
static PN aio_timer_new(Potion *P, PN cl, PN self, PN loop)
Definition: aio.c:362
static PN aio_async_new(Potion *P, PN cl, PN self, PN cb, PN loop)
Definition: aio.c:622
PNType aio_pipe_type
Definition: aio.c:23
static PN aio_check_start(Potion *P, PN cl, PN self, PN cb)
Definition: aio.c:1146
PNType aio_loop_type
Definition: aio.c:23
static PN aio_fs_write(Potion *P, PN cl, PN self, PN fd, PN buf, PN nbufs, PN offset, PN cb, PN loop)
Definition: aio.c:1648
static PN aio_tcp_simultaneous_accepts(Potion *P, PN cl, PN tcp, PN enable)
Definition: aio.c:836
static PN aio_fs_rmdir(Potion *P, PN cl, PN self, PN path, PN cb, PN loop)
Definition: aio.c:1704
PNType aio_connect_type
Definition: aio.c:23
#define DEF_AIO_NEW(T)
Definition: aio.c:115
static PN aio_tcp_getpeername(Potion *P, PN cl, PN tcp)
Definition: aio.c:884
PN potion_io_error(Potion *P, const char *msg)
Definition: internal.c:259
static PN aio_error(Potion *P, char *name, int status)
Definition: aio.c:110
static PN aio_size(Potion *P, PN cl, PN self)
Definition: aio.c:776
static PN aio_udp_set_multicast_loop(Potion *P, PN cl, PN udp, PN on)
Definition: aio.c:992
static PN aio_mutex_new(Potion *P, PN cl, PN self)
Definition: aio.c:635
PN potion_type_error(Potion *P, PN obj)
Definition: internal.c:273
static PN aio_process_kill(Potion *P, PN cl, PN self, PN signum)
Definition: aio.c:1569
static PN aio_prepare_stop(Potion *P, PN cl, PN self)
Definition: aio.c:1139
PNType aio_prepare_type
Definition: aio.c:23
static void aio_check_cb(uv_check_t *req)
Definition: aio.c:681
#define AIO_STREAM(ARG)
Definition: aio.c:195
PNType aio_udp_type
Definition: aio.c:23
static PN aio_version_string(Potion *P, PN cl, PN self)
Definition: aio.c:773
PN potion_obj_get(Potion *P, PN cl, PN self, PN ivar)
implements OP_GETPATH
Definition: objmodel.c:327
static PN aio_pipe_open(Potion *P, PN cl, PN pipe, PN file)
Definition: aio.c:1210
static PN aio_handle_new(Potion *P, PN cl, PN self)
Definition: aio.c:422
#define PN_FALSE
Definition: potion.h:141
#define DLLEXPORT
Definition: potion.h:58
#define DEF_AIO_NEW_LOOP_INIT(T)
Definition: aio.c:128
void potion_define_global(Potion *P, PN name, PN val)
Definition: objmodel.c:628
#define AIO_DATA(T, ARG)
Definition: aio.c:192
static PN aio_fs_read(Potion *P, PN cl, PN self, PN fd, PN buf, PN nbufs, PN offset, PN cb, PN loop)
Definition: aio.c:1627
static PN aio_tcp_bind6(Potion *P, PN cl, PN tcp, PN addr, PN port)
Definition: aio.c:864
static PN aio_read_start(Potion *P, PN cl, PN self, PN cb)
Definition: aio.c:1306
PNType aio_handle_type
Definition: aio.c:23
static PN aio_stream_new(Potion *P, PN cl, PN self)
Definition: aio.c:428
PNType aio_udp_send_type
Definition: aio.c:23
#define PN_VTYPE(x)
Definition: potion.h:134
PN_SIZE siz
Definition: potion.h:328
static PN aio_fs_close(Potion *P, PN cl, PN self, PN fd, PN cb, PN loop)
Definition: aio.c:1596
static PN aio_udp_send_new(Potion *P, PN cl, PN self)
Definition: aio.c:458
PNType aio_async_type
Definition: aio.c:23
static PN aio_timer_again(Potion *P, PN cl, PN self)
Definition: aio.c:1407
PNType aio_barrier_type
Definition: aio.c:23
#define PN_CHECK_TUPLE(obj)
Definition: potion.h:190
#define PN_CHECK_TYPE(obj, type)
Definition: potion.h:193
static PN aio_shutdown(Potion *P, PN cl, PN stream, PN req, PN cb)
Definition: aio.c:1245
static void aio_udp_recv_cb(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags)
Definition: aio.c:1090
static PN aio_is_active(Potion *P, PN cl, PN self)
Definition: aio.c:1371
#define AIO_CB_SET(T, ARG)
Definition: aio.c:132
#define PN_TRUE
Definition: potion.h:142
static PN aio_tcp_open(Potion *P, PN cl, PN tcp, PN sock)
Definition: aio.c:811
static PN aio_fs_cleanup(Potion *P, PN cl, PN self)
Definition: aio.c:1587
PNType aio_write_type
Definition: aio.c:23
static void aio_getaddrinfo_cb(uv_getaddrinfo_t *req, int status, struct addrinfo *res)
Definition: aio.c:216
#define AIO_CB_SET_CAST(T, ARG)
Definition: aio.c:141
PN potion_error(Potion *P, PN msg, long lineno, long charno, PN excerpt)
Definition: internal.c:236
static PN aio_tcp_nodelay(Potion *P, PN cl, PN tcp, PN enable)
Definition: aio.c:819
PNType aio_fs_event_type
Definition: aio.c:23
static PN aio_udp_open(Potion *P, PN cl, PN udp, PN sockfd)
Definition: aio.c:930
#define PN_CHECK_BOOL(obj)
Definition: potion.h:189
static PN aio_tty_new(Potion *P, PN cl, PN self, PN file, PN readable, PN loop)
Definition: aio.c:572
#define PN_IS_PTR(v)
Definition: potion.h:168
static PN aio_fs_fstat(Potion *P, PN cl, PN self, PN fd, PN cb, PN loop)
Definition: aio.c:1755
#define DEF_AIO_GLOBAL_VT(T, paren, args)
static PN aio_interface_address_new(Potion *P, PN cl, PN self)
Definition: aio.c:562
PN potion_str_format(Potion *, const char *,...) __attribute__((format(printf
DLLEXPORT void Potion_Init_aio(Potion *P)
Definition: aio.c:1809
#define PN_CHECK_INT(obj)
Definition: potion.h:187
static void aio_shutdown_cb(uv_shutdown_t *req, int status)
Definition: aio.c:673
#define CHECK_AIO_TYPE(self, T)
Definition: aio.c:152
static PN aio_udp_set(Potion *P, PN cl, PN self, PN key, PN value)
Definition: aio.c:293
static PN aio_req_uvsize(Potion *P, PN cl, PN self)
Definition: aio.c:1446
static PN aio_idle_new(Potion *P, PN cl, PN self, PN loop)
Definition: aio.c:355
#define PN_GET_TUPLE(t)
Definition: potion.h:276
static void aio_connection_cb(uv_stream_t *req, int status)
Definition: aio.c:685
static PN aio_idle_stop(Potion *P, PN cl, PN self)
Definition: aio.c:1168
static PN aio_pipe_connect(Potion *P, PN cl, PN pipe, PN req, PN name, PN cb)
Definition: aio.c:1226
static PN aio_kill(Potion *P, PN cl, PN self, PN pid, PN signum)
Definition: aio.c:1578
static PN aio_fs_poll_new(Potion *P, PN cl, PN self, PN loop)
Definition: aio.c:469
#define DEF_AIO_NUM_GLOBAL(name)
static PN aio_prepare_start(Potion *P, PN cl, PN self, PN cb)
Definition: aio.c:1131
static PN aio_write(Potion *P, PN cl, PN stream, PN req, PN buf, PN bufcnt, PN cb)
Definition: aio.c:1258
static PN aio_idle_start(Potion *P, PN cl, PN self, PN cb)
Definition: aio.c:1160
static void aio_walk_cb(uv_handle_t *handle, void *arg)
Definition: aio.c:744
PNType aio_process_type
Definition: aio.c:23
static PN aio_udp_send(Potion *P, PN cl, PN udp, PN req, PN buf, PN bufcnt, PN addr, PN port, PN cb)
Definition: aio.c:1031
static PN aio_signal_stop(Potion *P, PN cl, PN self)
Definition: aio.c:1481
the global interpreter state P. currently singleton (not threads yet)
Definition: potion.h:653
PNType aio_shutdown_type
Definition: aio.c:23
static PN aio_is_readable(Potion *P, PN cl, PN stream)
Definition: aio.c:1343
static PN aio_timer_start(Potion *P, PN cl, PN self, PN cb, PN timeout, PN repeat)
Definition: aio.c:1386
The potion API.
PNType aio_tcp_type
Definition: aio.c:23
static PN aio_tcp_new(Potion *P, PN cl, PN self, PN loop)
Definition: aio.c:231
The p2 API.
static void aio_close_cb(uv_handle_t *handle)
Definition: aio.c:753
#define DEF_AIO_HANDLE_WRAP(T)
Definition: aio.c:40
static PN aio_prepare_new(Potion *P, PN cl, PN self, PN loop)
Definition: aio.c:343
PNType aio_getaddrinfo_type
Definition: aio.c:23
#define PN_IS_INT(v)
Definition: potion.h:171
static PN aio_signal_new(Potion *P, PN cl, PN self, PN loop)
Definition: aio.c:404
PNType aio_fs_poll_type
Definition: aio.c:23
static PN aio_signal_start(Potion *P, PN cl, PN self, PN cb, PN signum)
Definition: aio.c:1472
#define PN_DATA(x)
Definition: potion.h:230
static void aio_fs_event_cb(uv_fs_event_t *handle, const char *filename, int events, int status)
Definition: aio.c:101
static PN aio_loop_new(Potion *P, PN cl, PN self)
Definition: aio.c:410
PNType aio_type
Definition: aio.c:23
PNType aio_rwlock_type
Definition: aio.c:23
static PN aio_pipe_bind(Potion *P, PN cl, PN pipe, PN name)
Definition: aio.c:1218
static PN aio_check_stop(Potion *P, PN cl, PN self)
Definition: aio.c:1153
PNType aio_signal_type
Definition: aio.c:23
PNType aio_req_type
Definition: aio.c:23
static PN aio_spawn(Potion *P, PN cl, PN self, PN options, PN loop)
Definition: aio.c:1545
#define potion_send(RCV, MSG, ARGS...)
method caches (more great stuff from ian piumarta)
Definition: potion.h:781
PN potion_str2(Potion *, char *, size_t)
Definition: string.c:47
PNType aio_stream_type
Definition: aio.c:23
PN potion_type_error_want(Potion *P, const char *param, PN obj, const char *type)
Definition: internal.c:277
static PN aio_fs_scandir(Potion *P, PN cl, PN self, PN path, PN flags, PN cb, PN loop)
Definition: aio.c:1717
PNType aio_idle_type
Definition: aio.c:23
static void aio_write_cb(uv_write_t *req, int status)
Definition: aio.c:649
static PN aio_is_writable(Potion *P, PN cl, PN stream)
Definition: aio.c:1350
const char * name
Definition: compile.c:30
#define DEF_AIO_NEW_LOOP(T)
Definition: aio.c:121
static void aio_signal_cb(uv_signal_t *req, int status)
Definition: aio.c:701
PNType aio_timer_type
Definition: aio.c:23
#define vPN(t)
Definition: buffile.c:34
volatile _PN PN
Definition: potion.h:81
PN PN_STR0
Definition: internal.c:18
static void aio_async_cb(uv_async_t *req)
Definition: aio.c:619
#define DEF_AIO_CB_WRAP1(T, H, C)
Definition: aio.c:32
PNType aio_work_type
Definition: aio.c:23
static PN aio_write2(Potion *P, PN cl, PN stream, PN req, PN buf, PN bufcnt, PN send_handle, PN cb)
Definition: aio.c:1327
#define DEF_AIO_VT(T, paren)
static PN aio_check_new(Potion *P, PN cl, PN self, PN loop)
Definition: aio.c:349
static PN aio_fs_event_new(Potion *P, PN cl, PN self, PN loop)
Definition: aio.c:492
#define PN_CHECK_STRB(obj)
Definition: potion.h:185
static PN aio_walk(Potion *P, PN cl, PN self, PN loop, PN cb, PN arg)
Definition: aio.c:796
PN PN_name
Definition: internal.c:18
static PN aio_cpu_info_new(Potion *P, PN cl, PN self)
Definition: aio.c:558
static PN aio_process_options(Potion *P, PN cl, PN self)
Definition: aio.c:516
static PN aio_fs_unlink(Potion *P, PN cl, PN self, PN path, PN cb, PN loop)
Definition: aio.c:1666
#define PN_TNUMBER
Definition: potion.h:108
static void aio_idle_cb(uv_idle_t *req)
Definition: aio.c:693
static PN aio_fs_fsync(Potion *P, PN cl, PN self, PN fd, PN cb, PN loop)
Definition: aio.c:1782
#define PN_IS_TUPLE(v)
Definition: potion.h:174
static PN aio_guess_handle(Potion *P, PN cl, PN file)
Definition: aio.c:1202
static PN aio_fs_scandir_next(Potion *P, PN cl, PN self)
Definition: aio.c:1729
static PN aio_accept(Potion *P, PN cl, PN stream, PN client)
Definition: aio.c:1289
#define PN_FUNC(f, s)
Definition: potion.h:228
static PN aio_version(Potion *P, PN cl, PN self)
Definition: aio.c:766
#define DEF_AIO_CB_WRAP(T)
Definition: aio.c:30
void potion_type_constructor_is(PN vt, PN cl)
set default constructor
Definition: objmodel.c:250
static PN aio_rwlock_new(Potion *P, PN cl, PN self)
Definition: aio.c:641
static PN aio_udp_get(Potion *P, PN cl, PN self, PN key, PN value)
Definition: aio.c:280
#define FATAL_AIO_TYPE(self, T)
Definition: aio.c:166
#define PN_TUPLE_EACH(T, I, V, B)
Definition: potion.h:288
static void aio_connect_cb(uv_connect_t *req, int status)
Definition: aio.c:653
static PN aio_connect_new(Potion *P, PN cl, PN self)
Definition: aio.c:440
static PN aio_udp_set_membership(Potion *P, PN cl, PN udp, PN mcaddr, PN ifaddr, PN membership)
Definition: aio.c:979
static PN aio_listen(Potion *P, PN cl, PN stream, PN backlog, PN cb)
Definition: aio.c:1272
void potion_fatal(char *message)
Definition: internal.c:286
char chars[]
Definition: potion.h:351
const u8 args
Definition: compile.c:31
#define PN_STR_PTR(x)
Definition: potion.h:222
#define PN_TUP0()
Definition: potion.h:270
static PN aio_close(Potion *P, PN cl, PN self, PN cb)
Definition: aio.c:1463
#define PN_VTABLE(t)
Definition: potion.h:136
PN potion_tuple_with_size(Potion *, unsigned long)
Definition: table.c:242
static PN aio_fs_open(Potion *P, PN cl, PN self, PN path, PN flags, PN mode, PN cb, PN loop)
Definition: aio.c:1610
static PN aio_fs_mkdtemp(Potion *P, PN cl, PN self, PN tpl, PN cb, PN loop)
Definition: aio.c:1692