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

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?

Returns:

  • (Boolean)


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_readableObject

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_writableObject

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