class SleepyPenguin::Epoll::IO

Epoll::IO is a low-level class. It does not provide fork nor GC-safety, so Ruby IO objects added via epoll_ctl must be retained by the application until IO#close is called.

Public Class Methods

SleepyPenguin::Epoll::IO.new(flags) → Epoll::IO object click to toggle source

Creates a new Epoll::IO object with the given flags argument. flags may currently be CLOEXEC or 0.

static VALUE s_new(VALUE klass, VALUE _flags)
{
        int default_flags = RB_SP_CLOEXEC(EPOLL_CLOEXEC);
        int flags = rb_sp_get_flags(cEpoll, _flags, default_flags);
        int fd = epoll_create1(flags);
        VALUE rv;

        if (fd < 0) {
                if (rb_sp_gc_for_fd(errno))
                        fd = epoll_create1(flags);
                if (fd < 0)
                        rb_sys_fail("epoll_create1");
        }

        rv = INT2FIX(fd);
        return rb_call_super(1, &rv);
}

Public Instance Methods

epoll_ctl(op, io, events) → nil click to toggle source

Register, modify, or register a watch for a given io for events.

op may be one of EPOLL_CTL_ADD, EPOLL_CTL_MOD, or EPOLL_CTL_DEL io is an IO object or one which proxies via the to_io method. events is an integer mask of events to watch for.

Returns nil on success.

static VALUE epctl(VALUE self, VALUE _op, VALUE io, VALUE events)
{
        struct epoll_event event;
        int epfd = rb_sp_fileno(self);
        int fd = rb_sp_fileno(io);
        int op = NUM2INT(_op);
        int rv;

        event.events = NUM2UINT(events);
        pack_event_data(&event, io);

        rv = epoll_ctl(epfd, op, fd, &event);
        if (rv < 0)
                rb_sys_fail("epoll_ctl");

        return Qnil;
}
epoll_wait([maxevents[, timeout]]) { |events, io| ... } click to toggle source

Calls epoll_wait(2) and yields Integer events and IO objects watched for. maxevents is the maximum number of events to process at once, lower numbers may prevent starvation when used by epoll_wait in multiple threads. Larger maxevents reduces syscall overhead for single-threaded applications. maxevents defaults to 64 events. timeout is specified in milliseconds, nil (the default) meaning it will block and wait indefinitely.

static VALUE epwait(int argc, VALUE *argv, VALUE self)
{
        VALUE timeout, maxevents;
        struct ep_per_thread *ept;
        int t;

        rb_need_block();
        rb_scan_args(argc, argv, "02", &maxevents, &timeout);
        t = NIL_P(timeout) ? -1 : NUM2INT(timeout);

        ept = ept_get(NIL_P(maxevents) ? 64 : NUM2INT(maxevents));
        ept->timeout = t;
        ept->io = self;

        return rb_ensure(real_epwait, (VALUE)ept, rb_sp_puttlsbuf, (VALUE)ept);
}