mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-07-16 01:26:07 +00:00
ade3a8f870
lockInbound acquired the global registry mutex and then blocked on the per-inbound mutex without releasing the registry first. A slow client operation holding one inbound's mutex (for example a bulk delete pushing to an unreachable node) made the next waiter park on that inbound while still holding the registry mutex, which in turn blocked lockInbound for every other inbound — freezing client mutations panel-wide. Release the registry mutex before taking the per-inbound lock.
30 lines
720 B
Go
30 lines
720 B
Go
package service
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// lockInbound must not hold the global registry mutex while it waits on a busy
|
|
// inbound's own mutex, otherwise one slow client operation on a single inbound
|
|
// freezes client mutations on every other inbound panel-wide.
|
|
func TestLockInboundReleasesRegistryMutexWhileWaiting(t *testing.T) {
|
|
const id = 990006
|
|
held := lockInbound(id)
|
|
|
|
parked := make(chan struct{})
|
|
go func() {
|
|
close(parked)
|
|
lockInbound(id).Unlock()
|
|
}()
|
|
<-parked
|
|
time.Sleep(50 * time.Millisecond)
|
|
|
|
if !inboundMutationLocksMu.TryLock() {
|
|
held.Unlock()
|
|
t.Fatal("registry mutex is held while a lockInbound caller waits on a busy inbound")
|
|
}
|
|
inboundMutationLocksMu.Unlock()
|
|
held.Unlock()
|
|
}
|