Module: Celluloid::IO::CommonMethods
- Included in:
- TCPSocket
- Defined in:
- lib/celluloid/io/common_methods.rb
Overview
Common implementations of methods originall from the IO class
Instance Method Summary collapse
-
#acquire_ownership(type) ⇒ Object
Request exclusive control for a particular operation Type should be one of :r (read) or :w (write).
-
#evented? ⇒ Boolean
Are we inside of a Celluloid::IO actor?.
- #read(length = nil, buffer = nil) ⇒ Object
- #readpartial(length, buffer = nil) ⇒ Object
-
#release_ownership(type) ⇒ Object
Release ownership for a particular operation Type should be one of :r (read) or :w (write).
-
#wait_readable ⇒ Object
Wait until the current object is readable.
-
#wait_writable ⇒ Object
Wait until the current object is writable.
- #write(string) ⇒ Object (also: #<<)
Instance Method Details
#acquire_ownership(type) ⇒ Object
Request exclusive control for a particular operation Type should be one of :r (read) or :w (write)
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/celluloid/io/common_methods.rb', line 31 def acquire_ownership(type) return unless Thread.current[:actor] case type when :r ivar = :@read_owner when :w ivar = :@write_owner else raise ArgumentError, "invalid ownership type: #{type}" end # Celluloid needs a better API here o_O Thread.current[:actor].wait(self) while instance_variable_get(ivar) instance_variable_set(ivar, Task.current) end |
#evented? ⇒ Boolean
Are we inside of a Celluloid::IO actor?
6 7 8 9 |
# File 'lib/celluloid/io/common_methods.rb', line 6 def evented? actor = Thread.current[:actor] actor && actor.mailbox.is_a?(Celluloid::IO::Mailbox) end |
#read(length = nil, buffer = nil) ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/celluloid/io/common_methods.rb', line 65 def read(length = nil, buffer = nil) buffer ||= '' remaining = length acquire_ownership :r begin if length until remaining.zero? begin str = readpartial(remaining) rescue EOFError return if length == remaining return buffer end buffer << str remaining -= str.length end else while true begin buffer << read_nonblock(Socket::SO_RCVBUF) rescue Errno::EAGAIN, EOFError return buffer end end end ensure release_ownership :r end buffer end |
#readpartial(length, buffer = nil) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/celluloid/io/common_methods.rb', line 99 def readpartial(length, buffer = nil) buffer ||= '' begin read_nonblock(length, buffer) rescue ::IO::WaitReadable wait_readable retry end buffer end |
#release_ownership(type) ⇒ Object
Release ownership for a particular operation Type should be one of :r (read) or :w (write)
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/celluloid/io/common_methods.rb', line 49 def release_ownership(type) return unless Thread.current[:actor] case type when :r ivar = :@read_owner when :w ivar = :@write_owner else raise ArgumentError, "invalid ownership type: #{type}" end raise "not owner" unless instance_variable_get(ivar) == Task.current instance_variable_set(ivar, nil) Thread.current[:actor].signal(self) end |
#wait_readable ⇒ Object
Wait until the current object is readable
12 13 14 15 16 17 18 |
# File 'lib/celluloid/io/common_methods.rb', line 12 def wait_readable if evented? Celluloid.current_actor.wait_readable(self.to_io) else Kernel.select([self.to_io]) end end |
#wait_writable ⇒ Object
Wait until the current object is writable
21 22 23 24 25 26 27 |
# File 'lib/celluloid/io/common_methods.rb', line 21 def wait_writable if evented? Celluloid.current_actor.wait_writable(self.to_io) else Kernel.select([], [self.to_io]) end end |
#write(string) ⇒ Object Also known as: <<
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/celluloid/io/common_methods.rb', line 112 def write(string) length = string.length total_written = 0 remaining = string acquire_ownership :w begin while total_written < length begin written = write_nonblock(remaining) rescue ::IO::WaitWritable wait_writable retry rescue EOFError return total_written end total_written += written remaining.slice!(0, written) if written < remaining.length end ensure release_ownership :w end total_written end |