Module: Rex::ThreadSafe
- Defined in:
- lib/rex/sync/thread_safe.rb
Overview
This module provides a set of methods for performing various blocking operations in a manner that is compatible with ruby style threads.
Constant Summary collapse
- DefaultCycle =
0.2
Class Method Summary collapse
-
.select(rfd = nil, wfd = nil, efd = nil, t = nil) ⇒ Object
Wraps calls to select with a lower timeout period and does the calculations to walk down to zero timeout.
-
.sleep(seconds = nil) ⇒ Object
Simulates a sleep operation by selecting on nil until a timeout period expires.
Class Method Details
.select(rfd = nil, wfd = nil, efd = nil, t = nil) ⇒ Object
Wraps calls to select with a lower timeout period and does the calculations to walk down to zero timeout. This has a little room for improvement in that it should probably check how much time actually elapsed during the select call considering ruby threading wont be exactly accurate perhaps.
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/rex/sync/thread_safe.rb', line 23 def self.select(rfd = nil, wfd = nil, efd = nil, t = nil) left = t # Immediately raise a StreamClosedError if the socket was closed. This # prevents a bad fd from being passed downstream and solves an issue # with Ruby on Windows. rfd.each { |fd| raise StreamClosedError.new(fd) if (fd.closed?) } if rfd begin orig_size = rfd.length if (rfd) # Poll the set supplied to us at least once. begin rv = ::IO.select(rfd, wfd, efd, DefaultCycle) rescue ::IOError, ::Errno::EBADF, ::Errno::ENOTSOCK # If a stream was detected as being closed, re-raise the error as # a StreamClosedError with the specific file descriptor that was # detected as being closed. This is to better handle the case of # a closed socket being detected so that it can be cleaned up and # removed. rfd.each { |fd| raise StreamClosedError.new(fd) if (fd.closed?) } if rfd # If the original rfd length is not the same as the current # length, then the list may have been altered and as such may not # contain the socket that caused the IOError. This is a bad way # to do this since it's possible that the array length could be # back to the size that it was originally and yet have had the # socket that caused the IOError to be removed. return nil if (rfd and rfd.length != orig_size) # Re-raise the exception since we didn't handle it here. raise $! # rescue ::Exception => e # $stderr.puts "SELECT(#{t}) #{[rfd,wfd,efd].inspect} #{e.class} #{e} #{e.backtrace}" end return rv if (rv) # Decrement the amount of time left by the polling cycle left -= DefaultCycle if (left) # Keep chugging until we run out of time, if time was supplied. end while ((left == nil) or (left > 0)) # Nothin. nil end |
.sleep(seconds = nil) ⇒ Object
Simulates a sleep operation by selecting on nil until a timeout period expires.
75 76 77 78 79 |
# File 'lib/rex/sync/thread_safe.rb', line 75 def self.sleep(seconds=nil) self.select(nil, nil, nil, seconds) seconds end |