Skip to content

Commit 3a111a2

Browse files
Protect against missing guard in check_return.
1 parent 910bee0 commit 3a111a2

File tree

2 files changed

+18
-6
lines changed

2 files changed

+18
-6
lines changed

lib/async/safe/monitor.rb

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ module Safe
1616
# Uses TracePoint to track in-flight method calls and detect concurrent access.
1717
class Monitor
1818
ASYNC_SAFE = true
19+
20+
IS_A = Kernel.instance_method(:is_a?)
21+
FROZEN = Kernel.instance_method(:frozen?)
22+
CLASS = Kernel.instance_method(:class)
1923

2024
# Initialize a new concurrency monitor.
2125
def initialize
@@ -66,15 +70,15 @@ def transfer(*objects)
6670
object = trace_point.self
6771

6872
# Skip tracking class/module methods:
69-
return if object.is_a?(Module)
73+
return if IS_A.bind_call(object, Module)
7074

7175
# Skip frozen objects:
72-
return if object.frozen?
76+
return if FROZEN.bind_call(object)
7377

7478
method = trace_point.method_id
7579

7680
# Check the object's actual class:
77-
klass = object.class
81+
klass = CLASS.bind_call(object)
7882

7983
# Check if the class or method is marked as async-safe:
8084
# Returns: true (skip), false (simple tracking), or Symbol (guard-based tracking)
@@ -140,15 +144,15 @@ def transfer(*objects)
140144
object = trace_point.self
141145

142146
# Skip tracking class/module methods:
143-
return if object.is_a?(Module)
147+
return if IS_A.bind_call(object, Module)
144148

145149
# Skip frozen objects:
146-
return if object.frozen?
150+
return if FROZEN.bind_call(object)
147151

148152
method = trace_point.method_id
149153

150154
# Check the object's actual class:
151-
klass = object.class
155+
klass = CLASS.bind_call(object)
152156

153157
# Check if the class or method is marked as async-safe:
154158
safe = klass.async_safe?(method)
@@ -159,6 +163,9 @@ def transfer(*objects)
159163
@mutex.synchronize do
160164
entry = @guards[object]
161165

166+
# No guard held, nothing to release:
167+
return unless entry
168+
162169
if safe == false
163170
# Simple tracking (single guard)
164171
# Release if this fiber holds it

releases.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Releases
22

3+
## Unreleased
4+
5+
- Protect against missing guard in `check_return`.
6+
- Use `Kernel` instance methods to handle broken proxy objects directly.
7+
38
## v0.5.0
49

510
- More conservative tracking of objects using call/return for ownership transfer.

0 commit comments

Comments
 (0)