[MacRuby-devel] Concurrency bug in ControlTower
Charles Oliver Nutter
headius at headius.com
Fri Jan 21 23:14:19 PST 2011
Apologies reporting this here; I'm not sure where I should report bugs
in ControlTower.
I believe there's a bug in ControlTower around line 34:
def open
@status = :open
while (@status == :open)
connection = @socket.accept # << here
@request_queue.async(@request_group) do
The "connection" local variable is used in the async block below to
parse the request and send the response. Unless MacRuby's blocks
behave differently than regular Ruby, this variable is shared across
all activations of that block. As a result, it's possible that two
concurrent requests will end up using each others' connection, and
usually just blowing up as a result.
The fix I've come up with is to wrap the @request_queue.async call in
a tap call:
def open
@status = :open
while (@status == :open)
conn = @socket.accept
conn.tap do |connection|
@request_queue.async(@request_group) do
Since async can't accept any explicitly-passed state, this seems like
the safest way to ensure the connection reference is not shared by
separate invocations. I'm not sure if it's possible in GCD, but having
async take an optional argument with explicitly-passed state might
also be a good way to fix this.
- Charlie
More information about the MacRuby-devel
mailing list