commit 2221f93

Hubert Hirtz  ·  2020-11-22 21:22:23 +0000 UTC
parent c761717
Cleanly stop all coroutines on irc.Session.Stop

This fixes a panic when irc.Session.handle is called with an empty
message.
2 files changed,  +19, -5
+13, -3
 1@@ -260,6 +260,7 @@ func (s *Session) Stop() {
 2 	close(s.acts)
 3 	close(s.evts)
 4 	close(s.msgs)
 5+	s.typings.Stop()
 6 }
 7 
 8 // Poll returns the event channel where incoming events are reported.
 9@@ -465,7 +466,10 @@ func (s *Session) run() {
10 		var err error
11 
12 		select {
13-		case act := <-s.acts:
14+		case act, ok := <-s.acts:
15+			if !ok {
16+				break
17+			}
18 			switch act := act.(type) {
19 			case actionSendRaw:
20 				err = s.sendRaw(act)
21@@ -484,13 +488,19 @@ func (s *Session) run() {
22 			case actionRequestHistory:
23 				err = s.requestHistory(act)
24 			}
25-		case msg := <-s.msgs:
26+		case msg, ok := <-s.msgs:
27+			if !ok {
28+				break
29+			}
30 			if s.registered {
31 				err = s.handle(msg)
32 			} else {
33 				err = s.handleStart(msg)
34 			}
35-		case t := <-s.typings.Stops():
36+		case t, ok := <-s.typings.Stops():
37+			if !ok {
38+				break
39+			}
40 			s.evts <- TagEvent{
41 				User:   s.users[t.Name].Name,
42 				Target: s.channels[t.Target].Name,
+6, -2
 1@@ -24,8 +24,7 @@ func NewTypings() *Typings {
 2 		stops:    make(chan Typing, 16),
 3 	}
 4 	go func() {
 5-		for {
 6-			t := <-ts.timeouts
 7+		for t := range ts.timeouts {
 8 			now := time.Now()
 9 			ts.l.Lock()
10 			oldT, ok := ts.targets[t]
11@@ -41,6 +40,11 @@ func NewTypings() *Typings {
12 	return ts
13 }
14 
15+func (ts *Typings) Stop() {
16+	close(ts.timeouts)
17+	close(ts.stops)
18+}
19+
20 func (ts *Typings) Stops() <-chan Typing {
21 	return ts.stops
22 }