polyphony 0.81.1 → 0.84

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +1 -1
  3. data/.gitmodules +3 -0
  4. data/CHANGELOG.md +17 -0
  5. data/Gemfile.lock +1 -1
  6. data/Rakefile +14 -0
  7. data/bin/test +1 -1
  8. data/ext/polyphony/backend_common.c +33 -10
  9. data/ext/polyphony/backend_common.h +20 -2
  10. data/ext/polyphony/backend_io_uring.c +182 -220
  11. data/ext/polyphony/backend_libev.c +212 -197
  12. data/ext/polyphony/extconf.rb +21 -2
  13. data/ext/polyphony/io_extensions.c +440 -0
  14. data/ext/polyphony/pipe.c +109 -0
  15. data/ext/polyphony/polyphony.c +50 -1
  16. data/ext/polyphony/polyphony.h +6 -11
  17. data/ext/polyphony/polyphony_ext.c +7 -2
  18. data/ext/polyphony/zlib_conf.rb +119 -0
  19. data/lib/polyphony/extensions/io.rb +20 -2
  20. data/lib/polyphony/extensions/pipe.rb +171 -0
  21. data/lib/polyphony/extensions.rb +1 -0
  22. data/lib/polyphony/version.rb +1 -1
  23. data/lib/polyphony.rb +4 -0
  24. data/test/helper.rb +4 -0
  25. data/test/test_backend.rb +3 -48
  26. data/test/test_global_api.rb +23 -23
  27. data/test/test_io.rb +426 -0
  28. data/test/test_pipe.rb +41 -0
  29. data/test/test_process_supervision.rb +1 -1
  30. data/test/test_raw_buffer.rb +37 -0
  31. data/test/test_socket.rb +50 -0
  32. metadata +8 -13
  33. data/ext/liburing/liburing/README.md +0 -4
  34. data/ext/liburing/liburing/barrier.h +0 -73
  35. data/ext/liburing/liburing/compat.h +0 -15
  36. data/ext/liburing/liburing/io_uring.h +0 -343
  37. data/ext/liburing/liburing.h +0 -585
  38. data/ext/liburing/queue.c +0 -333
  39. data/ext/liburing/register.c +0 -187
  40. data/ext/liburing/setup.c +0 -210
  41. data/ext/liburing/syscall.c +0 -54
  42. data/ext/liburing/syscall.h +0 -18
  43. data/ext/polyphony/liburing.c +0 -8
@@ -36,6 +36,7 @@
36
36
  #define BACKEND() (rb_ivar_get(rb_thread_current(), ID_ivar_backend))
37
37
 
38
38
  extern VALUE mPolyphony;
39
+ extern VALUE cPipe;
39
40
  extern VALUE cQueue;
40
41
  extern VALUE cEvent;
41
42
  extern VALUE cTimeoutException;
@@ -87,6 +88,9 @@ long Runqueue_len(VALUE self);
87
88
  int Runqueue_empty_p(VALUE self);
88
89
  int Runqueue_should_poll_nonblocking(VALUE self);
89
90
 
91
+ void Pipe_verify_blocking_mode(VALUE self, VALUE blocking);
92
+ int Pipe_get_fd(VALUE self, int write_mode);
93
+
90
94
  #ifdef POLYPHONY_BACKEND_LIBEV
91
95
  #define Backend_recv_loop Backend_read_loop
92
96
  #define Backend_recv_feed_loop Backend_feed_loop
@@ -108,11 +112,13 @@ VALUE Backend_sendv(VALUE self, VALUE io, VALUE ary, VALUE flags);
108
112
  VALUE Backend_sleep(VALUE self, VALUE duration);
109
113
  VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen);
110
114
  VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE chunksize);
115
+ VALUE Backend_tee(VALUE self, VALUE src, VALUE dest, VALUE maxlen);
111
116
  VALUE Backend_timeout(int argc,VALUE *argv, VALUE self);
112
117
  VALUE Backend_timer_loop(VALUE self, VALUE interval);
113
118
  VALUE Backend_wait_event(VALUE self, VALUE raise);
114
119
  VALUE Backend_wait_io(VALUE self, VALUE io, VALUE write);
115
120
  VALUE Backend_waitpid(VALUE self, VALUE pid);
121
+ VALUE Backend_write(VALUE self, VALUE io, VALUE str);
116
122
  VALUE Backend_write_m(int argc, VALUE *argv, VALUE self);
117
123
  // VALUE Backend_close(VALUE self, VALUE io);
118
124
 
@@ -135,15 +141,4 @@ VALUE Thread_switch_fiber(VALUE thread);
135
141
 
136
142
  VALUE Polyphony_snooze(VALUE self);
137
143
 
138
- struct raw_buffer {
139
- char *base;
140
- int size;
141
- };
142
-
143
- struct io_buffer {
144
- char *base;
145
- int size;
146
- int raw;
147
- };
148
-
149
144
  #endif /* POLYPHONY_H */
@@ -1,13 +1,16 @@
1
1
  #include "polyphony.h"
2
2
 
3
- void Init_Fiber();
4
3
  void Init_Polyphony();
5
4
  void Init_Backend();
5
+ void Init_Pipe();
6
6
  void Init_Queue();
7
7
  void Init_Event();
8
- void Init_SocketExtensions();
8
+ void Init_Fiber();
9
9
  void Init_Thread();
10
10
 
11
+ void Init_IOExtensions();
12
+ void Init_SocketExtensions();
13
+
11
14
  #ifdef POLYPHONY_PLAYGROUND
12
15
  extern void playground();
13
16
  #endif
@@ -17,10 +20,12 @@ void Init_polyphony_ext() {
17
20
 
18
21
  Init_Backend();
19
22
  Init_Queue();
23
+ Init_Pipe();
20
24
  Init_Event();
21
25
  Init_Fiber();
22
26
  Init_Thread();
23
27
 
28
+ Init_IOExtensions();
24
29
  Init_SocketExtensions();
25
30
 
26
31
  #ifdef POLYPHONY_PLAYGROUND
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ libs = $libs
4
+ if %w'z libz zlib1 zlib zdll zlibwapi'.find {|z| have_library(z, 'deflateReset')} and
5
+ have_header('zlib.h') then
6
+ have_zlib = true
7
+ else
8
+ $libs = libs
9
+ unless File.directory?(zsrc = "#{$srcdir}/zlib")
10
+ dirs = Dir.open($srcdir) {|z| z.grep(/\Azlib-\d+[.\d]*\z/) {|x|"#{$srcdir}/#{x}"}}
11
+ dirs.delete_if {|x| !File.directory?(x)}
12
+ zsrc = dirs.max_by {|x| x.scan(/\d+/).map(&:to_i)}
13
+ end
14
+ if zsrc
15
+ addconf = [
16
+ "ZSRC = $(srcdir)/#{File.basename(zsrc)}\n",
17
+ "all:\n",
18
+ ]
19
+ $INCFLAGS << " -I$(ZSRC)"
20
+ if $mswin or $mingw
21
+ dll = "zlib1.dll"
22
+ $extso << dll
23
+ $cleanfiles << "$(topdir)/#{dll}" << "$(ZIMPLIB)"
24
+ zmk = "\t$(MAKE) -f $(ZMKFILE) TOP=$(ZSRC)"
25
+ zopts = []
26
+ if $nmake
27
+ zmkfile = "$(ZSRC)/win32/Makefile.msc"
28
+ m = "#{zsrc}/win32/Makefile.msc"
29
+ # zopts << "USE_ASM=1"
30
+ zopts << "ARCH=#{RbConfig::CONFIG['target_cpu']}"
31
+ else
32
+ zmkfile = "$(ZSRC)/win32/Makefile.gcc"
33
+ m = "#{zsrc}/win32/Makefile.gcc"
34
+ zmk += " PREFIX="
35
+ zmk << CONFIG['CC'][/(.*-)gcc([^\/]*)\z/, 1]
36
+ zmk << " CC=$(CC)" if $2
37
+ end
38
+ m = File.read(m)
39
+ zimplib = m[/^IMPLIB[ \t]*=[ \t]*(\S+)/, 1]
40
+ ($LOCAL_LIBS << " ./" << zimplib).strip!
41
+ unless $nmake or /^TOP[ \t]/ =~ m
42
+ m.gsub!(/win32\/zlib\.def/, '$(TOP)/\&')
43
+ m.gsub!(/^(\t.*[ \t])(\S+\.rc)/, '\1-I$(<D) $<')
44
+ m = "TOP = .\n""VPATH=$(TOP)\n" + m
45
+ zmkfile = File.basename(zmkfile)
46
+ File.rename(zmkfile, zmkfile+".orig") if File.exist?(zmkfile)
47
+ File.write(zmkfile, m)
48
+ end
49
+ addconf.push(
50
+ "ZMKFILE = #{zmkfile}\n",
51
+ "ZIMPLIB = #{zimplib}\n",
52
+ "ZOPTS = #{zopts.join(' ')}\n",
53
+ "$(TARGET_SO): $(ZIMPLIB)\n",
54
+ "$(ZIMPLIB):\n",
55
+ "#{zmk} $(ZOPTS) $@\n",
56
+ "install-so static: $(topdir)/#{dll}",
57
+ "$(topdir)/#{dll}: $(ZIMPLIB)\n",
58
+ "\t$(Q) $(COPY) #{dll} $(@D)\n",
59
+ "clean: clean-zsrc\n",
60
+ "clean-zsrc:\n",
61
+ "#{zmk} clean\n",
62
+ )
63
+ end
64
+ Logging.message "using zlib in #{zsrc}\n"
65
+ $defs << "-DHAVE_ZLIB_H"
66
+ have_zlib = true
67
+ end
68
+ end
69
+
70
+ if have_zlib
71
+ defines = []
72
+
73
+ Logging::message 'checking for kind of operating system... '
74
+ os_code = with_config('os-code') ||
75
+ case RUBY_PLATFORM.split('-',2)[1]
76
+ when 'amigaos' then
77
+ os_code = 'AMIGA'
78
+ when /mswin|mingw|bccwin/ then
79
+ # NOTE: cygwin should be regarded as Unix.
80
+ os_code = 'WIN32'
81
+ else
82
+ os_code = 'UNIX'
83
+ end
84
+ os_code = 'OS_' + os_code.upcase
85
+
86
+ OS_NAMES = {
87
+ 'OS_MSDOS' => 'MS-DOS',
88
+ 'OS_AMIGA' => 'Amiga',
89
+ 'OS_VMS' => 'VMS',
90
+ 'OS_UNIX' => 'Unix',
91
+ 'OS_ATARI' => 'Atari',
92
+ 'OS_MACOS' => 'MacOS',
93
+ 'OS_TOPS20' => 'TOPS20',
94
+ 'OS_WIN32' => 'Win32',
95
+ 'OS_VMCMS' => 'VM/CMS',
96
+ 'OS_ZSYSTEM' => 'Z-System',
97
+ 'OS_CPM' => 'CP/M',
98
+ 'OS_QDOS' => 'QDOS',
99
+ 'OS_RISCOS' => 'RISCOS',
100
+ 'OS_UNKNOWN' => 'Unknown',
101
+ }
102
+ unless OS_NAMES.key? os_code then
103
+ raise "invalid OS_CODE `#{os_code}'"
104
+ end
105
+ Logging::message "#{OS_NAMES[os_code]}\n"
106
+ defines << "OS_CODE=#{os_code}"
107
+
108
+ $defs.concat(defines.collect{|d|' -D'+d})
109
+
110
+ if zsrc
111
+ $defs << "-DHAVE_CRC32_COMBINE"
112
+ $defs << "-DHAVE_ADLER32_COMBINE"
113
+ $defs << "-DHAVE_TYPE_Z_CRC_T"
114
+ else
115
+ have_func('crc32_combine', 'zlib.h')
116
+ have_func('adler32_combine', 'zlib.h')
117
+ have_type('z_crc_t', 'zlib.h')
118
+ end
119
+ end
@@ -73,6 +73,20 @@ class ::IO
73
73
 
74
74
  Open3.popen2(cmd) { |_i, o, _t| yield o }
75
75
  end
76
+
77
+ def splice(src, dest, maxlen)
78
+ Polyphony.backend_splice(src, dest, maxlen)
79
+ end
80
+
81
+ def splice_to_eof(src, dest, chunk_size = 8192)
82
+ Polyphony.backend_splice_to_eof(src, dest, chunk_size)
83
+ end
84
+
85
+ if RUBY_PLATFORM =~ /linux/
86
+ def tee(src, dest, maxlen)
87
+ Polyphony.backend_tee(src, dest, maxlen)
88
+ end
89
+ end
76
90
  end
77
91
  end
78
92
 
@@ -257,11 +271,15 @@ class ::IO
257
271
  end
258
272
  end
259
273
 
260
- def splice(src, maxlen)
274
+ def splice_from(src, maxlen)
261
275
  Polyphony.backend_splice(src, self, maxlen)
262
276
  end
263
277
 
264
- def splice_to_eof(src, chunksize = 8192)
278
+ def splice_to_eof_from(src, chunksize = 8192)
265
279
  Polyphony.backend_splice_to_eof(src, self, chunksize)
266
280
  end
281
+
282
+ def tee_from(src, maxlen)
283
+ Polyphony.backend_tee(src, self, maxlen)
284
+ end
267
285
  end
@@ -0,0 +1,171 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Pipe instance methods
4
+ class Polyphony::Pipe
5
+ def __read_method__
6
+ :backend_read
7
+ end
8
+
9
+ def getbyte
10
+ char = getc
11
+ char ? char.getbyte(0) : nil
12
+ end
13
+
14
+ def getc
15
+ return @read_buffer.slice!(0) if @read_buffer && !@read_buffer.empty?
16
+
17
+ @read_buffer ||= +''
18
+ Polyphony.backend_read(self, @read_buffer, 8192, false, -1)
19
+ return @read_buffer.slice!(0) if !@read_buffer.empty?
20
+
21
+ nil
22
+ end
23
+
24
+ def read(len = nil, buf = nil, buf_pos = 0)
25
+ if buf
26
+ return Polyphony.backend_read(self, buf, len, true, buf_pos)
27
+ end
28
+
29
+ @read_buffer ||= +''
30
+ result = Polyphony.backend_read(self, @read_buffer, len, true, -1)
31
+ return nil unless result
32
+
33
+ already_read = @read_buffer
34
+ @read_buffer = +''
35
+ already_read
36
+ end
37
+
38
+ def readpartial(len, str = +'', buffer_pos = 0, raise_on_eof = true)
39
+ result = Polyphony.backend_read(self, str, len, false, buffer_pos)
40
+ raise EOFError if !result && raise_on_eof
41
+
42
+ result
43
+ end
44
+
45
+ def write(str, *args)
46
+ Polyphony.backend_write(self, str, *args)
47
+ end
48
+
49
+ def <<(str)
50
+ Polyphony.backend_write(self, str)
51
+ self
52
+ end
53
+
54
+ def gets(sep = $/, _limit = nil, _chomp: nil)
55
+ if sep.is_a?(Integer)
56
+ sep = $/
57
+ _limit = sep
58
+ end
59
+ sep_size = sep.bytesize
60
+
61
+ @read_buffer ||= +''
62
+
63
+ while true
64
+ idx = @read_buffer.index(sep)
65
+ return @read_buffer.slice!(0, idx + sep_size) if idx
66
+
67
+ result = readpartial(8192, @read_buffer, -1)
68
+ return nil unless result
69
+ end
70
+ rescue EOFError
71
+ return nil
72
+ end
73
+
74
+ # def print(*args)
75
+ # end
76
+
77
+ # def printf(format, *args)
78
+ # end
79
+
80
+ # def putc(obj)
81
+ # end
82
+
83
+ LINEFEED = "\n"
84
+ LINEFEED_RE = /\n$/.freeze
85
+
86
+ def puts(*args)
87
+ if args.empty?
88
+ write LINEFEED
89
+ return
90
+ end
91
+
92
+ idx = 0
93
+ while idx < args.size
94
+ arg = args[idx]
95
+ args[idx] = arg = arg.to_s unless arg.is_a?(String)
96
+ if arg =~ LINEFEED_RE
97
+ idx += 1
98
+ else
99
+ args.insert(idx + 1, LINEFEED)
100
+ idx += 2
101
+ end
102
+ end
103
+
104
+ write(*args)
105
+ nil
106
+ end
107
+
108
+ # def readbyte
109
+ # end
110
+
111
+ # def readchar
112
+ # end
113
+
114
+ # def readline(sep = $/, limit = nil, chomp: nil)
115
+ # end
116
+
117
+ # def readlines(sep = $/, limit = nil, chomp: nil)
118
+ # end
119
+
120
+ def write_nonblock(string, _options = {})
121
+ write(string)
122
+ end
123
+
124
+ def read_nonblock(maxlen, buf = nil, _options = nil)
125
+ buf ? readpartial(maxlen, buf) : readpartial(maxlen)
126
+ end
127
+
128
+ def read_loop(maxlen = 8192, &block)
129
+ Polyphony.backend_read_loop(self, maxlen, &block)
130
+ end
131
+
132
+ def feed_loop(receiver, method = :call, &block)
133
+ Polyphony.backend_feed_loop(self, receiver, method, &block)
134
+ end
135
+
136
+ def wait_readable(timeout = nil)
137
+ if timeout
138
+ move_on_after(timeout) do
139
+ Polyphony.backend_wait_io(self, false)
140
+ self
141
+ end
142
+ else
143
+ Polyphony.backend_wait_io(self, false)
144
+ self
145
+ end
146
+ end
147
+
148
+ def wait_writable(timeout = nil)
149
+ if timeout
150
+ move_on_after(timeout) do
151
+ Polyphony.backend_wait_io(self, true)
152
+ self
153
+ end
154
+ else
155
+ Polyphony.backend_wait_io(self, true)
156
+ self
157
+ end
158
+ end
159
+
160
+ def splice_from(src, maxlen)
161
+ Polyphony.backend_splice(src, self, maxlen)
162
+ end
163
+
164
+ def splice_to_eof_from(src, chunksize = 8192)
165
+ Polyphony.backend_splice_to_eof(src, self, chunksize)
166
+ end
167
+
168
+ def tee_from(src, maxlen)
169
+ Polyphony.backend_tee(src, self, maxlen)
170
+ end
171
+ end
@@ -3,6 +3,7 @@
3
3
  require_relative './extensions/exception'
4
4
  require_relative './extensions/fiber'
5
5
  require_relative './extensions/io'
6
+ require_relative './extensions/pipe'
6
7
  require_relative './extensions/object'
7
8
  require_relative './extensions/kernel'
8
9
  require_relative './extensions/process'
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Polyphony
4
- VERSION = '0.81.1'
4
+ VERSION = '0.84'
5
5
  end
data/lib/polyphony.rb CHANGED
@@ -18,6 +18,10 @@ require_relative './polyphony/adapters/process'
18
18
  # Polyphony API
19
19
  module Polyphony
20
20
  class << self
21
+ def pipe
22
+ Pipe.new
23
+ end
24
+
21
25
  def fork(&block)
22
26
  Kernel.fork do
23
27
  # A race condition can arise if a TERM or INT signal is received before
data/test/helper.rb CHANGED
@@ -37,6 +37,10 @@ module ::Kernel
37
37
  format("%p\n", args.size == 1 ? args.first : args)
38
38
  end
39
39
  end
40
+
41
+ def monotonic_clock
42
+ ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
43
+ end
40
44
  end
41
45
 
42
46
  class MiniTest::Test
data/test/test_backend.rb CHANGED
@@ -17,7 +17,7 @@ class BackendTest < MiniTest::Test
17
17
 
18
18
  def test_sleep
19
19
  count = 0
20
- t0 = Time.now
20
+ t0 = monotonic_clock
21
21
  spin {
22
22
  @backend.sleep 0.01
23
23
  count += 1
@@ -26,7 +26,7 @@ class BackendTest < MiniTest::Test
26
26
  @backend.sleep 0.01
27
27
  count += 1
28
28
  }.await
29
- assert_in_range 0.02..0.06, Time.now - t0 if IS_LINUX
29
+ assert_in_range 0.02..0.06, monotonic_clock - t0 if IS_LINUX
30
30
  assert_equal 3, count
31
31
  end
32
32
 
@@ -309,51 +309,6 @@ class BackendTest < MiniTest::Test
309
309
  assert_equal [1], buffer
310
310
  end
311
311
 
312
- def test_splice
313
- i1, o1 = IO.pipe
314
- i2, o2 = IO.pipe
315
- len = nil
316
-
317
- spin {
318
- len = o2.splice(i1, 1000)
319
- o2.close
320
- }
321
-
322
- o1.write('foobar')
323
- result = i2.read
324
-
325
- assert_equal 'foobar', result
326
- assert_equal 6, len
327
- end
328
-
329
- def test_splice_to_eof
330
- i1, o1 = IO.pipe
331
- i2, o2 = IO.pipe
332
- len = nil
333
-
334
- f = spin {
335
- len = o2.splice_to_eof(i1, 1000)
336
- o2.close
337
- }
338
-
339
- o1.write('foo')
340
- result = i2.readpartial(1000)
341
- assert_equal 'foo', result
342
-
343
- o1.write('bar')
344
- result = i2.readpartial(1000)
345
- assert_equal 'bar', result
346
- o1.close
347
- f.await
348
- assert_equal 6, len
349
- ensure
350
- if f.alive?
351
- f.interrupt
352
- f.await
353
- end
354
- end
355
-
356
-
357
312
  def test_splice_chunks
358
313
  body = 'abcd' * 4
359
314
  chunk_size = 12
@@ -512,7 +467,7 @@ class BackendChainTest < MiniTest::Test
512
467
  i, o = IO.pipe
513
468
  backend = Thread.current.backend
514
469
  while true
515
- len = o.splice(from, 8192)
470
+ len = o.splice_from(from, 8192)
516
471
  break if len == 0
517
472
 
518
473
  backend.chain(
@@ -103,38 +103,38 @@ end
103
103
 
104
104
  class MoveOnAfterTest < MiniTest::Test
105
105
  def test_move_on_after
106
- t0 = Time.now
106
+ t0 = monotonic_clock
107
107
  v = move_on_after(0.01) do
108
108
  sleep 1
109
109
  :foo
110
110
  end
111
- t1 = Time.now
111
+ t1 = monotonic_clock
112
112
 
113
113
  assert t1 - t0 < 0.1
114
114
  assert_nil v
115
115
  end
116
116
 
117
117
  def test_move_on_after_with_value
118
- t0 = Time.now
118
+ t0 = monotonic_clock
119
119
  v = move_on_after(0.01, with_value: :bar) do
120
120
  sleep 1
121
121
  :foo
122
122
  end
123
- t1 = Time.now
123
+ t1 = monotonic_clock
124
124
 
125
125
  assert t1 - t0 < 0.1
126
126
  assert_equal :bar, v
127
127
  end
128
128
 
129
129
  def test_move_on_after_with_reset
130
- t0 = Time.now
130
+ t0 = monotonic_clock
131
131
  v = move_on_after(0.01, with_value: :moved_on) do |timeout|
132
132
  sleep 0.007
133
133
  timeout.reset
134
134
  sleep 0.007
135
135
  nil
136
136
  end
137
- t1 = Time.now
137
+ t1 = monotonic_clock
138
138
 
139
139
  assert_nil v
140
140
  assert_in_range 0.014..0.02, t1 - t0 if IS_LINUX
@@ -143,23 +143,23 @@ class MoveOnAfterTest < MiniTest::Test
143
143
  def test_nested_move_on_after
144
144
  skip unless IS_LINUX
145
145
 
146
- t0 = Time.now
146
+ t0 = monotonic_clock
147
147
  o = move_on_after(0.01, with_value: 1) do
148
148
  move_on_after(0.02, with_value: 2) do
149
149
  sleep 1
150
150
  end
151
151
  end
152
- t1 = Time.now
152
+ t1 = monotonic_clock
153
153
  assert_equal 1, o
154
154
  assert_in_range 0.008..0.015, t1 - t0 if IS_LINUX
155
155
 
156
- t0 = Time.now
156
+ t0 = monotonic_clock
157
157
  o = move_on_after(0.05, with_value: 1) do
158
158
  move_on_after(0.01, with_value: 2) do
159
159
  sleep 1
160
160
  end
161
161
  end
162
- t1 = Time.now
162
+ t1 = monotonic_clock
163
163
  assert_equal 2, o
164
164
  assert_in_range 0.008..0.013, t1 - t0 if IS_LINUX
165
165
  end
@@ -167,7 +167,7 @@ end
167
167
 
168
168
  class CancelAfterTest < MiniTest::Test
169
169
  def test_cancel_after
170
- t0 = Time.now
170
+ t0 = monotonic_clock
171
171
 
172
172
  assert_raises Polyphony::Cancel do
173
173
  cancel_after(0.01) do
@@ -175,12 +175,12 @@ class CancelAfterTest < MiniTest::Test
175
175
  :foo
176
176
  end
177
177
  end
178
- t1 = Time.now
178
+ t1 = monotonic_clock
179
179
  assert t1 - t0 < 0.1
180
180
  end
181
181
 
182
182
  def test_cancel_after_with_reset
183
- t0 = Time.now
183
+ t0 = monotonic_clock
184
184
  cancel_after(0.01) do |f|
185
185
  assert_kind_of Fiber, f
186
186
  assert_equal Fiber.current, f.parent
@@ -188,7 +188,7 @@ class CancelAfterTest < MiniTest::Test
188
188
  f.reset
189
189
  sleep 0.007
190
190
  end
191
- t1 = Time.now
191
+ t1 = monotonic_clock
192
192
  assert_in_range 0.014..0.024, t1 - t0 if IS_LINUX
193
193
  end
194
194
 
@@ -270,7 +270,7 @@ class SpinLoopTest < MiniTest::Test
270
270
  def test_spin_loop_with_rate
271
271
  buffer = []
272
272
  counter = 0
273
- t0 = Time.now
273
+ t0 = monotonic_clock
274
274
  f = spin_loop(rate: 100) { buffer << (counter += 1) }
275
275
  sleep 0.02
276
276
  f.stop
@@ -280,7 +280,7 @@ class SpinLoopTest < MiniTest::Test
280
280
  def test_spin_loop_with_interval
281
281
  buffer = []
282
282
  counter = 0
283
- t0 = Time.now
283
+ t0 = monotonic_clock
284
284
  f = spin_loop(interval: 0.01) { buffer << (counter += 1) }
285
285
  sleep 0.02
286
286
  f.stop
@@ -361,7 +361,7 @@ class ThrottledLoopTest < MiniTest::Test
361
361
  def test_throttled_loop
362
362
  buffer = []
363
363
  counter = 0
364
- t0 = Time.now
364
+ t0 = monotonic_clock
365
365
  f = spin do
366
366
  throttled_loop(10) { buffer << (counter += 1) }
367
367
  end
@@ -372,12 +372,12 @@ class ThrottledLoopTest < MiniTest::Test
372
372
  def test_throttled_loop_with_count
373
373
  buffer = []
374
374
  counter = 0
375
- t0 = Time.now
375
+ t0 = monotonic_clock
376
376
  f = spin do
377
377
  throttled_loop(50, count: 5) { buffer << (counter += 1) }
378
378
  end
379
379
  f.await
380
- t1 = Time.now
380
+ t1 = monotonic_clock
381
381
  assert_in_range 0.075..0.15, t1 - t0 if IS_LINUX
382
382
  assert_equal [1, 2, 3, 4, 5], buffer
383
383
  end
@@ -395,7 +395,7 @@ class GlobalAPIEtcTest < MiniTest::Test
395
395
 
396
396
  def test_every
397
397
  buffer = []
398
- t0 = Time.now
398
+ t0 = monotonic_clock
399
399
  f = spin do
400
400
  every(0.01) { buffer << 1 }
401
401
  end
@@ -406,7 +406,7 @@ class GlobalAPIEtcTest < MiniTest::Test
406
406
 
407
407
  def test_every_with_slow_op
408
408
  buffer = []
409
- t0 = Time.now
409
+ t0 = monotonic_clock
410
410
  f = spin do
411
411
  every(0.01) { sleep 0.05; buffer << 1 }
412
412
  end
@@ -416,9 +416,9 @@ class GlobalAPIEtcTest < MiniTest::Test
416
416
  end
417
417
 
418
418
  def test_sleep
419
- t0 = Time.now
419
+ t0 = monotonic_clock
420
420
  sleep 0.1
421
- elapsed = Time.now - t0
421
+ elapsed = monotonic_clock - t0
422
422
  assert_in_range 0.05..0.15, elapsed if IS_LINUX
423
423
 
424
424
  f = spin { sleep }