Kaynağa Gözat

refactor(ui/chat): avoid double-locking in guildState save

Remove the lock from save() and hold it through both mutation and
persistence in setExpanded/setChannelExpanded. This eliminates the
redundant second lock acquisition and closes the window where data
could change between mutation and save.

Fixes COMP #6.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
claude 1 ay önce
ebeveyn
işleme
756b4ed31a
1 değiştirilmiş dosya ile 3 ekleme ve 4 silme
  1. 3 4
      internal/ui/chat/guildstate.go

+ 3 - 4
internal/ui/chat/guildstate.go

@@ -44,20 +44,19 @@ func loadGuildState() *guildState {
 	return gs
 }
 
+// save persists guild state to disk. Caller must hold gs.mu.
 func (gs *guildState) save() {
-	gs.mu.Lock()
-	defer gs.mu.Unlock()
 	atomicSaveJSON(stateFilePath, gs)
 }
 
 func (gs *guildState) setExpanded(id discord.GuildID, expanded bool) {
 	gs.mu.Lock()
+	defer gs.mu.Unlock()
 	if expanded {
 		gs.ExpandedGuilds[id] = true
 	} else {
 		delete(gs.ExpandedGuilds, id)
 	}
-	gs.mu.Unlock()
 	gs.save()
 }
 
@@ -69,12 +68,12 @@ func (gs *guildState) isExpanded(id discord.GuildID) bool {
 
 func (gs *guildState) setChannelExpanded(id discord.ChannelID, expanded bool) {
 	gs.mu.Lock()
+	defer gs.mu.Unlock()
 	if expanded {
 		gs.ExpandedChannels[id] = true
 	} else {
 		delete(gs.ExpandedChannels, id)
 	}
-	gs.mu.Unlock()
 	gs.save()
 }