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