Skip to content

fix(context): avoid Context.Clone deadlock under a concurrent writer#884

Open
Shinku-Chen wants to merge 1 commit into
gocolly:masterfrom
Shinku-Chen:fix(context)-avoid-Context.Clone-deadlock-under-a-concurrent-writer
Open

fix(context): avoid Context.Clone deadlock under a concurrent writer#884
Shinku-Chen wants to merge 1 commit into
gocolly:masterfrom
Shinku-Chen:fix(context)-avoid-Context.Clone-deadlock-under-a-concurrent-writer

Conversation

@Shinku-Chen

Copy link
Copy Markdown
Contributor

Context.Clone held c.lock.RLock and then called c.ForEach, which
acquires c.lock.RLock a second time on the same goroutine. sync.RWMutex
intentionally starves additional readers once a writer is queued (to
prevent writer starvation), so the second RLock could block forever,
deadlocking Clone whenever any other goroutine had a Put queued
between the two RLock calls.

Iterate c.contextMap directly under the single RLock instead, copying
each entry into the freshly constructed (uncontended) new context. No
behavior change for callers; the lock acquisition count drops from
two to one.

Add TestContextCloneConcurrentWriter, which fires 500 Clone calls and
500 Put calls in parallel under a 5s deadline. The test reliably
times out on the previous implementation and completes in tens of
milliseconds with the fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant