quack_concurrency 0.5.3 → 0.5.4
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.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d110c1994e7796f45c3cade0f82f7bae2ce8daa0fa775e32fe92cb5a5d1bb3e7
|
4
|
+
data.tar.gz: 1253c01f31d051a5cdccd599c3d1ce597bc580c9e06311727b132aa4e1f2e172
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c44997c7c973429240bbf600ea68818eedb548012ccc0248028a4fc5a18509e9050b44baa92c563190512c1cb34a0999d8624288827915eb4dcdbc05997961ad
|
7
|
+
data.tar.gz: 99f22237f7a44ea60ac10c0a25c8ac6627fa17cf13de2f55e4797a749607f676dd02ffbfd47ade2f93a983e5ca83dab89e8374480ab930326154e47c14d69c36
|
@@ -61,18 +61,30 @@ module QuackConcurrency
|
|
61
61
|
end
|
62
62
|
@mutex.synchronize { @waiting_threads.push(caller) }
|
63
63
|
if mutex
|
64
|
+
# ideally we would would check if this Thread can sleep (not the last Thread alive)
|
65
|
+
# before we unlock the mutex, however I am not sure is that can be implemented
|
64
66
|
if mutex.respond_to?(:unlock!)
|
65
67
|
mutex.unlock! { sleep(timeout) }
|
66
68
|
else
|
67
69
|
mutex.unlock
|
68
|
-
|
69
|
-
|
70
|
+
begin
|
71
|
+
sleep(timeout)
|
72
|
+
ensure # rescue a fatal error (eg. only Thread stopped)
|
73
|
+
if mutex.locked?
|
74
|
+
# another Thread locked this before it died
|
75
|
+
# this is not a correct state to be in but I don't know how to fix it
|
76
|
+
# given that there are no other alive Threads then than the ramifications should be minimal
|
77
|
+
else
|
78
|
+
mutex.lock
|
79
|
+
end
|
80
|
+
end
|
70
81
|
end
|
71
82
|
else
|
72
83
|
sleep(timeout)
|
73
84
|
end
|
74
|
-
@mutex.synchronize { @waiting_threads.delete(caller) }
|
75
85
|
self
|
86
|
+
ensure
|
87
|
+
@mutex.synchronize { @waiting_threads.delete(caller) }
|
76
88
|
end
|
77
89
|
|
78
90
|
# Returns the number of `Thread`s currently waiting.
|
@@ -35,18 +35,30 @@ module QuackConcurrency
|
|
35
35
|
sleeper = UninterruptibleSleeper.for_current
|
36
36
|
@mutex.synchronize { @waiting_threads_sleepers.push(sleeper) }
|
37
37
|
if mutex
|
38
|
+
# ideally we would would check if this Thread can sleep (not the last Thread alive)
|
39
|
+
# before we unlock the mutex, however I am not sure is that can be implemented
|
38
40
|
if mutex.respond_to?(:unlock!)
|
39
41
|
mutex.unlock! { sleep(sleeper, timeout) }
|
40
42
|
else
|
41
43
|
mutex.unlock
|
42
|
-
|
43
|
-
|
44
|
+
begin
|
45
|
+
sleep(sleeper, timeout)
|
46
|
+
ensure # rescue a fatal error (eg. only Thread stopped)
|
47
|
+
if mutex.locked?
|
48
|
+
# another Thread locked this before it died
|
49
|
+
# this is not a correct state to be in but I don't know how to fix it
|
50
|
+
# given that there are no other alive Threads then than the ramifications should be minimal
|
51
|
+
else
|
52
|
+
mutex.lock
|
53
|
+
end
|
54
|
+
end
|
44
55
|
end
|
45
56
|
else
|
46
57
|
sleep(sleeper, timeout)
|
47
58
|
end
|
48
|
-
@mutex.synchronize { @waiting_threads_sleepers.delete(sleeper) }
|
49
59
|
self
|
60
|
+
ensure
|
61
|
+
@mutex.synchronize { @waiting_threads_sleepers.delete(sleeper) }
|
50
62
|
end
|
51
63
|
|
52
64
|
def waiting_threads_count
|
@@ -54,7 +66,7 @@ module QuackConcurrency
|
|
54
66
|
end
|
55
67
|
|
56
68
|
private
|
57
|
-
|
69
|
+
|
58
70
|
# @api private
|
59
71
|
def signal_next
|
60
72
|
next_waiting_thread_sleeper = @waiting_threads_sleepers.shift
|
@@ -4,6 +4,8 @@ module QuackConcurrency
|
|
4
4
|
# Unlike simply calling `Thread#sleep`, {#stop_thread} will ensure that only
|
5
5
|
# calling {#run_thread} on this {UninterruptibleSleeper} will wake the `Thread`.
|
6
6
|
# Any call to `Thread#run` directly, will be ignored.
|
7
|
+
# `Thread`s can still be resumed if `Thread#raise` is called.
|
8
|
+
# A `ThreadError` will be raised if a the last running `Thread` is stopped.
|
7
9
|
class UninterruptibleSleeper
|
8
10
|
|
9
11
|
def self.for_current
|
@@ -52,13 +54,14 @@ module QuackConcurrency
|
|
52
54
|
time_left = target_end_time - Time.now
|
53
55
|
Kernel.sleep(time_left) if time_left > 0
|
54
56
|
else
|
55
|
-
Thread.stop
|
57
|
+
Thread.stop # may raise ThreadError if this is last running Thread
|
56
58
|
end
|
57
59
|
break if @state == :running || Time.now >= target_time
|
58
60
|
end
|
61
|
+
ensure
|
59
62
|
@state = :running
|
60
63
|
|
61
|
-
# we relock the mutex ensure #run_thread has finshed before #stop_thread
|
64
|
+
# we relock the mutex to ensure #run_thread has finshed before #stop_thread
|
62
65
|
# if Thread#run is called by another part of the code at the same time as
|
63
66
|
# #run_thread is being called, we dont want the call to #run_thread
|
64
67
|
# to call Thread#run on a Thread has already resumed and stopped again
|