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; \
37 struct PNClosure *cb; \
40 #define DEF_AIO_HANDLE_WRAP(T) \
41 typedef struct aio_##T##_s aio_##T##_t; \
42 struct aio_##T##_s { \
45 struct PNClosure *cb; \
89 #undef DEF_AIO_CB_WRAP
90 #undef DEF_AIO_HANDLE_WRAP
91 #undef DEF_AIO_CB_WRAP1
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;
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),
112 uv_strerror(status)), 0, 0, 0);
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) \
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; \
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; \
147 else if (PN_IS_FFIPTR(cb)) \
148 T##_cb = (uv_##T##_cb)cb; \
149 else T##_cb = aio_##T##_cb
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) \
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"); \
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)); \
174 #define FATAL_AIO_STREAM(stream) \
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"))) \
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");\
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)
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)
217 aio_getaddrinfo_t* wrap = (aio_getaddrinfo_t*)req;
219 PN data = (
PN)((
char*)wrap -
sizeof(
struct PNData));
240 handle = (uv_tcp_t*)
PN_DATA(data);
241 ((aio_tcp_t*)handle)->P = P;
242 if (!loop) l = uv_default_loop();
246 r = uv_tcp_init(l, handle);
247 if (r)
return aio_error(P,
"Aio_tcp", r);
264 handle = (uv_udp_t*)
PN_DATA(data);
265 ((aio_udp_t*)handle)->P = P;
266 if (!loop) l = uv_default_loop();
270 r = uv_udp_init(l, handle);
271 if (r)
return aio_error(P,
"Aio_udp", r);
299 if (!strcmp(k,
"broadcast")) {
301 if (!uv_udp_set_broadcast(udp, value ==
PN_TRUE ? 1 : 0))
304 else if (!strcmp(k,
"multicast_loop")) {
306 if (!uv_udp_set_multicast_loop(udp, value ==
PN_TRUE ? 1 : 0))
309 else if (!strcmp(k,
"multicast_ttl")) {
311 if (!uv_udp_set_multicast_ttl(udp,
PN_INT(value)))
314 else if (!strcmp(k,
"ttl")) {
316 if (!uv_udp_set_ttl(udp,
PN_INT(value)))
319 else if (!strcmp(k,
"membership")) {
414 ((
struct aio_loop_s*)data)->P = P;
416 def = uv_default_loop();
417 memcpy(l, def,
sizeof(uv_loop_t));
501 aio_fs_event_t *handle =
AIO_DATA(fs_event,
self);
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;
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;
543 PN cb,
PN node,
PN service,
PN hints,
PN loop)
550 struct addrinfo* hints_c = (
struct addrinfo*)
PN_DATA(hints);
551 if (!node_c && !service_c) {
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);
577 if (r)
return aio_error(P,
"Aio_tty", r);
588 int r = uv_pipe_init(l, handle,
PN_NUM(ipc));
589 if (r)
return aio_error(P,
"Aio_pipe", r);
604 if (uv_barrier_init(handle,
PN_NUM(count)))
614 if (uv_sem_init(handle,
PN_NUM(value)))
625 int r = uv_async_init(l, handle, async_cb);
626 if (r)
return aio_error(P,
"Aio_async", r);
631 if (uv_cond_init(handle))
637 if (uv_mutex_init(handle))
643 if (uv_rwlock_init(handle))
657 aio_connect_t* wrap = (aio_connect_t*)req;
659 PN data = (
PN)((
char*)wrap -
sizeof(
struct PNData));
663 fprintf(stderr,
"** Invalid type %s, expected %s",
666 :
PN_IS_INT(data) ?
"Integer" :
"Boolean",
"Aio_connect");
669 if (cb) cb->method(P, (
PN)cb, data,
PN_NUM(status));
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;
717 if (cb) cb->method(P, (
PN)cb, (
PN)data,
PN_NUM(status),
723 aio_fs_t* wrap = (aio_fs_t*)req;
725 PN data = (
PN)((
char*)wrap -
sizeof(
struct PNData));
728 if (cb) cb->method(P, (
PN)cb, (
PN)data);
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;
736 PN data = (
PN)((
char*)wrap -
sizeof(
struct PNData));
740 cb->method(P, (
PN)cb, (
PN)data,
PN_NUM(nread),
745 aio_handle_t* wrap = (aio_handle_t*)handle;
747 PN data = (
PN)((
char*)wrap -
sizeof(
struct PNData));
750 if (cb) cb->method(P, (
PN)cb, (
PN)data, (
PN)arg);
754 aio_handle_t* wrap = (aio_handle_t*)handle;
756 PN data = (
PN)((
char*)wrap -
sizeof(
struct PNData));
759 if (cb) cb->method(P, (
PN)cb, (
PN)data);
767 return PN_NUM(uv_version());
774 return PN_STR(uv_version_string());
777 struct PNData* data = (
struct PNData*)
potion_fwd(
self);
785 if (!loop) l = uv_default_loop();
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;
798 if (!loop) l = uv_default_loop();
805 uv_walk(l, walk_cb, (
void *)arg);
812 aio_tcp_t *handle =
AIO_DATA(tcp,tcp);
814 int r = uv_tcp_open(&handle->r,
PN_INT(sock));
815 return r ?
aio_error(P,
"tcp open", r) : tcp;
820 aio_tcp_t *handle =
AIO_DATA(tcp,tcp);
823 return r ?
aio_error(P,
"tcp nodelay", r) : tcp;
828 aio_tcp_t *handle =
AIO_DATA(tcp,tcp);
832 return r ?
aio_error(P,
"tcp keepalive", r) : tcp;
837 aio_tcp_t *handle =
AIO_DATA(tcp,tcp);
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;
845 aio_tcp_t *handle =
AIO_DATA(tcp,tcp);
848 struct sockaddr_in ip4;
851 struct sockaddr_in6 ip6;
855 int r = uv_tcp_bind(&handle->r, (
const struct sockaddr*) &ip6, 1);
856 return r ?
aio_error(P,
"tcp bind6", r) : tcp;
859 int r = uv_tcp_bind(&handle->r, (
const struct sockaddr*) &ip4, 0);
860 return r ?
aio_error(P,
"tcp bind", r) : tcp;
865 aio_tcp_t *handle =
AIO_DATA(tcp,tcp);
868 struct sockaddr_in6 ip6;
871 int r = uv_tcp_bind(&handle->r, (
const struct sockaddr*) &ip6, 1);
872 return r ?
aio_error(P,
"tcp bind6", r) : tcp;
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);
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);
893 aio_tcp_t *handle =
AIO_DATA(tcp,tcp);
897 struct sockaddr_in ip4;
899 struct sockaddr_in6 ip6;
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;
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;
915 aio_tcp_t *handle =
AIO_DATA(tcp,tcp);
919 struct sockaddr_in6 ip6;
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)
931 aio_udp_t *handle =
AIO_DATA(udp,udp);
933 int r = uv_udp_open(&handle->r,
PN_INT(sockfd));
934 return r ?
aio_error(P,
"udp open", r) : udp;
939 aio_udp_t *handle =
AIO_DATA(udp,udp);
940 struct sockaddr_in ip4;
945 struct sockaddr_in6 ip6;
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;
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;
959 aio_udp_t *handle =
AIO_DATA(udp,udp);
960 struct sockaddr_in6 ip6;
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;
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);
980 aio_udp_t *handle =
AIO_DATA(udp,udp);
987 (uv_membership)
PN_NUM(membership));
988 return r ?
aio_error(P,
"udp set_membership", r) : udp;
993 aio_udp_t *handle =
AIO_DATA(udp,udp);
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;
1003 aio_udp_t *handle =
AIO_DATA(udp,udp);
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;
1012 aio_udp_t *handle =
AIO_DATA(udp,udp);
1016 int r = uv_udp_set_broadcast(&handle->r,
PN_NUM(on));
1017 return r ?
aio_error(P,
"udp set_broadcast", r) : udp;
1022 aio_udp_t *handle =
AIO_DATA(udp,udp);
1025 int r = uv_udp_set_ttl(&handle->r,
PN_NUM(ttl));
1026 return r ?
aio_error(P,
"udp set_ttl", r) : udp;
1032 aio_udp_t *handle =
AIO_DATA(udp,udp);
1033 aio_udp_send_t *request =
AIO_DATA(udp_send,req);
1035 struct sockaddr_in ip4;
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;
1051 aio_udp_t *handle =
AIO_DATA(udp,udp);
1055 struct sockaddr_in6 ip6;
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;
1071 aio_handle_t* wrap = (aio_handle_t*)handle;
1073 *buf = uv_buf_init(b->
chars, suggested_size);
1091 const struct sockaddr* addr,
unsigned flags)
1093 struct aio_udp_s* wrap = (
struct aio_udp_s*)handle;
1096 struct sockaddr_in* addr_in = (
struct sockaddr_in*)addr;
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;
1103 uv_ip4_name(addr_in, ip, 46);
1104 port = addr_in->sin_port;
1108 cb->method(wrap->P, (
PN)cb, (
PN)data,
PN_NUM(nread),
1117 aio_udp_t *handle =
AIO_DATA(udp,udp);
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;
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;
1132 aio_prepare_t *handle =
AIO_DATA(prepare,
self);
1134 int r = uv_prepare_start(&handle->r, prepare_cb);
1135 return r ?
aio_error(P,
"prepare start", r) :
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;
1147 aio_check_t *handle =
AIO_DATA(check,
self);
1149 int r = uv_check_start(&handle->r, check_cb);
1150 return r ?
aio_error(P,
"check start", r) :
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;
1161 aio_idle_t *handle =
AIO_DATA(idle,
self);
1163 int r = uv_idle_start(&handle->r, idle_cb);
1164 return r ?
aio_error(P,
"idle start", r) :
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;
1178 aio_tty_t *handle =
AIO_DATA(tty,tty);
1180 int r = uv_tty_set_mode(&handle->h,
PN_INT(mode));
1181 return r ?
aio_error(P,
"tty set_mode", r) : tty;
1188 uv_tty_reset_mode();
1194 aio_tty_t *handle =
AIO_DATA(tty,tty);
1196 int r = uv_tty_get_winsize(&handle->h, &width, &height);
1197 return r ?
aio_error(P,
"tty get_winsize", r) :
1204 uv_handle_type r = uv_guess_handle(
PN_INT(file));
1211 aio_pipe_t *handle =
AIO_DATA(pipe,pipe);
1213 int r = uv_pipe_open(&handle->r,
PN_INT(file));
1214 return r ?
aio_error(P,
"pipe open", r) : pipe;
1219 aio_pipe_t *handle =
AIO_DATA(pipe,pipe);
1221 int r = uv_pipe_bind(&handle->r,
PN_STR_PTR(name));
1222 return r ?
aio_error(P,
"pipe bind", r) : pipe;
1227 aio_pipe_t *handle =
AIO_DATA(pipe,pipe);
1228 aio_connect_t *request =
AIO_DATA(connect,req);
1231 uv_pipe_connect(&request->r, &handle->r,
PN_STR_PTR(name), connect_cb);
1238 aio_pipe_t *handle =
AIO_DATA(pipe,pipe);
1240 uv_pipe_pending_instances(&handle->r,
PN_INT(count));
1246 aio_stream_t *handle =
AIO_DATA(stream,stream);
1247 aio_shutdown_t *request =
AIO_DATA(shutdown,req);
1249 int r = uv_shutdown(&request->r, &handle->r, shutdown_cb);
1250 return r ?
aio_error(P,
"shutdown", r) : stream;
1260 aio_stream_t *stm =
AIO_DATA(stream,stream);
1261 aio_write_t *request =
AIO_DATA(write,req);
1267 int r = uv_write(&request->r, &stm->r, &bufs,
PN_INT(bufcnt), write_cb);
1268 return r ?
aio_error(P,
"write", r) : stream;
1276 int r = uv_listen(&request->r,
PN_INT(backlog), connection_cb);
1277 return r ?
aio_error(P,
"listen", r) : stream;
1292 int r = uv_accept(&stream_u->r, &client_u->r);
1293 return r ?
aio_error(P,
"accept", r) : stream;
1309 int r = uv_read_start(&handle->r,
aio_alloc_cb, read_cb);
1310 return r ?
aio_error(P,
"read start", r) :
self;
1316 int r = uv_read_stop(&handle->r);
1317 return r ?
aio_error(P,
"read stop", r) :
self;
1329 aio_write_t *request =
AIO_DATA(write,req);
1330 aio_stream_t *handle =
AIO_STREAM(send_handle);
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;
1344 const aio_stream_t *handle =
AIO_STREAM(stream);
1351 const aio_stream_t *handle =
AIO_STREAM(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;
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;
1381 aio_async_t *handle =
AIO_DATA(async,
self);
1382 return PN_NUM(uv_async_send(&handle->r));
1387 aio_timer_t *handle =
AIO_DATA(timer,
self);
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;
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;
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;
1416 aio_timer_t *handle =
AIO_DATA(timer,
self);
1417 return PN_NUM(uv_timer_get_repeat(&handle->r));
1427 aio_timer_t *handle =
AIO_DATA(timer,
self);
1429 uv_timer_set_repeat(&handle->r,
PN_INT(repeat));
1439 aio_handle_t *handle =
AIO_DATA(handle,
self);
1440 return PN_NUM(uv_handle_size(handle->h.type));
1447 aio_req_t *req =
AIO_DATA(req,
self);
1448 return PN_NUM(uv_req_size(req->r.type));
1464 aio_handle_t* handle =
AIO_DATA(handle,
self);
1466 uv_close(&handle->h, close_cb);
1473 aio_signal_t *handle =
AIO_DATA(signal,
self);
1476 int r = uv_signal_start(&handle->r, signal_cb,
PN_INT(signum));
1477 return r ?
aio_error(P,
"signal start", r) :
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;
1492 static PN aio_process_options_get(
Potion *P,
PN cl,
PN self,
PN key) {
1506 static PN aio_process_options_set(
Potion *P,
PN cl,
PN self,
PN key,
PN value) {
1515 else if (!strcmp(k,
"args")) {
1520 else if (!strcmp(k,
"env")) {
1525 else if (!strcmp(k,
"stdio")) {
1550 uv_process_options_t opts;
PN v;
1562 if (uv_spawn(l, handle, (
const uv_process_options_t*) &opts))
1570 aio_process_t *handle =
AIO_DATA(process,
self);
1572 int r = uv_process_kill(&handle->h,
PN_INT(signum));
1573 return r ?
aio_error(P,
"process kill", r) :
self;
1589 uv_fs_req_cleanup(&req->r);
1598 aio_fs_t* req = (aio_fs_t*)handle;
1601 int r = uv_fs_close(l, &req->r,
PN_INT(fd), fs_cb);
1602 return r ?
aio_error(P,
"fs close", r) :
self;
1612 aio_fs_t* req = (aio_fs_t*)handle;
1617 return r ?
aio_error(P,
"fs open", r) :
self;
1628 PN offset,
PN cb,
PN loop) {
1630 aio_fs_t* req = (aio_fs_t*)handle;
1639 int r = uv_fs_read(l, &req->r, (uv_file)
PN_INT(fd),
1641 return r ?
aio_error(P,
"fs read", r) :
self;
1649 PN offset,
PN cb,
PN loop) {
1651 aio_fs_t* req = (aio_fs_t*)handle;
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;
1668 aio_fs_t* req = (aio_fs_t*)handle;
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;
1681 aio_fs_t* req = (aio_fs_t*)handle;
1686 return r ?
aio_error(P,
"fs mkdir", r) :
self;
1694 aio_fs_t* req = (aio_fs_t*)handle;
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;
1706 aio_fs_t* req = (aio_fs_t*)handle;
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;
1719 aio_fs_t* req = (aio_fs_t*)handle;
1724 return r ?
aio_error(P,
"fs readdir", r) :
self;
1732 int r = uv_fs_scandir_next(&req->r, &dent);
1736 t->set[1] =
PN_NUM(r ? -1 : dent.type);
1745 aio_fs_t* req = (aio_fs_t*)handle;
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;
1757 aio_fs_t* req = (aio_fs_t*)handle;
1760 int r = uv_fs_fstat(l, &req->r,
PN_INT(fd), fs_cb);
1761 return r ?
aio_error(P,
"fs fstat", r) :
self;
1771 aio_fs_t* req = (aio_fs_t*)handle;
1776 return r ?
aio_error(P,
"fs rename", r) :
self;
1784 aio_fs_t* req = (aio_fs_t*)handle;
1787 int r = uv_fs_fsync(l, &req->r,
PN_INT(fd), fs_cb);
1788 return r ?
aio_error(P,
"fs fsync", r) :
self;
1796 aio_fs_t* req = (aio_fs_t*)handle;
1799 int r = uv_fs_fdatasync(l, &req->r,
PN_INT(fd), fs_cb);
1800 return r ?
aio_error(P,
"fs fdatasync", r) :
self;
1805 #undef DEF_AIO_NEW_LOOP
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); \
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))
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");
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");
1978 #undef DEF_AIO_GLOBAL_VT
#define PN_TUPLE_AT(t, n)
static PN aio_udp_recv_start(Potion *P, PN cl, PN udp, PN cb)
static PN aio_cond_new(Potion *P, PN cl, PN self)
static PN aio_fs_stat(Potion *P, PN cl, PN self, PN path, PN cb, PN loop)
PN potion_bytes(Potion *, size_t)
static PN aio_is_closing(Potion *P, PN cl, PN stream)
static PN aio_handle_uvsize(Potion *P, PN cl, PN self)
PN potion_class(Potion *P, PN cl, PN self, PN ivars)
create a user-class (ie type)
PN potion_str(Potion *, const char *)
static void aio_alloc_cb(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)
static PN aio_timer_stop(Potion *P, PN cl, PN self)
byte strings are raw character data, volatile, may be appended/changed.
#define FATAL_AIO_STREAM(stream)
static PN aio_pipe_new(Potion *P, PN cl, PN self, PN ipc, PN loop)
static void aio_timer_cb(uv_timer_t *req)
static PN aio_barrier_new(Potion *P, PN cl, PN self, PN count)
PNType aio_interface_address_type
static PN aio_udp_recv_stop(Potion *P, PN cl, PN udp)
static PN aio_run(Potion *P, PN cl, PN self, PN loop, PN mode)
PN potion_bind(Potion *P, PN rcv, PN msg)
find method for given receiver and message (method lookup)
static PN aio_tcp_connect6(Potion *P, PN cl, PN tcp, PN req, PN addr, PN port, PN cb)
PN potion_obj_set(Potion *P, PN cl, PN self, PN ivar, PN value)
implements OP_SETPATH
static PN aio_pipe_pending_instances(Potion *P, PN cl, PN pipe, PN count)
static PN aio_tcp_keepalive(Potion *P, PN cl, PN tcp, PN enable, PN delay)
static PN aio_udp_bind(Potion *P, PN cl, PN udp, PN addr, PN port, PN flags)
static PN aio_udp_new(Potion *P, PN cl, PN self, PN loop)
static PN aio_shutdown_new(Potion *P, PN cl, PN self)
static PN aio_udp_set_ttl(Potion *P, PN cl, PN udp, PN ttl)
static PN aio_fs_fdatasync(Potion *P, PN cl, PN self, PN fd, PN cb, PN loop)
struct to wrap arbitrary data that we may want to allocate from Potion.
static PN aio_udp_send6(Potion *P, PN cl, PN udp, PN req, PN buf, PN bufcnt, PN addr, PN port, PN cb)
static PN aio_udp_set_multicast_ttl(Potion *P, PN cl, PN udp, PN ttl)
PNType aio_process_options_type
PN PN potion_byte_str(Potion *, const char *)
#define potion_method(RCV, MSG, FN, SIG)
static PN aio_timer_get_repeat(Potion *P, PN cl, PN self)
static PN aio_read_stop(Potion *P, PN cl, PN self)
static PN aio_udp_set_broadcast(Potion *P, PN cl, PN udp, PN on)
PN potion_bytes_append(Potion *P, PN cl, PN self, PN str)
static PN aio_fs_mkdir(Potion *P, PN cl, PN self, PN path, PN mode, PN cb, PN loop)
PN potion_ref(Potion *P, PN data)
PN potion_byte_str2(Potion *, const char *, size_t len)
static struct PNData * potion_data_alloc(Potion *P, int siz)
static PN aio_fs_event_stop(Potion *P, PN cl, PN self)
static PN potion_fwd(PN)
the potion type is the 't' in the vtable tuple (m,t)
static PN aio_timer_set_repeat(Potion *P, PN cl, PN self, PN repeat)
static PN aio_fs_new(Potion *P, PN cl, PN self)
static void aio_udp_send_cb(uv_udp_send_t *req, int status)
static PN aio_req_new(Potion *P, PN cl, PN self)
static void * potion_gc_alloc(Potion *P, PNType vt, int siz)
quick inline allocation
static PN aio_udp_bind6(Potion *P, PN cl, PN udp, PN addr, PN port, PN flags)
void potion_type_call_is(PN vt, PN cl)
sets the default call method of the PNVtable
static PN aio_getaddrinfo_new(Potion *P, PN cl, PN self, PN cb, PN node, PN service, PN hints, PN loop)
static PN aio_tty_get_winsize(Potion *P, PN cl, PN tty)
static PN aio_tcp_connect(Potion *P, PN cl, PN tcp, PN req, PN addr, PN port, PN cb)
#define DEF_AIO_CB_NOSTATUS(T)
PNType potion_class_type(Potion *P, PN class)
static PN aio_tcp_getsockname(Potion *P, PN cl, PN tcp)
static PN aio_tty_reset_mode(Potion *P, PN cl, PN tty)
static void aio_read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
static PN aio_tcp_bind(Potion *P, PN cl, PN tcp, PN addr, PN port)
static PN aio_udp_getsockname(Potion *P, PN cl, PN udp)
static PN aio_sem_new(Potion *P, PN cl, PN self, PN value)
static PN aio_write_new(Potion *P, PN cl, PN self)
static PN aio_tty_set_mode(Potion *P, PN cl, PN tty, PN mode)
static PN aio_work_new(Potion *P, PN cl, PN self)
static void aio_fs_cb(uv_fs_t *req)
#define PN_CHECK_STR(obj)
static PN aio_fs_rename(Potion *P, PN cl, PN self, PN path, PN newpath, PN cb, PN loop)
static PN aio_fs_event_start(Potion *P, PN cl, PN self, PN cb, PN filename, PN flags)
void potion_type_callset_is(PN vt, PN cl)
set default writer
static void aio_prepare_cb(uv_prepare_t *req)
static PN aio_timer_new(Potion *P, PN cl, PN self, PN loop)
static PN aio_async_new(Potion *P, PN cl, PN self, PN cb, PN loop)
static PN aio_check_start(Potion *P, PN cl, PN self, PN cb)
static PN aio_fs_write(Potion *P, PN cl, PN self, PN fd, PN buf, PN nbufs, PN offset, PN cb, PN loop)
static PN aio_tcp_simultaneous_accepts(Potion *P, PN cl, PN tcp, PN enable)
static PN aio_fs_rmdir(Potion *P, PN cl, PN self, PN path, PN cb, PN loop)
static PN aio_tcp_getpeername(Potion *P, PN cl, PN tcp)
PN potion_io_error(Potion *P, const char *msg)
static PN aio_error(Potion *P, char *name, int status)
static PN aio_size(Potion *P, PN cl, PN self)
static PN aio_udp_set_multicast_loop(Potion *P, PN cl, PN udp, PN on)
static PN aio_mutex_new(Potion *P, PN cl, PN self)
PN potion_type_error(Potion *P, PN obj)
static PN aio_process_kill(Potion *P, PN cl, PN self, PN signum)
static PN aio_prepare_stop(Potion *P, PN cl, PN self)
static void aio_check_cb(uv_check_t *req)
static PN aio_version_string(Potion *P, PN cl, PN self)
PN potion_obj_get(Potion *P, PN cl, PN self, PN ivar)
implements OP_GETPATH
static PN aio_pipe_open(Potion *P, PN cl, PN pipe, PN file)
static PN aio_handle_new(Potion *P, PN cl, PN self)
#define DEF_AIO_NEW_LOOP_INIT(T)
void potion_define_global(Potion *P, PN name, PN val)
static PN aio_fs_read(Potion *P, PN cl, PN self, PN fd, PN buf, PN nbufs, PN offset, PN cb, PN loop)
static PN aio_tcp_bind6(Potion *P, PN cl, PN tcp, PN addr, PN port)
static PN aio_read_start(Potion *P, PN cl, PN self, PN cb)
static PN aio_stream_new(Potion *P, PN cl, PN self)
static PN aio_fs_close(Potion *P, PN cl, PN self, PN fd, PN cb, PN loop)
static PN aio_udp_send_new(Potion *P, PN cl, PN self)
static PN aio_timer_again(Potion *P, PN cl, PN self)
#define PN_CHECK_TUPLE(obj)
#define PN_CHECK_TYPE(obj, type)
static PN aio_shutdown(Potion *P, PN cl, PN stream, PN req, PN cb)
static void aio_udp_recv_cb(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags)
static PN aio_is_active(Potion *P, PN cl, PN self)
#define AIO_CB_SET(T, ARG)
static PN aio_tcp_open(Potion *P, PN cl, PN tcp, PN sock)
static PN aio_fs_cleanup(Potion *P, PN cl, PN self)
static void aio_getaddrinfo_cb(uv_getaddrinfo_t *req, int status, struct addrinfo *res)
#define AIO_CB_SET_CAST(T, ARG)
PN potion_error(Potion *P, PN msg, long lineno, long charno, PN excerpt)
static PN aio_tcp_nodelay(Potion *P, PN cl, PN tcp, PN enable)
static PN aio_udp_open(Potion *P, PN cl, PN udp, PN sockfd)
#define PN_CHECK_BOOL(obj)
static PN aio_tty_new(Potion *P, PN cl, PN self, PN file, PN readable, PN loop)
static PN aio_fs_fstat(Potion *P, PN cl, PN self, PN fd, PN cb, PN loop)
#define DEF_AIO_GLOBAL_VT(T, paren, args)
static PN aio_interface_address_new(Potion *P, PN cl, PN self)
PN potion_str_format(Potion *, const char *,...) __attribute__((format(printf
DLLEXPORT void Potion_Init_aio(Potion *P)
#define PN_CHECK_INT(obj)
static void aio_shutdown_cb(uv_shutdown_t *req, int status)
#define CHECK_AIO_TYPE(self, T)
static PN aio_udp_set(Potion *P, PN cl, PN self, PN key, PN value)
static PN aio_req_uvsize(Potion *P, PN cl, PN self)
static PN aio_idle_new(Potion *P, PN cl, PN self, PN loop)
static void aio_connection_cb(uv_stream_t *req, int status)
static PN aio_idle_stop(Potion *P, PN cl, PN self)
static PN aio_pipe_connect(Potion *P, PN cl, PN pipe, PN req, PN name, PN cb)
static PN aio_kill(Potion *P, PN cl, PN self, PN pid, PN signum)
static PN aio_fs_poll_new(Potion *P, PN cl, PN self, PN loop)
#define DEF_AIO_NUM_GLOBAL(name)
static PN aio_prepare_start(Potion *P, PN cl, PN self, PN cb)
static PN aio_write(Potion *P, PN cl, PN stream, PN req, PN buf, PN bufcnt, PN cb)
static PN aio_idle_start(Potion *P, PN cl, PN self, PN cb)
static void aio_walk_cb(uv_handle_t *handle, void *arg)
static PN aio_udp_send(Potion *P, PN cl, PN udp, PN req, PN buf, PN bufcnt, PN addr, PN port, PN cb)
static PN aio_signal_stop(Potion *P, PN cl, PN self)
the global interpreter state P. currently singleton (not threads yet)
static PN aio_is_readable(Potion *P, PN cl, PN stream)
static PN aio_timer_start(Potion *P, PN cl, PN self, PN cb, PN timeout, PN repeat)
static PN aio_tcp_new(Potion *P, PN cl, PN self, PN loop)
static void aio_close_cb(uv_handle_t *handle)
#define DEF_AIO_HANDLE_WRAP(T)
static PN aio_prepare_new(Potion *P, PN cl, PN self, PN loop)
PNType aio_getaddrinfo_type
static PN aio_signal_new(Potion *P, PN cl, PN self, PN loop)
static PN aio_signal_start(Potion *P, PN cl, PN self, PN cb, PN signum)
static void aio_fs_event_cb(uv_fs_event_t *handle, const char *filename, int events, int status)
static PN aio_loop_new(Potion *P, PN cl, PN self)
static PN aio_pipe_bind(Potion *P, PN cl, PN pipe, PN name)
static PN aio_check_stop(Potion *P, PN cl, PN self)
static PN aio_spawn(Potion *P, PN cl, PN self, PN options, PN loop)
#define potion_send(RCV, MSG, ARGS...)
method caches (more great stuff from ian piumarta)
PN potion_str2(Potion *, char *, size_t)
PN potion_type_error_want(Potion *P, const char *param, PN obj, const char *type)
static PN aio_fs_scandir(Potion *P, PN cl, PN self, PN path, PN flags, PN cb, PN loop)
static void aio_write_cb(uv_write_t *req, int status)
static PN aio_is_writable(Potion *P, PN cl, PN stream)
#define DEF_AIO_NEW_LOOP(T)
static void aio_signal_cb(uv_signal_t *req, int status)
static void aio_async_cb(uv_async_t *req)
#define DEF_AIO_CB_WRAP1(T, H, C)
static PN aio_write2(Potion *P, PN cl, PN stream, PN req, PN buf, PN bufcnt, PN send_handle, PN cb)
#define DEF_AIO_VT(T, paren)
static PN aio_check_new(Potion *P, PN cl, PN self, PN loop)
static PN aio_fs_event_new(Potion *P, PN cl, PN self, PN loop)
#define PN_CHECK_STRB(obj)
static PN aio_walk(Potion *P, PN cl, PN self, PN loop, PN cb, PN arg)
static PN aio_cpu_info_new(Potion *P, PN cl, PN self)
static PN aio_process_options(Potion *P, PN cl, PN self)
static PN aio_fs_unlink(Potion *P, PN cl, PN self, PN path, PN cb, PN loop)
static void aio_idle_cb(uv_idle_t *req)
static PN aio_fs_fsync(Potion *P, PN cl, PN self, PN fd, PN cb, PN loop)
static PN aio_guess_handle(Potion *P, PN cl, PN file)
static PN aio_fs_scandir_next(Potion *P, PN cl, PN self)
static PN aio_accept(Potion *P, PN cl, PN stream, PN client)
static PN aio_version(Potion *P, PN cl, PN self)
#define DEF_AIO_CB_WRAP(T)
void potion_type_constructor_is(PN vt, PN cl)
set default constructor
static PN aio_rwlock_new(Potion *P, PN cl, PN self)
static PN aio_udp_get(Potion *P, PN cl, PN self, PN key, PN value)
#define FATAL_AIO_TYPE(self, T)
#define PN_TUPLE_EACH(T, I, V, B)
static void aio_connect_cb(uv_connect_t *req, int status)
static PN aio_connect_new(Potion *P, PN cl, PN self)
static PN aio_udp_set_membership(Potion *P, PN cl, PN udp, PN mcaddr, PN ifaddr, PN membership)
static PN aio_listen(Potion *P, PN cl, PN stream, PN backlog, PN cb)
void potion_fatal(char *message)
static PN aio_close(Potion *P, PN cl, PN self, PN cb)
PN potion_tuple_with_size(Potion *, unsigned long)
static PN aio_fs_open(Potion *P, PN cl, PN self, PN path, PN flags, PN mode, PN cb, PN loop)
static PN aio_fs_mkdtemp(Potion *P, PN cl, PN self, PN tpl, PN cb, PN loop)