diff options
| author | Andrew Gallant (Ocelot) <[email protected]> | 2012-05-12 21:55:57 -0400 |
|---|---|---|
| committer | Andrew Gallant (Ocelot) <[email protected]> | 2012-05-12 21:55:57 -0400 |
| commit | c27e49fbcfbb6c2381c3edc5a7765d7ca6e4f226 (patch) | |
| tree | 89546d542213bae3794152f474a227de4595ce2a | |
| parent | e93d7d109a1eaf93b67636e04d6a795d49b15b37 (diff) | |
A more idiomatic way of trying a non-blocking send on a buffered channel
and falling back to a blocking send inside a goroutine.
This really needs to be fixed. The situation only arises when events are
sent and aren't pulled off the channel using {Wait,Poll}ForEvent.
Namely, if the event send blocks, the entire program will deadlock.
Using a goroutine is not ideal because we lose a guarantee of order:
that events are processed in the order of their arrival. However, it
seems OK as a temporary band-aide for a situation that probably doesn't
arise too often.
What I need to do is implement a dynamic queue. Here is a reference
implementation: http://play.golang.org/p/AiHBsxTFpj
| -rw-r--r-- | xgb.go | 8 |
1 files changed, 5 insertions, 3 deletions
@@ -379,12 +379,14 @@ func (c *Conn) readResponses() { // FIXME: I'm not sure if using a goroutine here to guarantee // a non-blocking send is the right way to go. I should implement // a proper dynamic queue. - if cap(c.eventChan) == len(c.eventChan) { + // I am pretty sure this also loses a guarantee of events being + // processed in order of being received. + select { + case c.eventChan <- event: + default: go func() { c.eventChan <- event }() - } else { - c.eventChan <- event } // No more processing for events. |
