Source File
closemu.go
Belonging Package
database/sql
// Copyright 2026 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package sqlimport ()// A closingMutex is an RWMutex for synchronizing close.// Unlike a sync.RWMutex, RLock takes priority over Lock.// Reads can starve out close, but reads are safely reentrant.type closingMutex struct {// state is 2*readers+writerWaiting.// 0 is unlocked// 1 is unlocked and a writer needs to wake// >0 is read-locked// <0 is write-lockedstate atomic.Int64mu sync.Mutexread *sync.Condwrite *sync.Cond}func ( *closingMutex) () {if .TryRLock() {return}// Wait for writer..mu.Lock()defer .mu.Unlock()for {if .TryRLock() {return}.init().read.Wait()}}func ( *closingMutex) () {for {:= .state.Load()if < 2 {panic("runlock of un-rlocked mutex")}if .state.CompareAndSwap(, -2) {if -2 == 1 {// We were the last reader, and a writer is waiting.// The lock makes sure the writer sees the broadcast..mu.Lock()defer .mu.Unlock().write.Broadcast()}return}}}func ( *closingMutex) () {.mu.Lock()defer .mu.Unlock()for {:= .state.Load()if == 0 || == 1 {if .state.CompareAndSwap(, -1) {return}continue}// Set writer waiting bit and sleep.if &1 == 0 && !.state.CompareAndSwap(, |1) {continue}.init().write.Wait()}}func ( *closingMutex) () {.mu.Lock()defer .mu.Unlock()if !.state.CompareAndSwap(-1, 0) {panic("unlock of unlocked mutex")}if .read != nil {.read.Broadcast().write.Broadcast()}}func ( *closingMutex) () bool {for {:= .state.Load()// Fail if the mutex is write locked (x < 0)// or unlocked with a writer waiting (x == 1).//// If the mutex is read-locked (x > 1), try to add a reader// even if this starves out a waiting writer.if < 0 || == 1 {return false}if .state.CompareAndSwap(, +2) {return true}}}func ( *closingMutex) () {// Lazily create the read/write Conds.// In the common, uncontended case, we'll never need them.if .read == nil {.read = sync.NewCond(&.mu).write = sync.NewCond(&.mu)}}
The pages are generated with Golds v0.8.4. (GOOS=linux GOARCH=amd64)