Fix critical double-release race in importInProgress flag
CRITICAL BUG: The previous fix had a race condition where the importInProgress flag could be released twice, allowing two goroutines to think they both hold the lock. Bug scenario: 1. Goroutine A: acquires lock (CAS true) 2. Goroutine A: manually releases at line 208 for git dirty skip 3. Goroutine B: CAS succeeds, acquires lock 4. Goroutine A: defer runs, releases flag AGAIN (clears B lock) 5. Goroutine C: CAS succeeds - now TWO goroutines have lock Root cause: Using both manual Store(false) AND defer Store(false) created a window where the flag could be cleared twice. Fix: Use a shouldDeferRelease flag to disable the deferred release when we manually release early. This ensures exactly one release per acquisition. Testing: All auto-import tests still passing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2
.beads/daemon-stderr.log
Normal file
2
.beads/daemon-stderr.log
Normal file
@@ -0,0 +1,2 @@
|
||||
Error: daemon already running (PID 27867)
|
||||
Use 'bd daemon --stop' to stop it first
|
||||
@@ -196,7 +196,15 @@ func (s *Server) checkAndAutoImportIfStale(req *Request) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
defer s.importInProgress.Store(false)
|
||||
|
||||
// Track whether we should release the lock via defer
|
||||
// Set to false if we manually release early to avoid double-release bug
|
||||
shouldDeferRelease := true
|
||||
defer func() {
|
||||
if shouldDeferRelease {
|
||||
s.importInProgress.Store(false)
|
||||
}
|
||||
}()
|
||||
|
||||
// Check if git has uncommitted changes that include beads files (bd-8931)
|
||||
// If JSONL files are uncommitted, skip auto-import to avoid conflicts
|
||||
@@ -204,8 +212,9 @@ func (s *Server) checkAndAutoImportIfStale(req *Request) error {
|
||||
dbDir := filepath.Dir(dbPath)
|
||||
workspaceRoot := filepath.Dir(dbDir) // Go up from .beads to workspace root
|
||||
if hasUncommittedBeadsFiles(workspaceRoot) {
|
||||
// CRITICAL: Must release lock before returning to avoid race condition
|
||||
// CRITICAL: Release lock and disable defer to avoid double-release race
|
||||
s.importInProgress.Store(false)
|
||||
shouldDeferRelease = false
|
||||
|
||||
if os.Getenv("BD_DEBUG") != "" {
|
||||
fmt.Fprintf(os.Stderr, "Debug: skipping auto-import, .beads files have uncommitted changes\n")
|
||||
|
||||
Reference in New Issue
Block a user