Skip to content

Commit b71cf5c

Browse files
committed
Avoid a deadlock when running MT
This fix may be better as a reentrant mutex that is conditionally applied only to mt_preview compiled code, but I like the fact that spinlocks become no-ops unless running multithreaded, and they are very simple. Also bump the version for a new release, and made a couple code cleanliness tweaks.
1 parent a4cf961 commit b71cf5c

File tree

3 files changed

+9
-8
lines changed

3 files changed

+9
-8
lines changed

VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.0.0
1+
1.0.1

shard.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: csuuid
2-
version: 1.0.0
2+
version: 1.0.1
33

44
authors:
55
- Kirk Haines <[email protected]>
@@ -18,4 +18,4 @@ dependencies:
1818
development_dependencies:
1919
ameba:
2020
github: crystal-ameba/ameba
21-
version: ~> 1.5
21+
version: ~> 1.6

src/csuuid.cr

+6-5
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ struct CSUUID
5858
# It defaults to `Random::ISAAC`.
5959
class_property prng : Random = Random::ISAAC.new
6060
@@mutex = Crystal::SpinLock.new
61+
@@isaac_mutex = Crystal::SpinLock.new
6162
@@unique_identifier : Slice(UInt8) = Slice(UInt8).new(6, 0)
6263
@@unique_seconds_and_nanoseconds : Tuple(Int64, Int32) = {0_i64, 0_i32}
6364

@@ -153,11 +154,11 @@ struct CSUUID
153154

154155
IO::ByteFormat::BigEndian.encode(seconds, @bytes[2, 8])
155156
IO::ByteFormat::BigEndian.encode(nanoseconds, @bytes[0, 4])
156-
@@mutex.sync do
157+
@@isaac_mutex.sync do
157158
# Random::ISAAC.random_bytes doesn't appear to be threadsafe.
158159
# It sometimes dies ugly in multithreaded code, so we need a
159160
# lock in this one tiny little space to avoid that.
160-
# TODO: Check if this is still the case post Crystal 1.4.0,
161+
# Check if this is still the case post Crystal 1.4.0,
161162
# and if it is, fix Crypt::ISAAC and send in a PR.
162163
@bytes[10, 6].copy_from(id || CSUUID.prng.random_bytes(6))
163164
end
@@ -201,16 +202,16 @@ struct CSUUID
201202

202203
# Compare two CSUUID objects, returning -1 if the first is less than the second,
203204
# 0 if they are equal, and 1 if the first is greater than the second.
204-
def <=>(val : CSUUID)
205+
def <=>(other : CSUUID)
205206
s, ns = seconds_and_nanoseconds
206-
s_val, ns_val = val.seconds_and_nanoseconds
207+
s_val, ns_val = other.seconds_and_nanoseconds
207208
r = s <=> s_val
208209
return r unless r == 0
209210

210211
r = ns <=> ns_val
211212
return r unless r == 0
212213

213-
to_s <=> val.to_s
214+
to_s <=> other.to_s
214215
end
215216

216217
# Returns `true` if `self` is less than *other*.

0 commit comments

Comments
 (0)