uv.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. #define HL_NAME(n) uv_##n
  2. #ifdef _WIN32
  3. # include <uv.h>
  4. # include <hl.h>
  5. #else
  6. # include <hl.h>
  7. # include <uv.h>
  8. #endif
  9. #if (UV_VERSION_MAJOR <= 0)
  10. # error "libuv1-dev required, uv version 0.x found"
  11. #endif
  12. typedef struct sockaddr uv_sockaddr;
  13. #define EVT_CLOSE 1
  14. #define EVT_READ 0 // stream
  15. #define EVT_LISTEN 2 // stream
  16. #define EVT_WRITE 0 // write_t
  17. #define EVT_CONNECT 0 // connect_t
  18. #define EVT_MAX 2
  19. typedef struct {
  20. vclosure *events[EVT_MAX + 1];
  21. void *write_data;
  22. } events_data;
  23. #define UV_DATA(h) ((events_data*)((h)->data))
  24. #define _LOOP _ABSTRACT(uv_loop)
  25. #define _HANDLE _ABSTRACT(uv_handle)
  26. #define _CALLB _FUN(_VOID,_NO_ARG)
  27. #define UV_ALLOC(t) ((t*)malloc(sizeof(t)))
  28. // HANDLE
  29. static events_data *init_hl_data( uv_handle_t *h ) {
  30. events_data *d = hl_gc_alloc_raw(sizeof(events_data));
  31. memset(d,0,sizeof(events_data));
  32. hl_add_root(&h->data);
  33. h->data = d;
  34. return d;
  35. }
  36. static void register_callb( uv_handle_t *h, vclosure *c, int event_kind ) {
  37. if( !h || !h->data ) return;
  38. UV_DATA(h)->events[event_kind] = c;
  39. }
  40. static void clear_callb( uv_handle_t *h, int event_kind ) {
  41. register_callb(h,NULL,event_kind);
  42. }
  43. static void trigger_callb( uv_handle_t *h, int event_kind, vdynamic **args, int nargs, bool repeat ) {
  44. events_data *ev = UV_DATA(h);
  45. vclosure *c = ev ? ev->events[event_kind] : NULL;
  46. if( !c ) return;
  47. if( !repeat ) ev->events[event_kind] = NULL;
  48. hl_dyn_call(c, args, nargs);
  49. }
  50. static void on_close( uv_handle_t *h ) {
  51. events_data *ev = UV_DATA(h);
  52. if( !ev ) return;
  53. trigger_callb(h, EVT_CLOSE, NULL, 0, false);
  54. free(ev->write_data);
  55. hl_remove_root(&h->data);
  56. h->data = NULL;
  57. free(h);
  58. }
  59. static void free_handle( void *h ) {
  60. if( h ) uv_close((uv_handle_t*)h, on_close);
  61. }
  62. HL_PRIM void HL_NAME(close_handle)( uv_handle_t *h, vclosure *c ) {
  63. register_callb(h, c, EVT_CLOSE);
  64. free_handle(h);
  65. }
  66. DEFINE_PRIM(_VOID, close_handle, _HANDLE _CALLB);
  67. // STREAM
  68. static void on_write( uv_write_t *wr, int status ) {
  69. vdynamic b;
  70. vdynamic *args = &b;
  71. b.t = &hlt_bool;
  72. b.v.b = status == 0;
  73. trigger_callb((uv_handle_t*)wr,EVT_WRITE,&args,1,false);
  74. on_close((uv_handle_t*)wr);
  75. }
  76. HL_PRIM bool HL_NAME(stream_write)( uv_stream_t *s, vbyte *b, int size, vclosure *c ) {
  77. uv_write_t *wr = UV_ALLOC(uv_write_t);
  78. events_data *d = init_hl_data((uv_handle_t*)wr);
  79. // keep a copy of the data
  80. uv_buf_t buf;
  81. d->write_data = malloc(size);
  82. memcpy(d->write_data,b,size);
  83. buf.base = d->write_data;
  84. buf.len = size;
  85. register_callb((uv_handle_t*)wr,c,EVT_WRITE);
  86. if( uv_write(wr,s,&buf,1,on_write) < 0 ) {
  87. on_close((uv_handle_t*)wr);
  88. return false;
  89. }
  90. return true;
  91. }
  92. static void on_alloc( uv_handle_t* h, size_t size, uv_buf_t *buf ) {
  93. *buf = uv_buf_init(malloc(size), (int)size);
  94. }
  95. static void on_read( uv_stream_t *s, ssize_t nread, const uv_buf_t *buf ) {
  96. vdynamic bytes;
  97. vdynamic len;
  98. vdynamic *args[2];
  99. bytes.t = &hlt_bytes;
  100. bytes.v.ptr = buf->base;
  101. len.t = &hlt_i32;
  102. len.v.i = (int)nread;
  103. args[0] = &bytes;
  104. args[1] = &len;
  105. trigger_callb((uv_handle_t*)s,EVT_READ,args,2,true);
  106. free(buf->base);
  107. }
  108. HL_PRIM bool HL_NAME(stream_read_start)( uv_stream_t *s, vclosure *c ) {
  109. register_callb((uv_handle_t*)s,c,EVT_READ);
  110. return uv_read_start(s,on_alloc,on_read) >= 0;
  111. }
  112. HL_PRIM void HL_NAME(stream_read_stop)( uv_stream_t *s ) {
  113. uv_read_stop(s);
  114. clear_callb((uv_handle_t*)s,EVT_READ); // clear callback
  115. }
  116. static void on_listen( uv_stream_t *s, int status ) {
  117. trigger_callb((uv_handle_t*)s, EVT_LISTEN, NULL, 0, true);
  118. }
  119. HL_PRIM bool HL_NAME(stream_listen)( uv_stream_t *s, int count, vclosure *c ) {
  120. register_callb((uv_handle_t*)s,c,EVT_LISTEN);
  121. return uv_listen(s,count,on_listen) >= 0;
  122. }
  123. DEFINE_PRIM(_BOOL, stream_write, _HANDLE _BYTES _I32 _FUN(_VOID,_BOOL));
  124. DEFINE_PRIM(_BOOL, stream_read_start, _HANDLE _FUN(_VOID,_BYTES _I32));
  125. DEFINE_PRIM(_VOID, stream_read_stop, _HANDLE);
  126. DEFINE_PRIM(_BOOL, stream_listen, _HANDLE _I32 _CALLB);
  127. // TCP
  128. #define _TCP _HANDLE
  129. HL_PRIM uv_tcp_t *HL_NAME(tcp_init_wrap)( uv_loop_t *loop ) {
  130. uv_tcp_t *t = UV_ALLOC(uv_tcp_t);
  131. if( uv_tcp_init(loop,t) < 0 ) {
  132. free(t);
  133. return NULL;
  134. }
  135. init_hl_data((uv_handle_t*)t);
  136. return t;
  137. }
  138. static void on_connect( uv_connect_t *cnx, int status ) {
  139. vdynamic b;
  140. vdynamic *args = &b;
  141. b.t = &hlt_bool;
  142. b.v.b = status == 0;
  143. trigger_callb((uv_handle_t*)cnx,EVT_CONNECT,&args,1,false);
  144. on_close((uv_handle_t*)cnx);
  145. }
  146. HL_PRIM uv_connect_t *HL_NAME(tcp_connect_wrap)( uv_tcp_t *t, int host, int port, vclosure *c ) {
  147. uv_connect_t *cnx = UV_ALLOC(uv_connect_t);
  148. struct sockaddr_in addr;
  149. memset(&addr,0,sizeof(addr));
  150. addr.sin_family = AF_INET;
  151. addr.sin_port = htons((unsigned short)port);
  152. *(int*)&addr.sin_addr.s_addr = host;
  153. if( !t || uv_tcp_connect(cnx,t,(uv_sockaddr *)&addr,on_connect) < 0 ) {
  154. free(cnx);
  155. return NULL;
  156. }
  157. memset(&addr,0,sizeof(addr));
  158. init_hl_data((uv_handle_t*)cnx);
  159. register_callb((uv_handle_t*)cnx, c, EVT_CONNECT);
  160. return cnx;
  161. }
  162. HL_PRIM bool HL_NAME(tcp_bind_wrap)( uv_tcp_t *t, int host, int port ) {
  163. struct sockaddr_in addr;
  164. memset(&addr,0,sizeof(addr));
  165. addr.sin_family = AF_INET;
  166. addr.sin_port = htons((unsigned short)port);
  167. *(int*)&addr.sin_addr.s_addr = host;
  168. return uv_tcp_bind(t,(uv_sockaddr *)&addr,0) >= 0;
  169. }
  170. HL_PRIM uv_tcp_t *HL_NAME(tcp_accept_wrap)( uv_tcp_t *t ) {
  171. uv_tcp_t *client = UV_ALLOC(uv_tcp_t);
  172. if( uv_tcp_init(t->loop, client) < 0 ) {
  173. free(client);
  174. return NULL;
  175. }
  176. if( uv_accept((uv_stream_t*)t,(uv_stream_t*)client) < 0 ) {
  177. uv_close((uv_handle_t*)client, NULL);
  178. return NULL;
  179. }
  180. init_hl_data((uv_handle_t*)client);
  181. return client;
  182. }
  183. HL_PRIM void HL_NAME(tcp_nodelay_wrap)( uv_tcp_t *t, bool enable ) {
  184. uv_tcp_nodelay(t,enable?1:0);
  185. }
  186. DEFINE_PRIM(_TCP, tcp_init_wrap, _LOOP);
  187. DEFINE_PRIM(_HANDLE, tcp_connect_wrap, _TCP _I32 _I32 _FUN(_VOID,_BOOL));
  188. DEFINE_PRIM(_BOOL, tcp_bind_wrap, _TCP _I32 _I32);
  189. DEFINE_PRIM(_HANDLE, tcp_accept_wrap, _HANDLE);
  190. DEFINE_PRIM(_VOID, tcp_nodelay_wrap, _TCP _BOOL);
  191. // loop
  192. DEFINE_PRIM(_LOOP, default_loop, _NO_ARG);
  193. DEFINE_PRIM(_I32, loop_close, _LOOP);
  194. DEFINE_PRIM(_I32, run, _LOOP _I32);
  195. DEFINE_PRIM(_I32, loop_alive, _LOOP);
  196. DEFINE_PRIM(_VOID, stop, _LOOP);
  197. DEFINE_PRIM(_BYTES, strerror, _I32);