// 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 sql

import (
	"sync"
	"sync/atomic"
)

// 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-locked
	state atomic.Int64
	mu    sync.Mutex
	read  *sync.Cond
	write *sync.Cond
}

func (m *closingMutex) RLock() {
	if m.TryRLock() {
		return
	}

	// Wait for writer.
	m.mu.Lock()
	defer m.mu.Unlock()
	for {
		if m.TryRLock() {
			return
		}
		m.init()
		m.read.Wait()
	}
}

func (m *closingMutex) RUnlock() {
	for {
		x := m.state.Load()
		if x < 2 {
			panic("runlock of un-rlocked mutex")
		}
		if m.state.CompareAndSwap(x, x-2) {
			if x-2 == 1 {
				// We were the last reader, and a writer is waiting.
				// The lock makes sure the writer sees the broadcast.
				m.mu.Lock()
				defer m.mu.Unlock()
				m.write.Broadcast()
			}
			return
		}
	}
}

func (m *closingMutex) Lock() {
	m.mu.Lock()
	defer m.mu.Unlock()
	for {
		x := m.state.Load()
		if (x == 0 || x == 1) && m.state.CompareAndSwap(x, -1) {
			return
		}
		// Set writer waiting bit and sleep.
		if x&1 == 0 && !m.state.CompareAndSwap(x, x|1) {
			continue
		}
		m.init()
		m.write.Wait()
	}
}

func (m *closingMutex) Unlock() {
	m.mu.Lock()
	defer m.mu.Unlock()
	if !m.state.CompareAndSwap(-1, 0) {
		panic("unlock of unlocked mutex")
	}
	if m.read != nil {
		m.read.Broadcast()
		m.write.Broadcast()
	}
}

func (m *closingMutex) TryRLock() bool {
	for {
		x := m.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 x < 0 || x == 1 {
			return false
		}
		if m.state.CompareAndSwap(x, x+2) {
			return true
		}
	}
}

func (m *closingMutex) init() {
	// Lazily create the read/write Conds.
	// In the common, uncontended case, we'll never need them.
	if m.read == nil {
		m.read = sync.NewCond(&m.mu)
		m.write = sync.NewCond(&m.mu)
	}
}
