polyphony 1.1.1 → 1.2

Sign up to get free protection for your applications and to get access to all the features.
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 +9 -0
  6. data/README.md +2 -1
  7. data/docs/advanced-io.md +9 -1
  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 +1 -1
  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 +5 -3
@@ -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.1'
5
+ VERSION = '1.2'
6
6
  end