Use mutex for accessing go-whatsapp contacts and chats maps

This commit is contained in:
Tulir Asokan 2021-06-19 02:22:01 +03:00
parent a3669a675b
commit bc7a82c0be
4 changed files with 20 additions and 1 deletions

View file

@ -779,7 +779,9 @@ func (handler *CommandHandler) CommandList(ce *CommandEvent) {
if contacts { if contacts {
typeName = "Contacts" typeName = "Contacts"
} }
ce.User.Conn.Store.ContactsLock.RLock()
result := formatContacts(contacts, ce.User.Conn.Store.Contacts) result := formatContacts(contacts, ce.User.Conn.Store.Contacts)
ce.User.Conn.Store.ContactsLock.RUnlock()
if len(result) == 0 { if len(result) == 0 {
ce.Reply("No %s found", strings.ToLower(typeName)) ce.Reply("No %s found", strings.ToLower(typeName))
return return
@ -817,7 +819,9 @@ func (handler *CommandHandler) CommandOpen(ce *CommandEvent) {
return return
} }
user.Conn.Store.ContactsLock.RLock()
contact, ok := user.Conn.Store.Contacts[jid] contact, ok := user.Conn.Store.Contacts[jid]
user.Conn.Store.ContactsLock.RUnlock()
if !ok { if !ok {
ce.Reply("Group JID not found in contacts. Try syncing contacts with `sync` first.") ce.Reply("Group JID not found in contacts. Try syncing contacts with `sync` first.")
return return
@ -863,7 +867,9 @@ func (handler *CommandHandler) CommandPM(ce *CommandEvent) {
handler.log.Debugln("Importing", jid, "for", user) handler.log.Debugln("Importing", jid, "for", user)
user.Conn.Store.ContactsLock.RLock()
contact, ok := user.Conn.Store.Contacts[jid] contact, ok := user.Conn.Store.Contacts[jid]
user.Conn.Store.ContactsLock.RUnlock()
if !ok { if !ok {
if !force { if !force {
ce.Reply("Phone number not found in contacts. Try syncing contacts with `sync` first. " + ce.Reply("Phone number not found in contacts. Try syncing contacts with `sync` first. " +

View file

@ -201,7 +201,9 @@ func (portal *Portal) syncDoublePuppetDetailsAfterCreate(source *User) {
if doublePuppet == nil { if doublePuppet == nil {
return return
} }
source.Conn.Store.ChatsLock.RLock()
chat, ok := source.Conn.Store.Chats[portal.Key.JID] chat, ok := source.Conn.Store.Chats[portal.Key.JID]
source.Conn.Store.ChatsLock.RUnlock()
if !ok { if !ok {
portal.log.Debugln("Not syncing chat mute/tags with %s: chat info not found", source.MXID) portal.log.Debugln("Not syncing chat mute/tags with %s: chat info not found", source.MXID)
return return
@ -598,7 +600,9 @@ func (portal *Portal) UpdateMetadata(user *User) bool {
portal.SyncBroadcastRecipients(user, broadcastMetadata) portal.SyncBroadcastRecipients(user, broadcastMetadata)
update = portal.UpdateName(broadcastMetadata.Name, "", nil, false) || update update = portal.UpdateName(broadcastMetadata.Name, "", nil, false) || update
} else { } else {
user.Conn.Store.ContactsLock.RLock()
contact, _ := user.Conn.Store.Contacts[portal.Key.JID] contact, _ := user.Conn.Store.Contacts[portal.Key.JID]
user.Conn.Store.ContactsLock.RUnlock()
update = portal.UpdateName(contact.Name, "", nil, false) || update update = portal.UpdateName(contact.Name, "", nil, false) || update
} }
update = portal.UpdateTopic(BroadcastTopic, "", nil, false) || update update = portal.UpdateTopic(BroadcastTopic, "", nil, false) || update
@ -1085,7 +1089,9 @@ func (portal *Portal) CreateMatrixRoom(user *User) error {
if err == nil && broadcastMetadata.Status == 200 { if err == nil && broadcastMetadata.Status == 200 {
portal.Name = broadcastMetadata.Name portal.Name = broadcastMetadata.Name
} else { } else {
user.Conn.Store.ContactsLock.RLock()
contact, _ := user.Conn.Store.Contacts[portal.Key.JID] contact, _ := user.Conn.Store.Contacts[portal.Key.JID]
user.Conn.Store.ContactsLock.RUnlock()
portal.Name = contact.Name portal.Name = contact.Name
} }
if len(portal.Name) == 0 { if len(portal.Name) == 0 {

View file

@ -293,7 +293,9 @@ func (puppet *Puppet) SyncContactIfNecessary(source *User) {
return return
} }
source.Conn.Store.ContactsLock.RLock()
contact, ok := source.Conn.Store.Contacts[puppet.JID] contact, ok := source.Conn.Store.Contacts[puppet.JID]
source.Conn.Store.ContactsLock.RUnlock()
if !ok { if !ok {
puppet.log.Warnfln("No contact info found through %s in SyncContactIfNecessary", source.MXID) puppet.log.Warnfln("No contact info found through %s in SyncContactIfNecessary", source.MXID)
contact.JID = puppet.JID contact.JID = puppet.JID

View file

@ -667,9 +667,11 @@ func (user *User) HandleStreamEvent(evt whatsapp.StreamEvent) {
func (user *User) HandleChatList(chats []whatsapp.Chat) { func (user *User) HandleChatList(chats []whatsapp.Chat) {
user.log.Infoln("Chat list received") user.log.Infoln("Chat list received")
chatMap := make(map[string]whatsapp.Chat) chatMap := make(map[string]whatsapp.Chat)
user.Conn.Store.ChatsLock.RLock()
for _, chat := range user.Conn.Store.Chats { for _, chat := range user.Conn.Store.Chats {
chatMap[chat.JID] = chat chatMap[chat.JID] = chat
} }
user.Conn.Store.ChatsLock.RUnlock()
for _, chat := range chats { for _, chat := range chats {
chatMap[chat.JID] = chat chatMap[chat.JID] = chat
} }
@ -798,10 +800,13 @@ func (user *User) collectChatList(chatMap map[string]whatsapp.Chat) ChatList {
for _, chat := range chatMap { for _, chat := range chatMap {
portal := user.GetPortalByJID(chat.JID) portal := user.GetPortalByJID(chat.JID)
user.Conn.Store.ContactsLock.RLock()
contact, _ := user.Conn.Store.Contacts[chat.JID]
user.Conn.Store.ContactsLock.RUnlock()
chats = append(chats, Chat{ chats = append(chats, Chat{
Chat: chat, Chat: chat,
Portal: portal, Portal: portal,
Contact: user.Conn.Store.Contacts[chat.JID], Contact: contact,
}) })
var inCommunity, ok bool var inCommunity, ok bool
if inCommunity, ok = existingKeys[portal.Key]; !ok || !inCommunity { if inCommunity, ok = existingKeys[portal.Key]; !ok || !inCommunity {