Close channel to signal goroutines to quit and waitgroup to confirm that they have
This commit is contained in:
parent
50d8ba24ee
commit
f27b0b53e2
35
irc.go
35
irc.go
@ -37,12 +37,12 @@ const (
|
||||
|
||||
// Read data from a connection. To be used as a goroutine.
|
||||
func (irc *Connection) readLoop() {
|
||||
defer irc.Done()
|
||||
br := bufio.NewReaderSize(irc.socket, 512)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-irc.endread:
|
||||
irc.readerExit <- true
|
||||
case <-irc.end:
|
||||
return
|
||||
default:
|
||||
// Set a read deadline based on the combined timeout and ping frequency
|
||||
@ -97,21 +97,19 @@ func (irc *Connection) readLoop() {
|
||||
irc.RunCallbacks(event)
|
||||
}
|
||||
}
|
||||
|
||||
irc.readerExit <- true
|
||||
return
|
||||
}
|
||||
|
||||
// Loop to write to a connection. To be used as a goroutine.
|
||||
func (irc *Connection) writeLoop() {
|
||||
defer irc.Done()
|
||||
for {
|
||||
select {
|
||||
case <-irc.endwrite:
|
||||
irc.writerExit <- true
|
||||
case <-irc.end:
|
||||
return
|
||||
default:
|
||||
b, ok := <-irc.pwrite
|
||||
if !ok || b == "" || irc.socket == nil {
|
||||
irc.writerExit <- true
|
||||
return
|
||||
}
|
||||
|
||||
@ -130,17 +128,17 @@ func (irc *Connection) writeLoop() {
|
||||
|
||||
if err != nil {
|
||||
irc.Error <- err
|
||||
irc.writerExit <- true
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
irc.writerExit <- true
|
||||
return
|
||||
}
|
||||
|
||||
// Pings the server if we have not received any messages for 5 minutes
|
||||
// to keep the connection alive. To be used as a goroutine.
|
||||
func (irc *Connection) pingLoop() {
|
||||
defer irc.Done()
|
||||
ticker := time.NewTicker(1 * time.Minute) // Tick every minute for monitoring
|
||||
ticker2 := time.NewTicker(irc.PingFreq) // Tick at the ping frequency.
|
||||
for {
|
||||
@ -158,10 +156,9 @@ func (irc *Connection) pingLoop() {
|
||||
irc.nickcurrent = irc.nick
|
||||
irc.SendRawf("NICK %s", irc.nick)
|
||||
}
|
||||
case <-irc.endping:
|
||||
case <-irc.end:
|
||||
ticker.Stop()
|
||||
ticker2.Stop()
|
||||
irc.pingerExit <- true
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -284,15 +281,11 @@ func (irc *Connection) Mode(target string, modestring ...string) {
|
||||
// A disconnect sends all buffered messages (if possible),
|
||||
// stops all goroutines and then closes the socket.
|
||||
func (irc *Connection) Disconnect() {
|
||||
irc.endping <- true
|
||||
irc.endwrite <- true
|
||||
irc.endread <- true
|
||||
close(irc.end)
|
||||
close(irc.pwrite)
|
||||
close(irc.pread)
|
||||
|
||||
<-irc.readerExit
|
||||
<-irc.writerExit
|
||||
<-irc.pingerExit
|
||||
irc.Wait()
|
||||
irc.socket.Close()
|
||||
irc.socket = nil
|
||||
if irc.netsock != nil {
|
||||
@ -362,6 +355,7 @@ func (irc *Connection) Connect(server string) error {
|
||||
irc.pwrite = make(chan string, 10)
|
||||
irc.Error = make(chan error, 2)
|
||||
|
||||
irc.Add(3)
|
||||
go irc.readLoop()
|
||||
go irc.writeLoop()
|
||||
go irc.pingLoop()
|
||||
@ -390,12 +384,7 @@ func IRC(nick, user string) *Connection {
|
||||
nick: nick,
|
||||
user: user,
|
||||
Log: log.New(os.Stdout, "", log.LstdFlags),
|
||||
readerExit: make(chan bool),
|
||||
writerExit: make(chan bool),
|
||||
pingerExit: make(chan bool),
|
||||
endping: make(chan bool),
|
||||
endread: make(chan bool),
|
||||
endwrite: make(chan bool),
|
||||
end: make(chan struct{}),
|
||||
Version: VERSION,
|
||||
KeepAlive: 4 * time.Minute,
|
||||
Timeout: 1 * time.Minute,
|
||||
|
@ -8,10 +8,12 @@ import (
|
||||
"crypto/tls"
|
||||
"log"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Connection struct {
|
||||
sync.WaitGroup
|
||||
Debug bool
|
||||
Error chan error
|
||||
Password string
|
||||
@ -25,8 +27,7 @@ type Connection struct {
|
||||
socket net.Conn
|
||||
netsock net.Conn
|
||||
pread, pwrite chan string
|
||||
readerExit, writerExit, pingerExit chan bool
|
||||
endping, endread, endwrite chan bool
|
||||
end chan struct{}
|
||||
|
||||
nick string //The nickname we want.
|
||||
nickcurrent string //The nickname we currently have.
|
||||
@ -43,7 +44,6 @@ type Connection struct {
|
||||
stopped bool
|
||||
}
|
||||
|
||||
|
||||
// A struct to represent an event.
|
||||
type Event struct {
|
||||
Code string
|
||||
@ -55,7 +55,6 @@ type Event struct {
|
||||
Arguments []string
|
||||
}
|
||||
|
||||
|
||||
// Retrieve the last message from Event arguments.
|
||||
// This function leaves the arguments untouched and
|
||||
// returns an empty string if there are none.
|
||||
|
Loading…
Reference in New Issue
Block a user