lib/sleepy_penguin/epoll.rb in sleepy_penguin-3.4.1 vs lib/sleepy_penguin/epoll.rb in sleepy_penguin-3.5.0

- old
+ new

@@ -43,28 +43,31 @@ __ep_check @io end end - # Calls epoll_wait(2) and yields Integer +events+ and IO objects watched + # 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. + # + # As of sleepy_penguin 3.5.0+, it is possible to nest + # #wait calls within the same thread. def wait(maxevents = 64, timeout = nil) # snapshot the marks so we do can sit this thread on epoll_wait while other # threads may call epoll_ctl. People say RCU is a poor man's GC, but our # (ab)use of GC here is inspired by RCU... snapshot = @mtx.synchronize do __ep_check @marks.dup end # we keep a snapshot of @marks around in case another thread closes - # the IO while it is being transferred to userspace. We release mtx + # the io while it is being transferred to userspace. We release mtx # so another thread may add events to us while we're sleeping. @io.epoll_wait(maxevents, timeout) { |events, io| yield(events, io) } ensure # hopefully Ruby does not optimize this array away... snapshot.clear @@ -85,11 +88,11 @@ end # call-seq: # ep.del(io) -> 0 # - # Disables an IO object from being watched. + # Disables an +IO+ object from being watched. def del(io) fd = io.to_io.fileno @mtx.synchronize do __ep_check @io.epoll_ctl(CTL_DEL, io, 0) @@ -123,11 +126,11 @@ end # call-seq: # epoll.mod(io, flags) -> 0 # - # Changes the watch for an existing IO object based on +events+. + # Changes the watch for an existing +IO+ object based on +events+. # Returns zero on success, will raise SystemError on failure. def mod(io, events) events = __event_flags(events) fd = io.to_io.fileno @mtx.synchronize do @@ -164,19 +167,19 @@ cur_events = @events[fd] return 0 if (cur_events & ONESHOT) == 0 && cur_events == events begin @io.epoll_ctl(CTL_MOD, io, events) rescue Errno::ENOENT - warn "epoll event cache failed (mod -> add)" + warn "epoll event cache failed (mod -> add)\n" @io.epoll_ctl(CTL_ADD, io, events) @marks[fd] = io end else begin @io.epoll_ctl(CTL_ADD, io, events) rescue Errno::EEXIST - warn "epoll event cache failed (add -> mod)" + warn "epoll event cache failed (add -> mod)\n" @io.epoll_ctl(CTL_MOD, io, events) end @marks[fd] = io end @events[fd] = events @@ -212,12 +215,12 @@ end # call-seq: # ep.io_for(io) -> object # - # Returns the given IO object currently being watched for. Different - # IO objects may internally refer to the same process file descriptor. + # Returns the given +IO+ object currently being watched for. Different + # +IO+ objects may internally refer to the same process file descriptor. # Mostly used for debugging. def io_for(io) fd = __fileno(io) @mtx.synchronize do __ep_check @@ -242,12 +245,12 @@ alias flags_for events_for # call-seq: # epoll.include?(io) -> true or false # - # Returns whether or not a given IO is watched and prevented from being + # Returns whether or not a given +IO+ is watched and prevented from being # garbage-collected by the current Epoll object. This may include - # closed IO objects. + # closed +IO+ objects. def include?(io) fd = __fileno(io) @mtx.synchronize do __ep_check @marks[fd] ? true : false