aboutsummaryrefslogtreecommitdiff
path: root/nexgb
diff options
context:
space:
mode:
authorAndrew Gallant (Ocelot) <Andrew.Gallant@tufts.edu>2012-05-12 21:55:57 -0400
committerAndrew Gallant (Ocelot) <Andrew.Gallant@tufts.edu>2012-05-12 21:55:57 -0400
commit6bdfd1d1b14071e22d9b09fa5e526f715798c379 (patch)
tree5b700755492ffddc295e2d73aaa18911e0a42d9e /nexgb
parent7abc9c6455b8281d5dfd5604ec6ca6fe0d459318 (diff)
downloadhaven-6bdfd1d1b14071e22d9b09fa5e526f715798c379.tar.gz
haven-6bdfd1d1b14071e22d9b09fa5e526f715798c379.tar.xz
haven-6bdfd1d1b14071e22d9b09fa5e526f715798c379.zip
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
Diffstat (limited to 'nexgb')
-rw-r--r--nexgb/xgb.go8
1 files changed, 5 insertions, 3 deletions
diff --git a/nexgb/xgb.go b/nexgb/xgb.go
index b2cf56c..c52f722 100644
--- a/nexgb/xgb.go
+++ b/nexgb/xgb.go
@@ -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.