|
@@ -42,7 +42,7 @@ type Socket struct {
|
42
|
42
|
}
|
43
|
43
|
|
44
|
44
|
// NewSocket returns a new Socket.
|
45
|
|
-func NewSocket(conn net.Conn, maxReadQBytes int, maxSendQBytes int) Socket {
|
|
45
|
+func NewSocket(conn net.Conn, maxReadQBytes int, maxSendQBytes int) *Socket {
|
46
|
46
|
result := Socket{
|
47
|
47
|
conn: conn,
|
48
|
48
|
reader: bufio.NewReaderSize(conn, maxReadQBytes),
|
|
@@ -50,7 +50,7 @@ func NewSocket(conn net.Conn, maxReadQBytes int, maxSendQBytes int) Socket {
|
50
|
50
|
writerSlotOpen: make(chan bool, 1),
|
51
|
51
|
}
|
52
|
52
|
result.writerSlotOpen <- true
|
53
|
|
- return result
|
|
53
|
+ return &result
|
54
|
54
|
}
|
55
|
55
|
|
56
|
56
|
// Close stops a Socket from being able to send/receive any more data.
|
|
@@ -162,16 +162,20 @@ func (socket *Socket) readyToWrite() bool {
|
162
|
162
|
|
163
|
163
|
// send actually writes messages to socket.Conn; it may block
|
164
|
164
|
func (socket *Socket) send() {
|
165
|
|
- // one of these checks happens-after every call to Write(), so we can't miss writes
|
166
|
|
- for socket.readyToWrite() {
|
|
165
|
+ for {
|
167
|
166
|
select {
|
168
|
167
|
case <-socket.writerSlotOpen:
|
169
|
168
|
// got the trylock: actually do the write
|
170
|
169
|
socket.performWrite()
|
|
170
|
+ // surrender the trylock:
|
171
|
171
|
socket.writerSlotOpen <- true
|
|
172
|
+ // check if more data came in while we held the trylock:
|
|
173
|
+ if !socket.readyToWrite() {
|
|
174
|
+ return
|
|
175
|
+ }
|
172
|
176
|
default:
|
173
|
|
- // another goroutine is in progress; exit and wait for them to loop back around
|
174
|
|
- // and observe readyToWrite() again
|
|
177
|
+ // someone else has the trylock; if there's more data to write,
|
|
178
|
+ // they'll see if after they release it
|
175
|
179
|
return
|
176
|
180
|
}
|
177
|
181
|
}
|