mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-10 22:19:31 +01:00
try to reduce redundant goroutines
This commit is contained in:
parent
4778e7bcc7
commit
f54561171e
@ -59,7 +59,7 @@ func (socket *Socket) Close() {
|
|||||||
socket.closed = true
|
socket.closed = true
|
||||||
socket.Unlock()
|
socket.Unlock()
|
||||||
|
|
||||||
go socket.send()
|
socket.wakeWriter()
|
||||||
}
|
}
|
||||||
|
|
||||||
// CertFP returns the fingerprint of the certificate provided by the client.
|
// CertFP returns the fingerprint of the certificate provided by the client.
|
||||||
@ -134,10 +134,22 @@ func (socket *Socket) Write(data string) (err error) {
|
|||||||
}
|
}
|
||||||
socket.Unlock()
|
socket.Unlock()
|
||||||
|
|
||||||
go socket.send()
|
socket.wakeWriter()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// wakeWriter starts the goroutine that actually performs the write, without blocking
|
||||||
|
func (socket *Socket) wakeWriter() {
|
||||||
|
// attempt to acquire the trylock
|
||||||
|
select {
|
||||||
|
case <-socket.writerSlotOpen:
|
||||||
|
// acquired the trylock; send() will release it
|
||||||
|
go socket.send()
|
||||||
|
default:
|
||||||
|
// failed to acquire; the holder will check for more data after releasing it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// SetFinalData sets the final data to send when the SocketWriter closes.
|
// SetFinalData sets the final data to send when the SocketWriter closes.
|
||||||
func (socket *Socket) SetFinalData(data string) {
|
func (socket *Socket) SetFinalData(data string) {
|
||||||
socket.Lock()
|
socket.Lock()
|
||||||
@ -163,19 +175,21 @@ func (socket *Socket) readyToWrite() bool {
|
|||||||
// send actually writes messages to socket.Conn; it may block
|
// send actually writes messages to socket.Conn; it may block
|
||||||
func (socket *Socket) send() {
|
func (socket *Socket) send() {
|
||||||
for {
|
for {
|
||||||
select {
|
// we are holding the trylock: actually do the write
|
||||||
case <-socket.writerSlotOpen:
|
|
||||||
// got the trylock: actually do the write
|
|
||||||
socket.performWrite()
|
socket.performWrite()
|
||||||
// surrender the trylock:
|
// surrender the trylock, avoiding a race where a write comes in after we've
|
||||||
|
// checked readyToWrite() and it returned false, but while we still hold the trylock:
|
||||||
socket.writerSlotOpen <- true
|
socket.writerSlotOpen <- true
|
||||||
// check if more data came in while we held the trylock:
|
// check if more data came in while we held the trylock:
|
||||||
if !socket.readyToWrite() {
|
if !socket.readyToWrite() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
select {
|
||||||
|
case <-socket.writerSlotOpen:
|
||||||
|
// got the trylock, loop back around and write
|
||||||
default:
|
default:
|
||||||
// someone else has the trylock; if there's more data to write,
|
// failed to acquire; exit and wait for the holder to observe readyToWrite()
|
||||||
// they'll see if after they release it
|
// after releasing it
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user