polyphony 1.1 → 1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +1 -1
  3. data/.github/workflows/test_io_uring.yml +1 -1
  4. data/.rubocop.yml +16 -8
  5. data/CHANGELOG.md +13 -0
  6. data/README.md +2 -1
  7. data/docs/advanced-io.md +141 -44
  8. data/docs/cancellation.md +213 -0
  9. data/docs/readme.md +2 -1
  10. data/examples/core/enumerator.rb +92 -0
  11. data/examples/io/https_server_sni_2.rb +1 -1
  12. data/ext/polyphony/backend_common.c +11 -0
  13. data/ext/polyphony/backend_common.h +2 -0
  14. data/ext/polyphony/backend_io_uring.c +1 -1
  15. data/ext/polyphony/backend_libev.c +1 -1
  16. data/ext/polyphony/polyphony.h +3 -1
  17. data/lib/polyphony/core/debug.rb +24 -29
  18. data/lib/polyphony/core/exceptions.rb +0 -3
  19. data/lib/polyphony/core/sync.rb +0 -3
  20. data/lib/polyphony/core/thread_pool.rb +1 -5
  21. data/lib/polyphony/core/throttler.rb +0 -1
  22. data/lib/polyphony/core/timer.rb +7 -9
  23. data/lib/polyphony/extensions/exception.rb +0 -1
  24. data/lib/polyphony/extensions/fiber.rb +41 -28
  25. data/lib/polyphony/extensions/io.rb +86 -93
  26. data/lib/polyphony/extensions/kernel.rb +52 -16
  27. data/lib/polyphony/extensions/object.rb +7 -6
  28. data/lib/polyphony/extensions/openssl.rb +6 -8
  29. data/lib/polyphony/extensions/pipe.rb +5 -7
  30. data/lib/polyphony/extensions/socket.rb +28 -37
  31. data/lib/polyphony/extensions/thread.rb +2 -4
  32. data/lib/polyphony/extensions/timeout.rb +0 -1
  33. data/lib/polyphony/version.rb +1 -1
  34. data/lib/polyphony.rb +4 -7
  35. data/polyphony.gemspec +2 -2
  36. data/test/test_fiber.rb +6 -6
  37. data/test/test_global_api.rb +3 -3
  38. data/test/test_io.rb +2 -2
  39. data/test/test_socket.rb +2 -2
  40. data/test/test_supervise.rb +1 -1
  41. metadata +6 -4
@@ -80,7 +80,6 @@ class ::IO
80
80
  # @!visibility private
81
81
  alias_method :orig_popen, :popen
82
82
 
83
-
84
83
  # @!visibility private
85
84
  def popen(cmd, mode = 'r')
86
85
  return orig_popen(cmd, mode) unless block_given?
@@ -163,7 +162,6 @@ class ::IO
163
162
  # @!visibility private
164
163
  alias_method :orig_getbyte, :getbyte
165
164
 
166
-
167
165
  # @!visibility private
168
166
  def getbyte
169
167
  char = getc
@@ -173,7 +171,6 @@ class ::IO
173
171
  # @!visibility private
174
172
  alias_method :orig_getc, :getc
175
173
 
176
-
177
174
  # @!visibility private
178
175
  def getc
179
176
  return @read_buffer.slice!(0) if @read_buffer && !@read_buffer.empty?
@@ -186,12 +183,12 @@ class ::IO
186
183
  end
187
184
 
188
185
  # @!visibility private
189
- def ungetc(c)
190
- c = c.chr if c.is_a?(Integer)
186
+ def ungetc(chr)
187
+ chr = chr.chr if chr.is_a?(Integer)
191
188
  if @read_buffer
192
- @read_buffer.prepend(c)
189
+ @read_buffer.prepend(chr)
193
190
  else
194
- @read_buffer = +c
191
+ @read_buffer = +chr
195
192
  end
196
193
  end
197
194
  alias_method :ungetbyte, :ungetc
@@ -199,14 +196,10 @@ class ::IO
199
196
  # @!visibility private
200
197
  alias_method :orig_read, :read
201
198
 
202
-
203
199
  # @!visibility private
204
- def read(len = nil, buf = nil, buf_pos = 0)
200
+ def read(len = nil, buf = nil, buffer_pos: 0)
205
201
  return '' if len == 0
206
-
207
- if buf
208
- return Polyphony.backend_read(self, buf, len, true, buf_pos)
209
- end
202
+ return Polyphony.backend_read(self, buf, len, true, buffer_pos) if buf
210
203
 
211
204
  @read_buffer ||= +''
212
205
  result = Polyphony.backend_read(self, @read_buffer, len, true, -1)
@@ -221,7 +214,7 @@ class ::IO
221
214
  alias_method :orig_readpartial, :read
222
215
 
223
216
  # @!visibility private
224
- def readpartial(len, str = +'', buffer_pos = 0, raise_on_eof = true)
217
+ def readpartial(len, str = +'', buffer_pos: 0, raise_on_eof: true)
225
218
  result = Polyphony.backend_read(self, str, len, false, buffer_pos)
226
219
  raise EOFError if !result && raise_on_eof
227
220
 
@@ -262,7 +255,7 @@ class ::IO
262
255
  idx = @read_buffer.index(sep)
263
256
  return @read_buffer.slice!(0, idx + sep_size) if idx
264
257
 
265
- result = readpartial(8192, @read_buffer, -1)
258
+ result = readpartial(8192, @read_buffer, buffer_pos: -1)
266
259
  return nil unless result
267
260
  end
268
261
  rescue EOFError
@@ -287,7 +280,7 @@ class ::IO
287
280
  yield line
288
281
  end
289
282
 
290
- result = readpartial(8192, @read_buffer, -1)
283
+ result = readpartial(8192, @read_buffer, buffer_pos: -1)
291
284
  return self if !result
292
285
  end
293
286
  rescue EOFError
@@ -306,7 +299,7 @@ class ::IO
306
299
  # @!visibility private
307
300
  LINEFEED = "\n"
308
301
  # @!visibility private
309
- LINEFEED_RE = /\n$/.freeze
302
+ LINEFEED_RE = /\n$/
310
303
 
311
304
  # @!visibility private
312
305
  alias_method :orig_puts, :puts
@@ -351,97 +344,97 @@ class ::IO
351
344
 
352
345
  # @!visibility private
353
346
  def write_nonblock(string, _options = {})
354
- write(string)
355
- end
356
-
357
- # @!visibility private
358
- alias_method :orig_read_nonblock, :read_nonblock
347
+ write(string)
348
+ end
359
349
 
360
- # @!visibility private
361
- def read_nonblock(maxlen, buf = nil, _options = nil)
362
- buf ? readpartial(maxlen, buf) : readpartial(maxlen)
363
- end
350
+ # @!visibility private
351
+ alias_method :orig_read_nonblock, :read_nonblock
364
352
 
365
- # Reads up to `maxlen` bytes at a time in an infinite loop. Read data
366
- # will be passed to the given block.
367
- #
368
- # @param maxlen [Integer] maximum bytes to receive
369
- # @yield [String] read data
370
- # @return [IO] self
371
- def read_loop(maxlen = 8192, &block)
372
- Polyphony.backend_read_loop(self, maxlen, &block)
373
- end
353
+ # @!visibility private
354
+ def read_nonblock(maxlen, buf = nil, _options = nil)
355
+ buf ? readpartial(maxlen, buf) : readpartial(maxlen)
356
+ end
374
357
 
375
- # Receives data from the io in an infinite loop, passing the data to the given
376
- # receiver using the given method. If a block is given, the result of the
377
- # method call to the receiver is passed to the block.
378
- #
379
- # This method can be used to feed data into parser objects. The following
380
- # example shows how to feed data from a io directly into a MessagePack
381
- # unpacker:
382
- #
383
- # unpacker = MessagePack::Unpacker.new
384
- # io.feed_loop(unpacker, :feed_each) { |msg| handle_msg(msg) }
385
- #
386
- # @param receiver [any] receiver object
387
- # @param method [Symbol] method to call
388
- # @return [IO] self
389
- def feed_loop(receiver, method = :call, &block)
390
- Polyphony.backend_feed_loop(self, receiver, method, &block)
391
- end
358
+ # Reads up to `maxlen` bytes at a time in an infinite loop. Read data
359
+ # will be passed to the given block.
360
+ #
361
+ # @param maxlen [Integer] maximum bytes to receive
362
+ # @yield [String] read data
363
+ # @return [IO] self
364
+ def read_loop(maxlen = 8192, &block)
365
+ Polyphony.backend_read_loop(self, maxlen, &block)
366
+ end
392
367
 
393
- # Waits for the IO to become readable, with an optional timeout.
394
- #
395
- # @param timeout [Integer, nil] optional timeout in seconds.
396
- # @return [IO] self
397
- def wait_readable(timeout = nil)
398
- return self if @read_buffer && @read_buffer.size > 0
368
+ # Receives data from the io in an infinite loop, passing the data to the given
369
+ # receiver using the given method. If a block is given, the result of the
370
+ # method call to the receiver is passed to the block.
371
+ #
372
+ # This method can be used to feed data into parser objects. The following
373
+ # example shows how to feed data from a io directly into a MessagePack
374
+ # unpacker:
375
+ #
376
+ # unpacker = MessagePack::Unpacker.new
377
+ # io.feed_loop(unpacker, :feed_each) { |msg| handle_msg(msg) }
378
+ #
379
+ # @param receiver [any] receiver object
380
+ # @param method [Symbol] method to call
381
+ # @return [IO] self
382
+ def feed_loop(receiver, method = :call, &block)
383
+ Polyphony.backend_feed_loop(self, receiver, method, &block)
384
+ end
399
385
 
400
- if timeout
401
- move_on_after(timeout) do
386
+ # Waits for the IO to become readable, with an optional timeout.
387
+ #
388
+ # @param timeout [Integer, nil] optional timeout in seconds.
389
+ # @return [IO] self
390
+ def wait_readable(timeout = nil)
391
+ return self if @read_buffer && !@read_buffer.empty?
392
+
393
+ if timeout
394
+ move_on_after(timeout) do
395
+ Polyphony.backend_wait_io(self, false)
396
+ self
397
+ end
398
+ else
402
399
  Polyphony.backend_wait_io(self, false)
403
400
  self
404
401
  end
405
- else
406
- Polyphony.backend_wait_io(self, false)
407
- self
408
402
  end
409
- end
410
403
 
411
- # Waits for the IO to become writeable, with an optional timeout.
412
- #
413
- # @param timeout [Integer, nil] optional timeout in seconds.
414
- # @return [IO] self
415
- def wait_writable(timeout = nil)
416
- if timeout
417
- move_on_after(timeout) do
404
+ # Waits for the IO to become writeable, with an optional timeout.
405
+ #
406
+ # @param timeout [Integer, nil] optional timeout in seconds.
407
+ # @return [IO] self
408
+ def wait_writable(timeout = nil)
409
+ if timeout
410
+ move_on_after(timeout) do
411
+ Polyphony.backend_wait_io(self, true)
412
+ self
413
+ end
414
+ else
418
415
  Polyphony.backend_wait_io(self, true)
419
416
  self
420
417
  end
421
- else
422
- Polyphony.backend_wait_io(self, true)
423
- self
424
418
  end
425
- end
426
-
427
- # Splices data from the given IO. If maxlen is negative, splices repeatedly
428
- # using absolute value of maxlen until EOF is encountered.
429
- #
430
- # @param src [IO, Polpyhony::Pipe] source to splice from
431
- # @param maxlen [Integer] maximum bytes to splice
432
- # @return [Integer] bytes spliced
433
- def splice_from(src, maxlen)
434
- Polyphony.backend_splice(src, self, maxlen)
435
- end
436
419
 
437
- if RUBY_PLATFORM =~ /linux/
438
- # Tees data from the given IO.
420
+ # Splices data from the given IO. If maxlen is negative, splices repeatedly
421
+ # using absolute value of maxlen until EOF is encountered.
439
422
  #
440
- # @param src [IO, Polpyhony::Pipe] source to tee from
441
- # @param maxlen [Integer] maximum bytes to tee
442
- # @return [Integer] bytes teed
443
- def tee_from(src, maxlen)
444
- Polyphony.backend_tee(src, self, maxlen)
423
+ # @param src [IO, Polpyhony::Pipe] source to splice from
424
+ # @param maxlen [Integer] maximum bytes to splice
425
+ # @return [Integer] bytes spliced
426
+ def splice_from(src, maxlen)
427
+ Polyphony.backend_splice(src, self, maxlen)
428
+ end
429
+
430
+ if RUBY_PLATFORM =~ /linux/
431
+ # Tees data from the given IO.
432
+ #
433
+ # @param src [IO, Polpyhony::Pipe] source to tee from
434
+ # @param maxlen [Integer] maximum bytes to tee
435
+ # @return [Integer] bytes teed
436
+ def tee_from(src, maxlen)
437
+ Polyphony.backend_tee(src, self, maxlen)
438
+ end
445
439
  end
446
- end
447
440
  end
@@ -2,6 +2,27 @@
2
2
 
3
3
  require 'open3'
4
4
 
5
+ module Polyphony
6
+ # Intercepts calls to #trap
7
+ module TrapInterceptor
8
+ def trap(sig, command = nil, &block)
9
+ return super(sig, command) if command.is_a? String
10
+
11
+ block = command if !block && command.respond_to?(:call)
12
+
13
+ # The signal trap can be invoked at any time, including while the system
14
+ # backend is blocking while polling for events. In order to deal with this
15
+ # correctly, we run the signal handler code in an out-of-band, priority
16
+ # scheduled fiber, that will pass any uncaught exception (including
17
+ # SystemExit and Interrupt) to the main thread's main fiber. See also
18
+ # `Fiber#schedule_priority_oob_fiber`.
19
+ super(sig) do
20
+ Fiber.schedule_priority_oob_fiber(&block)
21
+ end
22
+ end
23
+ end
24
+ end
25
+
5
26
  # Kernel extensions (methods available to all objects / call sites)
6
27
  module ::Kernel
7
28
  # @!visibility private
@@ -59,7 +80,7 @@ module ::Kernel
59
80
  strs = args.inject([]) do |m, a|
60
81
  m << a.inspect << "\n"
61
82
  end
62
- STDOUT.write(*strs)
83
+ $stdout.write(*strs)
63
84
  args.size == 1 ? args.first : args
64
85
  end
65
86
 
@@ -72,6 +93,9 @@ module ::Kernel
72
93
  end
73
94
 
74
95
  class << self
96
+ # @!visibility private
97
+ alias_method :orig_trap, :trap
98
+
75
99
  # @!visibility private
76
100
  alias_method :orig_system, :system
77
101
 
@@ -92,23 +116,29 @@ module ::Kernel
92
116
  # @!visibility private
93
117
  alias_method :orig_trap, :trap
94
118
 
95
- # @!visibility private
96
- def trap(sig, command = nil, &block)
97
- return orig_trap(sig, command) if command.is_a? String
98
-
99
- block = command if !block && command.respond_to?(:call)
100
-
101
- # The signal trap can be invoked at any time, including while the system
102
- # backend is blocking while polling for events. In order to deal with this
103
- # correctly, we run the signal handler code in an out-of-band, priority
104
- # scheduled fiber, that will pass any uncaught exception (including
105
- # SystemExit and Interrupt) to the main thread's main fiber. See also
106
- # `Fiber#schedule_priority_oob_fiber`.
107
- orig_trap(sig) do
108
- Fiber.schedule_priority_oob_fiber(&block)
109
- end
119
+ prepend Polyphony::TrapInterceptor
120
+
121
+ class << self
122
+ prepend Polyphony::TrapInterceptor
110
123
  end
111
124
 
125
+ # # @!visibility private
126
+ # def trap(sig, command = nil, &block)
127
+ # return orig_trap(sig, command) if command.is_a? String
128
+
129
+ # block = command if !block && command.respond_to?(:call)
130
+
131
+ # # The signal trap can be invoked at any time, including while the system
132
+ # # backend is blocking while polling for events. In order to deal with this
133
+ # # correctly, we run the signal handler code in an out-of-band, priority
134
+ # # scheduled fiber, that will pass any uncaught exception (including
135
+ # # SystemExit and Interrupt) to the main thread's main fiber. See also
136
+ # # `Fiber#schedule_priority_oob_fiber`.
137
+ # orig_trap(sig) do
138
+ # Fiber.schedule_priority_oob_fiber(&block)
139
+ # end
140
+ # end
141
+
112
142
  private
113
143
 
114
144
  # @!visibility private
@@ -116,3 +146,9 @@ module ::Kernel
116
146
  src.read_loop { |data| dest << data }
117
147
  end
118
148
  end
149
+
150
+ module ::Process
151
+ class << self
152
+ prepend Polyphony::TrapInterceptor
153
+ end
154
+ end
@@ -84,7 +84,7 @@ class ::Object
84
84
  def spin_loop(tag = nil, rate: nil, interval: nil, &block)
85
85
  if rate || interval
86
86
  Fiber.current.spin(tag, caller) do
87
- throttled_loop(rate: rate, interval: interval, &block)
87
+ throttled_loop(rate:, interval:, &block)
88
88
  end
89
89
  else
90
90
  spin_loop_without_throttling(tag, caller, block)
@@ -200,8 +200,11 @@ class ::Object
200
200
  # @param duration [Number, nil] duration
201
201
  # @return [any]
202
202
  def sleep(duration = nil)
203
- duration ?
204
- Polyphony.backend_sleep(duration) : Polyphony.backend_wait_event(true)
203
+ if duration
204
+ Polyphony.backend_sleep(duration)
205
+ else
206
+ Polyphony.backend_wait_event(true)
207
+ end
205
208
  end
206
209
 
207
210
  # Starts a throttled loop with the given rate. If `count:` is given, the
@@ -220,9 +223,7 @@ class ::Object
220
223
  if opts[:count]
221
224
  opts[:count].times { |_i| throttler.(&block) }
222
225
  else
223
- while true
224
- throttler.(&block)
225
- end
226
+ throttler.(&block) while true
226
227
  end
227
228
  rescue LocalJumpError, StopIteration
228
229
  # break called or StopIteration raised
@@ -39,7 +39,7 @@ class ::OpenSSL::SSL::SSLSocket
39
39
 
40
40
  # @!visibility private
41
41
  def fill_rbuff
42
- data = self.sysread(BLOCK_SIZE)
42
+ data = sysread(BLOCK_SIZE)
43
43
  if data
44
44
  @rbuffer << data
45
45
  else
@@ -103,15 +103,13 @@ class ::OpenSSL::SSL::SSLSocket
103
103
  # @param buf [String, nil] buffer to read into
104
104
  # @param buf_pos [Number] buffer position to read into
105
105
  # @return [String] buffer used for reading
106
- def read(maxlen = nil, buf = nil, buf_pos = 0)
107
- return readpartial(maxlen, buf, buf_pos) if buf
106
+ def read(maxlen = nil, buf = nil, buffer_pos: 0)
107
+ return readpartial(maxlen, buf, buffer_pos:) if buf
108
108
 
109
109
  buf = +''
110
110
  return readpartial(maxlen, buf) if maxlen
111
111
 
112
- while true
113
- readpartial(4096, buf, -1)
114
- end
112
+ readpartial(4096, buf, buffer_pos: -1) while true
115
113
  rescue EOFError
116
114
  buf
117
115
  end
@@ -132,7 +130,7 @@ class ::OpenSSL::SSL::SSLSocket
132
130
  # @param buf_pos [Number] buffer position to read into
133
131
  # @param raise_on_eof [bool] whether to raise an exception on `EOF`
134
132
  # @return [String, nil] buffer used for reading or nil on `EOF`
135
- def readpartial(maxlen, buf = +'', buf_pos = 0, raise_on_eof = true)
133
+ def readpartial(maxlen, buf = +'', buffer_pos: 0, raise_on_eof: true)
136
134
  if buf_pos != 0
137
135
  if (result = sysread(maxlen, +''))
138
136
  if buf_pos == -1
@@ -265,7 +263,7 @@ class ::OpenSSL::SSL::SSLServer
265
263
  # @param ignore_errors [boolean] whether to ignore IO and SSL errors
266
264
  # @yield [OpenSSL::SSL::SSLSocket] accepted socket
267
265
  # @return [OpenSSL::SSL::SSLServer] self
268
- def accept_loop(ignore_errors = true)
266
+ def accept_loop(ignore_errors: true)
269
267
  loop do
270
268
  yield accept
271
269
  rescue OpenSSL::SSL::SSLError, SystemCallError => e
@@ -43,10 +43,8 @@ class Polyphony::Pipe
43
43
  # @param buf [String, nil] buffer to read into
44
44
  # @param buf_pos [Integer] buffer position to read into
45
45
  # @return [String] read data
46
- def read(len = nil, buf = nil, buf_pos = 0)
47
- if buf
48
- return Polyphony.backend_read(self, buf, len, true, buf_pos)
49
- end
46
+ def read(len = nil, buf = nil, buffer_pos: 0)
47
+ return Polyphony.backend_read(self, buf, len, true, buffer_pos) if buf
50
48
 
51
49
  @read_buffer ||= +''
52
50
  result = Polyphony.backend_read(self, @read_buffer, len, true, -1)
@@ -64,8 +62,8 @@ class Polyphony::Pipe
64
62
  # @param buf_pos [Integer] buffer position to read into
65
63
  # @param raise_on_eof [boolean] whether to raise an error if EOF is detected
66
64
  # @return [String] read data
67
- def readpartial(len, buf = +'', buf_pos = 0, raise_on_eof = true)
68
- result = Polyphony.backend_read(self, buf, len, false, buf_pos)
65
+ def readpartial(len, buf = +'', buffer_pos: 0, raise_on_eof: true)
66
+ result = Polyphony.backend_read(self, buf, len, false, buffer_pos)
69
67
  raise EOFError if !result && raise_on_eof
70
68
 
71
69
  result
@@ -106,7 +104,7 @@ class Polyphony::Pipe
106
104
  idx = @read_buffer.index(sep)
107
105
  return @read_buffer.slice!(0, idx + sep_size) if idx
108
106
 
109
- result = readpartial(8192, @read_buffer, -1)
107
+ result = readpartial(8192, @read_buffer, buffer_pos: -1)
110
108
  return nil unless result
111
109
  end
112
110
  rescue EOFError
@@ -26,9 +26,8 @@ end
26
26
 
27
27
  # Socket extensions # TODO: rewrite in C
28
28
  class ::Socket < ::BasicSocket
29
-
30
29
  # Accepts an incoming connection.
31
-
30
+ #
32
31
  # @return [TCPSocket] new connection
33
32
  def accept
34
33
  Polyphony.backend_accept(self, TCPSocket)
@@ -73,12 +72,9 @@ class ::Socket < ::BasicSocket
73
72
  # @param buf [String, nil] buffer to read into
74
73
  # @param buf_pos [Number] buffer position to read into
75
74
  # @return [String] buffer used for reading
76
- def read(len = nil, buf = nil, buf_pos = 0)
75
+ def read(len = nil, buf = nil, buffer_pos: 0)
77
76
  return '' if len == 0
78
-
79
- if buf
80
- return Polyphony.backend_read(self, buf, len, true, buf_pos)
81
- end
77
+ return Polyphony.backend_read(self, buf, len, true, buffer_pos) if buf
82
78
 
83
79
  @read_buffer ||= +''
84
80
  result = Polyphony.backend_read(self, @read_buffer, len, true, -1)
@@ -167,8 +163,8 @@ class ::Socket < ::BasicSocket
167
163
  # @param buf_pos [Number] buffer position to read into
168
164
  # @param raise_on_eof [bool] whether to raise an exception on `EOF`
169
165
  # @return [String, nil] buffer used for reading or nil on `EOF`
170
- def readpartial(maxlen, buf = +'', buf_pos = 0, raise_on_eof = true)
171
- result = Polyphony.backend_recv(self, buf, maxlen, buf_pos)
166
+ def readpartial(maxlen, buf = +'', buffer_pos: 0, raise_on_eof: true)
167
+ result = Polyphony.backend_recv(self, buf, maxlen, buffer_pos)
172
168
  raise EOFError if !result && raise_on_eof
173
169
 
174
170
  result
@@ -210,8 +206,8 @@ class ::Socket < ::BasicSocket
210
206
  end
211
207
 
212
208
  class << self
213
- # @!visibility private
214
- alias_method :orig_getaddrinfo, :getaddrinfo
209
+ # @!visibility private
210
+ alias_method :orig_getaddrinfo, :getaddrinfo
215
211
 
216
212
  # Resolves the given addr using a worker thread from the default thread
217
213
  # pool.
@@ -337,12 +333,9 @@ class ::TCPSocket < ::IPSocket
337
333
  # @param buf [String, nil] buffer to read into
338
334
  # @param buf_pos [Number] buffer position to read into
339
335
  # @return [String] buffer used for reading
340
- def read(len = nil, buf = nil, buf_pos = 0)
336
+ def read(len = nil, buf = nil, buffer_pos: 0)
341
337
  return '' if len == 0
342
-
343
- if buf
344
- return Polyphony.backend_read(self, buf, len, true, buf_pos)
345
- end
338
+ return Polyphony.backend_read(self, buf, len, true, buffer_pos) if buf
346
339
 
347
340
  @read_buffer ||= +''
348
341
  result = Polyphony.backend_read(self, @read_buffer, len, true, -1)
@@ -413,9 +406,10 @@ class ::TCPSocket < ::IPSocket
413
406
  # @param buf_pos [Number] buffer position to read into
414
407
  # @param raise_on_eof [bool] whether to raise an exception on `EOF`
415
408
  # @return [String, nil] buffer used for reading or nil on `EOF`
416
- def readpartial(maxlen, buf = +'', buf_pos = 0, raise_on_eof = true)
417
- result = Polyphony.backend_recv(self, buf, maxlen, buf_pos)
409
+ def readpartial(maxlen, buf = +'', buffer_pos: 0, raise_on_eof: true)
410
+ result = Polyphony.backend_recv(self, buf, maxlen, buffer_pos)
418
411
  raise EOFError if !result && raise_on_eof
412
+
419
413
  result
420
414
  end
421
415
 
@@ -430,7 +424,7 @@ class ::TCPSocket < ::IPSocket
430
424
  # @param exception [bool] whether to raise an exception if not ready for reading
431
425
  # @return [String, :wait_readable] read buffer
432
426
  def read_nonblock(maxlen, buf = nil, exception: true)
433
- @io.read_nonblock(maxlen, buf, exception: exception)
427
+ @io.read_nonblock(maxlen, buf, exception:)
434
428
  end
435
429
 
436
430
  # Performs a non-blocking to the socket. If the socket is not ready for
@@ -442,13 +436,12 @@ class ::TCPSocket < ::IPSocket
442
436
  # @param exception [bool] whether to raise an exception if not ready for reading
443
437
  # @return [Integer, :wait_readable] number of bytes written
444
438
  def write_nonblock(buf, exception: true)
445
- @io.write_nonblock(buf, exception: exception)
439
+ @io.write_nonblock(buf, exception:)
446
440
  end
447
441
  end
448
442
 
449
443
  # TCPServer extensions
450
444
  class ::TCPServer < ::TCPSocket
451
-
452
445
  # Initializes the TCP server socket.
453
446
  #
454
447
  # @param hostname [String, nil] hostname to connect to
@@ -546,12 +539,9 @@ class ::UNIXSocket < ::BasicSocket
546
539
  # @param buf [String, nil] buffer to read into
547
540
  # @param buf_pos [Number] buffer position to read into
548
541
  # @return [String] buffer used for reading
549
- def read(len = nil, buf = nil, buf_pos = 0)
542
+ def read(len = nil, buf = nil, buffer_pos: 0)
550
543
  return '' if len == 0
551
-
552
- if buf
553
- return Polyphony.backend_read(self, buf, len, true, buf_pos)
554
- end
544
+ return Polyphony.backend_read(self, buf, len, true, buffer_pos) if buf
555
545
 
556
546
  @read_buffer ||= +''
557
547
  result = Polyphony.backend_read(self, @read_buffer, len, true, -1)
@@ -648,9 +638,10 @@ class ::UNIXSocket < ::BasicSocket
648
638
  # @param buf_pos [Number] buffer position to read into
649
639
  # @param raise_on_eof [bool] whether to raise an exception on `EOF`
650
640
  # @return [String, nil] buffer used for reading or nil on `EOF`
651
- def readpartial(maxlen, buf = +'', buf_pos = 0, raise_on_eof = true)
652
- result = Polyphony.backend_recv(self, buf, maxlen, buf_pos)
641
+ def readpartial(maxlen, buf = +'', buffer_pos: 0, raise_on_eof: true)
642
+ result = Polyphony.backend_recv(self, buf, maxlen, buffer_pos)
653
643
  raise EOFError if !result && raise_on_eof
644
+
654
645
  result
655
646
  end
656
647
 
@@ -665,7 +656,7 @@ class ::UNIXSocket < ::BasicSocket
665
656
  # @param exception [bool] whether to raise an exception if not ready for reading
666
657
  # @return [String, :wait_readable] read buffer
667
658
  def read_nonblock(maxlen, buf = nil, exception: true)
668
- @io.read_nonblock(maxlen, buf, exception: exception)
659
+ @io.read_nonblock(maxlen, buf, exception:)
669
660
  end
670
661
 
671
662
  # Performs a non-blocking to the socket. If the socket is not ready for
@@ -677,7 +668,7 @@ class ::UNIXSocket < ::BasicSocket
677
668
  # @param exception [bool] whether to raise an exception if not ready for reading
678
669
  # @return [Integer, :wait_readable] number of bytes written
679
670
  def write_nonblock(buf, exception: true)
680
- @io.write_nonblock(buf, exception: exception)
671
+ @io.write_nonblock(buf, exception:)
681
672
  end
682
673
  end
683
674
 
@@ -724,13 +715,13 @@ class ::UDPSocket < ::IPSocket
724
715
  # @return [Integer] bytes sent
725
716
  def send(msg, flags, *addr)
726
717
  sockaddr = case addr.size
727
- when 2
728
- Socket.sockaddr_in(addr[1], addr[0])
729
- when 1
730
- addr[0]
731
- else
732
- nil
733
- end
718
+ when 2
719
+ Socket.sockaddr_in(addr[1], addr[0])
720
+ when 1
721
+ addr[0]
722
+ else
723
+ nil
724
+ end
734
725
 
735
726
  Polyphony.backend_sendmsg(self, msg, flags, sockaddr, nil)
736
727
  end
@@ -81,7 +81,6 @@ class ::Thread
81
81
  return self if @terminated
82
82
 
83
83
  raise Polyphony::Terminate
84
- self
85
84
  end
86
85
 
87
86
  # @!visibility private
@@ -160,9 +159,8 @@ class ::Thread
160
159
  #
161
160
  # @param result [any] thread's return value
162
161
  def finalize(result)
163
- unless Fiber.current.children.empty?
164
- Fiber.current.shutdown_all_children
165
- end
162
+ Fiber.current.shutdown_all_children if !Fiber.current.children.empty?
163
+
166
164
  @finalization_mutex.synchronize do
167
165
  @terminated = true
168
166
  @result = result
@@ -4,7 +4,6 @@ require 'timeout'
4
4
 
5
5
  # Timeout extensions
6
6
  module ::Timeout
7
-
8
7
  # Sets a timeout for the given block. This method provides an equivalent API
9
8
  # to the stock Timeout API provided by Ruby. In case of a timeout, the block
10
9
  # will be interrupted and an exception will be raised according to the given
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Polyphony
4
4
  # @!visibility private
5
- VERSION = '1.1'
5
+ VERSION = '1.2'
6
6
  end