ext/rbuv/rbuv_tcp.c in rbuv-0.0.3 vs ext/rbuv/rbuv_tcp.c in rbuv-0.0.4

- old
+ new

@@ -5,10 +5,15 @@ VALUE cb_on_close; VALUE cb_on_connection; VALUE cb_on_read; }; +typedef struct { + uv_connect_t *uv_connect; + int status; +} _uv_tcp_on_connect_arg_t; + VALUE cRbuvTcp; /* Allocator/deallocator */ static VALUE rbuv_tcp_alloc(VALUE klass); static void rbuv_tcp_mark(rbuv_tcp_t *rbuv_tcp); @@ -28,17 +33,26 @@ uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) */ static VALUE rbuv_tcp_bind(VALUE self, VALUE ip, VALUE port); //static VALUE rbuv_tcp_bind6(VALUE self, VALUE ip, VALUE port); +static VALUE rbuv_tcp_connect(VALUE self, VALUE ip, VALUE port); +//static VALUE rbuv_tcp_connect6(VALUE self, VALUE ip, VALUE port); +/* Private methods */ +static void _uv_tcp_on_connect(uv_connect_t *uv_connect, int status); +static void _uv_tcp_on_connect_no_gvl(_uv_tcp_on_connect_arg_t *arg); +extern void __uv_stream_on_connection_no_gvl(uv_stream_t *uv_stream, int status); + void Init_rbuv_tcp() { cRbuvTcp = rb_define_class_under(mRbuv, "Tcp", cRbuvStream); rb_define_alloc_func(cRbuvTcp, rbuv_tcp_alloc); rb_define_method(cRbuvTcp, "bind", rbuv_tcp_bind, 2); //rb_define_method(cRbuvTcp, "bind6", rbuv_tcp_bind6, 2); + rb_define_method(cRbuvTcp, "connect", rbuv_tcp_connect, 2); + //rb_define_method(cRbuvTcp, "connect6", rbuv_tcp_connect6, 2); } VALUE rbuv_tcp_alloc(VALUE klass) { rbuv_tcp_t *rbuv_tcp; VALUE tcp; @@ -98,5 +112,46 @@ RSTRING_PTR(rb_inspect(self)), uv_ip, uv_port, rbuv_tcp, rbuv_tcp->uv_handle); return self; } + +VALUE rbuv_tcp_connect(VALUE self, VALUE ip, VALUE port) { + VALUE block; + const char *uv_ip; + int uv_port; + rbuv_tcp_t *rbuv_tcp; + struct sockaddr_in connect_addr; + uv_connect_t uv_connect; + + rb_need_block(); + block = rb_block_proc(); + + uv_ip = RSTRING_PTR(ip); + uv_port = FIX2INT(port); + + Data_Get_Struct(self, rbuv_tcp_t, rbuv_tcp); + rbuv_tcp->cb_on_connection = block; + + connect_addr = uv_ip4_addr(uv_ip, uv_port); + + RBUV_CHECK_UV_RETURN(uv_tcp_connect(&uv_connect, rbuv_tcp->uv_handle, + connect_addr, _uv_tcp_on_connect)); + + RBUV_DEBUG_LOG_DETAIL("self: %s, ip: %s, port: %d, rbuv_tcp: %p, uv_handle: %p", + RSTRING_PTR(rb_inspect(self)), uv_ip, uv_port, rbuv_tcp, + rbuv_tcp->uv_handle); + + return self; +} + +void _uv_tcp_on_connect(uv_connect_t *uv_connect, int status) { + _uv_tcp_on_connect_arg_t arg = { .uv_connect = uv_connect, .status = status }; + rb_thread_call_with_gvl((rbuv_rb_blocking_function_t)_uv_tcp_on_connect_no_gvl, &arg); +} + +void _uv_tcp_on_connect_no_gvl(_uv_tcp_on_connect_arg_t *arg) { + uv_connect_t *uv_connect = arg->uv_connect; + int status = arg->status; + + __uv_stream_on_connection_no_gvl(uv_connect->handle, status); +} \ No newline at end of file