diff options
| author | Brad Fitzpatrick <bradfitz@tailscale.com> | 2025-12-02 12:50:33 -0800 |
|---|---|---|
| committer | Brad Fitzpatrick <bradfitz@tailscale.com> | 2025-12-02 15:12:13 -0800 |
| commit | 381de776c4878dd9af76b126cfa37bc80cad363f (patch) | |
| tree | c3ddcbf9613db3074c9c6882bb757357cf5bdd0a /util/execqueue/execqueue.go | |
| parent | b8c58ca7c1a49fb772d095c65693cdab06488047 (diff) | |
| download | tailscale-bradfitz/mutex_debug.tar.xz tailscale-bradfitz/mutex_debug.zip | |
syncs: start working on mutex debugging, registrationbradfitz/mutex_debug
Updates #17852
Change-Id: Ib1b634eedd30cc4006bc1b39aa8d479d37c5f1f2
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Diffstat (limited to 'util/execqueue/execqueue.go')
| -rw-r--r-- | util/execqueue/execqueue.go | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/util/execqueue/execqueue.go b/util/execqueue/execqueue.go index 87616a6b5..acf25f645 100644 --- a/util/execqueue/execqueue.go +++ b/util/execqueue/execqueue.go @@ -7,11 +7,14 @@ package execqueue import ( "context" "errors" + "sync" "tailscale.com/syncs" ) type ExecQueue struct { + regMutexOnce sync.Once + mu syncs.Mutex ctx context.Context // context.Background + closed on Shutdown cancel context.CancelFunc // closes ctx @@ -21,7 +24,13 @@ type ExecQueue struct { queue []func() } +func (q *ExecQueue) registerMutex() { + syncs.RegisterMutex(&q.mu, "execqueue.ExecQueue.mu") +} + func (q *ExecQueue) Add(f func()) { + q.regMutexOnce.Do(q.registerMutex) + q.mu.Lock() defer q.mu.Unlock() if q.closed { @@ -39,6 +48,8 @@ func (q *ExecQueue) Add(f func()) { // RunSync waits for the queue to be drained and then synchronously runs f. // It returns an error if the queue is closed before f is run or ctx expires. func (q *ExecQueue) RunSync(ctx context.Context, f func()) error { + q.regMutexOnce.Do(q.registerMutex) + q.mu.Lock() q.initCtxLocked() shutdownCtx := q.ctx @@ -80,6 +91,8 @@ func (q *ExecQueue) run(f func()) { // Shutdown asynchronously signals the queue to stop. func (q *ExecQueue) Shutdown() { + q.regMutexOnce.Do(q.registerMutex) + q.mu.Lock() defer q.mu.Unlock() q.closed = true @@ -98,6 +111,8 @@ var errExecQueueShutdown = errors.New("execqueue shut down") // Wait waits for the queue to be empty or shut down. func (q *ExecQueue) Wait(ctx context.Context) error { + q.regMutexOnce.Do(q.registerMutex) + q.mu.Lock() q.initCtxLocked() waitCh := q.doneWaiter |
