87 строки
		
	
	
	
		
			1,4 КиБ
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			87 строки
		
	
	
	
		
			1,4 КиБ
		
	
	
	
		
			Go
		
	
	
	
	
	
package sync
 | 
						|
 | 
						|
import (
 | 
						|
	"internal/task"
 | 
						|
	_ "unsafe"
 | 
						|
)
 | 
						|
 | 
						|
// These mutexes assume there is only one thread of operation: no goroutines,
 | 
						|
// interrupts or anything else.
 | 
						|
 | 
						|
type Mutex struct {
 | 
						|
	locked  bool
 | 
						|
	blocked task.Stack
 | 
						|
}
 | 
						|
 | 
						|
//go:linkname scheduleTask runtime.runqueuePushBack
 | 
						|
func scheduleTask(*task.Task)
 | 
						|
 | 
						|
func (m *Mutex) Lock() {
 | 
						|
	if m.locked {
 | 
						|
		// Push self onto stack of blocked tasks, and wait to be resumed.
 | 
						|
		m.blocked.Push(task.Current())
 | 
						|
		task.Pause()
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	m.locked = true
 | 
						|
}
 | 
						|
 | 
						|
func (m *Mutex) Unlock() {
 | 
						|
	if !m.locked {
 | 
						|
		panic("sync: unlock of unlocked Mutex")
 | 
						|
	}
 | 
						|
 | 
						|
	// Wake up a blocked task, if applicable.
 | 
						|
	if t := m.blocked.Pop(); t != nil {
 | 
						|
		scheduleTask(t)
 | 
						|
	} else {
 | 
						|
		m.locked = false
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
type RWMutex struct {
 | 
						|
	m       Mutex
 | 
						|
	readers uint32
 | 
						|
}
 | 
						|
 | 
						|
func (rw *RWMutex) Lock() {
 | 
						|
	rw.m.Lock()
 | 
						|
}
 | 
						|
 | 
						|
func (rw *RWMutex) Unlock() {
 | 
						|
	rw.m.Unlock()
 | 
						|
}
 | 
						|
 | 
						|
func (rw *RWMutex) RLock() {
 | 
						|
	if rw.readers == 0 {
 | 
						|
		rw.m.Lock()
 | 
						|
	}
 | 
						|
	rw.readers++
 | 
						|
}
 | 
						|
 | 
						|
func (rw *RWMutex) RUnlock() {
 | 
						|
	if rw.readers == 0 {
 | 
						|
		panic("sync: unlock of unlocked RWMutex")
 | 
						|
	}
 | 
						|
	rw.readers--
 | 
						|
	if rw.readers == 0 {
 | 
						|
		rw.m.Unlock()
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
type Locker interface {
 | 
						|
	Lock()
 | 
						|
	Unlock()
 | 
						|
}
 | 
						|
 | 
						|
// RLocker returns a Locker interface that implements
 | 
						|
// the Lock and Unlock methods by calling rw.RLock and rw.RUnlock.
 | 
						|
func (rw *RWMutex) RLocker() Locker {
 | 
						|
	return (*rlocker)(rw)
 | 
						|
}
 | 
						|
 | 
						|
type rlocker RWMutex
 | 
						|
 | 
						|
func (r *rlocker) Lock()   { (*RWMutex)(r).RLock() }
 | 
						|
func (r *rlocker) Unlock() { (*RWMutex)(r).RUnlock() }
 |