Class/Module Index

SocketDontwait

Public Instance Methods

read([length [, buffer]]) → string, buffer, or nil view method source

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;
}
read_nonblock(maxlen) → string view method source
read_nonblock(maxlen, outbuf) → outbuf

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");
}
readpartial(maxlen) → string view method source
readpartial(maxlen, outbuf) → outbuf

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");
}
sync = boolean → boolean view method source

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;
}
write(string) → integer view method source

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);
}
write_nonblock(string) → integer view method source

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.