Browse Source

fix #1053, #1083

tags/v2.2.0-rc1
Shivaram Lingamneni 4 years ago
parent
commit
cb530050f1
3 changed files with 46 additions and 46 deletions
  1. 3
    2
      irc/client.go
  2. 5
    14
      irc/handlers.go
  3. 38
    30
      irc/monitor.go

+ 3
- 2
irc/client.go View File

@@ -1316,6 +1316,9 @@ func (client *Client) destroy(session *Session) {
1316 1316
 		session.SetDestroyed()
1317 1317
 		session.socket.Close()
1318 1318
 
1319
+		// clean up monitor state
1320
+		client.server.monitorManager.RemoveAll(session)
1321
+
1319 1322
 		// remove from connection limits
1320 1323
 		var source string
1321 1324
 		if session.isTor {
@@ -1381,8 +1384,6 @@ func (client *Client) destroy(session *Session) {
1381 1384
 	if registered {
1382 1385
 		client.server.monitorManager.AlertAbout(details.nick, details.nickCasefolded, false)
1383 1386
 	}
1384
-	// clean up monitor state
1385
-	client.server.monitorManager.RemoveAll(client)
1386 1387
 
1387 1388
 	// clean up channels
1388 1389
 	// (note that if this is a reattach, client has no channels and therefore no friends)

+ 5
- 14
irc/handlers.go View File

@@ -1722,11 +1722,7 @@ func monitorRemoveHandler(server *Server, client *Client, msg ircmsg.IrcMessage,
1722 1722
 
1723 1723
 	targets := strings.Split(msg.Params[1], ",")
1724 1724
 	for _, target := range targets {
1725
-		cfnick, err := CasefoldName(target)
1726
-		if err != nil {
1727
-			continue
1728
-		}
1729
-		server.monitorManager.Remove(client, cfnick)
1725
+		server.monitorManager.Remove(rb.session, target)
1730 1726
 	}
1731 1727
 
1732 1728
 	return false
@@ -1752,12 +1748,7 @@ func monitorAddHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb
1752 1748
 		}
1753 1749
 
1754 1750
 		// add target
1755
-		casefoldedTarget, err := CasefoldName(target)
1756
-		if err != nil {
1757
-			continue
1758
-		}
1759
-
1760
-		err = server.monitorManager.Add(client, casefoldedTarget, limits.MonitorEntries)
1751
+		err := server.monitorManager.Add(rb.session, target, limits.MonitorEntries)
1761 1752
 		if err == errMonitorLimitExceeded {
1762 1753
 			rb.Add(nil, server.name, ERR_MONLISTFULL, client.Nick(), strconv.Itoa(limits.MonitorEntries), strings.Join(targets, ","))
1763 1754
 			break
@@ -1786,14 +1777,14 @@ func monitorAddHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb
1786 1777
 
1787 1778
 // MONITOR C
1788 1779
 func monitorClearHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
1789
-	server.monitorManager.RemoveAll(client)
1780
+	server.monitorManager.RemoveAll(rb.session)
1790 1781
 	return false
1791 1782
 }
1792 1783
 
1793 1784
 // MONITOR L
1794 1785
 func monitorListHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
1795 1786
 	nick := client.Nick()
1796
-	monitorList := server.monitorManager.List(client)
1787
+	monitorList := server.monitorManager.List(rb.session)
1797 1788
 
1798 1789
 	var nickList []string
1799 1790
 	for _, cfnick := range monitorList {
@@ -1820,7 +1811,7 @@ func monitorStatusHandler(server *Server, client *Client, msg ircmsg.IrcMessage,
1820 1811
 	var online []string
1821 1812
 	var offline []string
1822 1813
 
1823
-	monitorList := server.monitorManager.List(client)
1814
+	monitorList := server.monitorManager.List(rb.session)
1824 1815
 
1825 1816
 	for _, name := range monitorList {
1826 1817
 		currentNick := server.getCurrentNick(name)

+ 38
- 30
irc/monitor.go View File

@@ -12,25 +12,24 @@ import (
12 12
 // MonitorManager keeps track of who's monitoring which nicks.
13 13
 type MonitorManager struct {
14 14
 	sync.RWMutex // tier 2
15
-	// client -> nicks it's watching
16
-	watching map[*Client]map[string]bool
17
-	// nick -> clients watching it
18
-	watchedby map[string]map[*Client]bool
19
-	// (all nicks must be normalized externally by casefolding)
15
+	// client -> (casefolded nick it's watching -> uncasefolded nick)
16
+	watching map[*Session]map[string]string
17
+	// casefolded nick -> clients watching it
18
+	watchedby map[string]map[*Session]empty
20 19
 }
21 20
 
22 21
 func (mm *MonitorManager) Initialize() {
23
-	mm.watching = make(map[*Client]map[string]bool)
24
-	mm.watchedby = make(map[string]map[*Client]bool)
22
+	mm.watching = make(map[*Session]map[string]string)
23
+	mm.watchedby = make(map[string]map[*Session]empty)
25 24
 }
26 25
 
27 26
 // AlertAbout alerts everyone monitoring `client`'s nick that `client` is now {on,off}line.
28 27
 func (manager *MonitorManager) AlertAbout(nick, cfnick string, online bool) {
29
-	var watchers []*Client
28
+	var watchers []*Session
30 29
 	// safely copy the list of clients watching our nick
31 30
 	manager.RLock()
32
-	for client := range manager.watchedby[cfnick] {
33
-		watchers = append(watchers, client)
31
+	for session := range manager.watchedby[cfnick] {
32
+		watchers = append(watchers, session)
34 33
 	}
35 34
 	manager.RUnlock()
36 35
 
@@ -39,58 +38,67 @@ func (manager *MonitorManager) AlertAbout(nick, cfnick string, online bool) {
39 38
 		command = RPL_MONONLINE
40 39
 	}
41 40
 
42
-	for _, mClient := range watchers {
43
-		mClient.Send(nil, mClient.server.name, command, mClient.Nick(), nick)
41
+	for _, session := range watchers {
42
+		session.Send(nil, session.client.server.name, command, session.client.Nick(), nick)
44 43
 	}
45 44
 }
46 45
 
47 46
 // Add registers `client` to receive notifications about `nick`.
48
-func (manager *MonitorManager) Add(client *Client, nick string, limit int) error {
47
+func (manager *MonitorManager) Add(session *Session, nick string, limit int) error {
48
+	cfnick, err := CasefoldName(nick)
49
+	if err != nil {
50
+		return err
51
+	}
52
+
49 53
 	manager.Lock()
50 54
 	defer manager.Unlock()
51 55
 
52
-	if manager.watching[client] == nil {
53
-		manager.watching[client] = make(map[string]bool)
56
+	if manager.watching[session] == nil {
57
+		manager.watching[session] = make(map[string]string)
54 58
 	}
55
-	if manager.watchedby[nick] == nil {
56
-		manager.watchedby[nick] = make(map[*Client]bool)
59
+	if manager.watchedby[cfnick] == nil {
60
+		manager.watchedby[cfnick] = make(map[*Session]empty)
57 61
 	}
58 62
 
59
-	if len(manager.watching[client]) >= limit {
63
+	if len(manager.watching[session]) >= limit {
60 64
 		return errMonitorLimitExceeded
61 65
 	}
62 66
 
63
-	manager.watching[client][nick] = true
64
-	manager.watchedby[nick][client] = true
67
+	manager.watching[session][cfnick] = nick
68
+	manager.watchedby[cfnick][session] = empty{}
65 69
 	return nil
66 70
 }
67 71
 
68 72
 // Remove unregisters `client` from receiving notifications about `nick`.
69
-func (manager *MonitorManager) Remove(client *Client, nick string) error {
73
+func (manager *MonitorManager) Remove(session *Session, nick string) (err error) {
74
+	cfnick, err := CasefoldName(nick)
75
+	if err != nil {
76
+		return
77
+	}
78
+
70 79
 	manager.Lock()
71 80
 	defer manager.Unlock()
72
-	// deleting from nil maps is fine
73
-	delete(manager.watching[client], nick)
74
-	delete(manager.watchedby[nick], client)
81
+	delete(manager.watching[session], cfnick)
82
+	delete(manager.watchedby[cfnick], session)
75 83
 	return nil
76 84
 }
77 85
 
78 86
 // RemoveAll unregisters `client` from receiving notifications about *all* nicks.
79
-func (manager *MonitorManager) RemoveAll(client *Client) {
87
+func (manager *MonitorManager) RemoveAll(session *Session) {
80 88
 	manager.Lock()
81 89
 	defer manager.Unlock()
82 90
 
83
-	for nick := range manager.watching[client] {
84
-		delete(manager.watchedby[nick], client)
91
+	for cfnick := range manager.watching[session] {
92
+		delete(manager.watchedby[cfnick], session)
85 93
 	}
86
-	delete(manager.watching, client)
94
+	delete(manager.watching, session)
87 95
 }
88 96
 
89 97
 // List lists all nicks that `client` is registered to receive notifications about.
90
-func (manager *MonitorManager) List(client *Client) (nicks []string) {
98
+func (manager *MonitorManager) List(session *Session) (nicks []string) {
91 99
 	manager.RLock()
92 100
 	defer manager.RUnlock()
93
-	for nick := range manager.watching[client] {
101
+	for _, nick := range manager.watching[session] {
94 102
 		nicks = append(nicks, nick)
95 103
 	}
96 104
 	return nicks

Loading…
Cancel
Save