igrigorik/agent — pull request #4 by nate (2012-02-29 08:51:48+00:00)
Title: Race conditions exists in Agent::Transport::Queue

The contents of `que` could change between the lines checking their contents ([L85](https://github.com/igrigorik/agent/blob/master/lib/agent/transport/queue.rb#L85) and [L90](https://github.com/igrigorik/agent/blob/master/lib/agent/transport/queue.rb#L90)), and when pop or push synchronizes to to prevent modification to `que` ([L52](https://github.com/igrigorik/agent/blob/master/lib/agent/transport/queue.rb#L52) and [L67](https://github.com/igrigorik/agent/blob/master/lib/agent/transport/queue.rb#L67)). This could cause a call to receive(true) or send(msg, true) to block instead of raising an exception.

To fix this, this patch changes the mutex to a monitor, which I think is more appropriate for two reasons. The first is that we're waiting until a statement is true, so MonitorMixin::ConditionVariable's handy wait_while method is a good fit and simplifies the code. The second is that Monitors are re-entrant, which lets us synchronize both in receive and pop (or send and push) which should prevent the race condition mentioned above while keeping receive/send and pop/push separate.

The specs all pass in ruby 1.9.2-p290 and 1.9.3-p125, and jruby 1.6.7 in 1.9 mode.