mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 00:42:24 -05:00 
			
		
		
		
	
		
			
	
	
		
			106 lines
		
	
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			106 lines
		
	
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
|  | package mutexes | ||
|  | 
 | ||
|  | import ( | ||
|  | 	"sync" | ||
|  | ) | ||
|  | 
 | ||
|  | // Mutex defines a wrappable mutex. By forcing unlocks | ||
|  | // via returned function it makes wrapping much easier | ||
|  | type Mutex interface { | ||
|  | 	// Lock performs a mutex lock, returning an unlock function | ||
|  | 	Lock() (unlock func()) | ||
|  | } | ||
|  | 
 | ||
|  | // RWMutex defines a wrappable read-write mutex. By forcing | ||
|  | // unlocks via returned functions it makes wrapping much easier | ||
|  | type RWMutex interface { | ||
|  | 	Mutex | ||
|  | 
 | ||
|  | 	// RLock performs a mutex read lock, returning an unlock function | ||
|  | 	RLock() (runlock func()) | ||
|  | } | ||
|  | 
 | ||
|  | // New returns a new base Mutex implementation | ||
|  | func New() Mutex { | ||
|  | 	return &baseMutex{} | ||
|  | } | ||
|  | 
 | ||
|  | // NewRW returns a new base RWMutex implementation | ||
|  | func NewRW() RWMutex { | ||
|  | 	return &baseRWMutex{} | ||
|  | } | ||
|  | 
 | ||
|  | // WithFunc wraps the supplied Mutex to call the provided hooks on lock / unlock | ||
|  | func WithFunc(mu Mutex, onLock, onUnlock func()) Mutex { | ||
|  | 	return &fnMutex{mu: mu, lo: onLock, un: onUnlock} | ||
|  | } | ||
|  | 
 | ||
|  | // WithFuncRW wrapps the supplied RWMutex to call the provided hooks on lock / rlock / unlock/ runlock | ||
|  | func WithFuncRW(mu RWMutex, onLock, onRLock, onUnlock, onRUnlock func()) RWMutex { | ||
|  | 	return &fnRWMutex{mu: mu, lo: onLock, rlo: onRLock, un: onUnlock, run: onRUnlock} | ||
|  | } | ||
|  | 
 | ||
|  | // baseMutex simply wraps a sync.Mutex to implement our Mutex interface | ||
|  | type baseMutex struct{ mu sync.Mutex } | ||
|  | 
 | ||
|  | func (mu *baseMutex) Lock() func() { | ||
|  | 	mu.mu.Lock() | ||
|  | 	return mu.mu.Unlock | ||
|  | } | ||
|  | 
 | ||
|  | // baseRWMutex simply wraps a sync.RWMutex to implement our RWMutex interface | ||
|  | type baseRWMutex struct{ mu sync.RWMutex } | ||
|  | 
 | ||
|  | func (mu *baseRWMutex) Lock() func() { | ||
|  | 	mu.mu.Lock() | ||
|  | 	return mu.mu.Unlock | ||
|  | } | ||
|  | 
 | ||
|  | func (mu *baseRWMutex) RLock() func() { | ||
|  | 	mu.mu.RLock() | ||
|  | 	return mu.mu.RUnlock | ||
|  | } | ||
|  | 
 | ||
|  | // fnMutex wraps a Mutex to add hooks for Lock and Unlock | ||
|  | type fnMutex struct { | ||
|  | 	mu Mutex | ||
|  | 	lo func() | ||
|  | 	un func() | ||
|  | } | ||
|  | 
 | ||
|  | func (mu *fnMutex) Lock() func() { | ||
|  | 	unlock := mu.mu.Lock() | ||
|  | 	mu.lo() | ||
|  | 	return func() { | ||
|  | 		mu.un() | ||
|  | 		unlock() | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | // fnRWMutex wraps a RWMutex to add hooks for Lock, RLock, Unlock and RUnlock | ||
|  | type fnRWMutex struct { | ||
|  | 	mu  RWMutex | ||
|  | 	lo  func() | ||
|  | 	rlo func() | ||
|  | 	un  func() | ||
|  | 	run func() | ||
|  | } | ||
|  | 
 | ||
|  | func (mu *fnRWMutex) Lock() func() { | ||
|  | 	unlock := mu.mu.Lock() | ||
|  | 	mu.lo() | ||
|  | 	return func() { | ||
|  | 		mu.un() | ||
|  | 		unlock() | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func (mu *fnRWMutex) RLock() func() { | ||
|  | 	unlock := mu.mu.RLock() | ||
|  | 	mu.rlo() | ||
|  | 	return func() { | ||
|  | 		mu.run() | ||
|  | 		unlock() | ||
|  | 	} | ||
|  | } |