This behaves like IO#read from Ruby core. If data is not immediately available, this will unset the O_NONBLOCK flag, release the GVL, and block on the socket. This will use the MSG_WAITALL flag for the recv(2) syscall to reduce context switching.
static VALUE xread(int argc, VALUE *argv, VALUE io) { struct io_args a; VALUE length; long n; prepare_read_io(&a, io); rb_scan_args(argc, argv, "02", &length, &a.buf); if (NIL_P(length)) return read_all(&a); prepare_read_buf(&a, length); if (a.len == 0) return a.buf; /* try to read as much as possible without blocking */ errno = 0; do n = (long)recv(a.fd, a.ptr, a.len, MSG_DONTWAIT); while (n > 0 && (a.ptr += n) && (a.len -= n) > 0); /* release the GVL to block on whatever's left */ rb_str_locktmp(a.buf); while (a.len > 0 && n != 0) { n = my_tbr(recv_all, &a); if (n < 0) { if (!can_retry(a.fd)) break; } } rb_str_unlocktmp(a.buf); n = RSTRING_LEN(a.buf) - a.len; rb_str_set_len(a.buf, n); if (n == 0) { if (errno) rb_sys_fail("recv"); return Qnil; } return a.buf; }
This behaves like IO#read_nonblock in Ruby core. Unlike IO#read_nonblock, this does not have the side effect of setting the O_NONBLOCK flag on the file descriptor. It should otherwise behave exactly like IO#read_nonblock when dealing with sockets.
Unlike BasicSocket#recv_nonblock, this allows outbuf to be specified and reused to reduce impact on GC. This method never releases the GVL.
static VALUE read_nonblock(int argc, VALUE *argv, VALUE io) { struct io_args a; long n; read_args(&a, argc, argv, io); if (a.len == 0) return a.buf; n = (long)recv(a.fd, a.ptr, a.len, MSG_DONTWAIT); return read_retval(&a, n, "recv"); }
This behaves like IO#readpartial from Ruby core. If data is immediately not available, this will unset the O_NONBLOCK flag, release the GVL, and block on the socket.
static VALUE readpartial(int argc, VALUE *argv, VALUE io) { struct io_args a; long n; read_args(&a, argc, argv, io); if (a.len == 0) return a.buf; /* try optimistically first */ n = (long)recv(a.fd, a.ptr, a.len, MSG_DONTWAIT); while (n < 0 && can_retry(a.fd)) { rb_str_locktmp(a.buf); /* ugh, nothing available: block on the socket */ n = my_tbr(recv_once, &a); rb_str_unlocktmp(a.buf); } return read_retval(&a, n, "recv"); }
socket_dontwait makes BasicSocket#sync= a no-op. Ruby sockets already default to synchronized operation, and socket_dontwait prevents users from changing this default as it increases complexity.
static VALUE set_sync(VALUE io, VALUE boolean) { return boolean; }
This behaves like IO#write in Ruby core.
If socket buffer space is not immediately available in the kernel, this will unset the O_NONBLOCK flag, release the GVL, and block on the socket until data is written.
static VALUE xwrite(VALUE io, VALUE str) { struct io_args a; long n; prepare_write_args(&a, io, str); /* optimistically try to send everything w/o releasing GVL */ n = (long)send(a.fd, a.ptr, a.len, MSG_DONTWAIT); if (n == a.len) return LONG2FIX(n); /* buffer may be expanded in the kernel, keep trying w/o blocking */ while (n >= 0 && (a.ptr += n) && (a.len -= n) > 0) n = (long)send(a.fd, a.ptr, a.len, MSG_DONTWAIT); /* all done, we managed to finish without releasing the GVL */ if (a.len == 0) return LONG2FIX(RSTRING_LEN(a.buf)); if (n < 0 && !can_retry(a.fd)) rb_sys_fail("send"); rb_str_locktmp(a.buf); while (a.len > 0) { n = my_tbr(send_once, &a); if (n < 0) { if (!can_retry(a.fd)) break; } } rb_str_unlocktmp(a.buf); n = RSTRING_LEN(a.buf) - a.len; rb_str_set_len(a.buf, n); if (a.len > 0) rb_sys_fail("send"); return LONG2FIX(n); }
This behaves like IO#write_nonblock in Ruby core. Unlike IO#write_nonblock, this does not have the side effect of setting the O_NONBLOCK flag on the file descriptor. It should otherwise behave exactly like IO#write_nonblock when dealing with sockets.
This method never releases the GVL.
static VALUE write_nonblock(VALUE io, VALUE str) { struct io_args a; long n; prepare_write_args(&a, io, str); n = (long)send(a.fd, a.ptr, a.len, MSG_DONTWAIT); if (n == -1) rb_sys_fail("send"); return LONG2FIX(n); }
Originally generated with the Darkfish Rdoc Generator 2, modified by wrongdoc.