func (m *ReadLockManager) ReadLock(ctx context.Context, fn string) *LockContext {
	retCtx, cancel := context.WithCancel(ctx)

	// if Cancellable, call Cancel() when cancelled
	cancellable, ok := ctx.(Cancellable)
	if ok {
		origCancel := cancel
		cancel = func() {
			origCancel()
			cancellable.Cancel()
		}
	}

	m.mutex.Lock()
	defer m.mutex.Unlock()

	locks := m.readLocks[fn]

	cc := &LockContext{
		Context: retCtx,
		cancel:  cancel,
	}
	m.readLocks[fn] = append(locks, cc)

	go m.waitAndUnlock(fn, cc)

	return cc
}
// ReadLock adds a pending file read lock for fn to its storage, returning a context and cancel function.
// Per standard WithCancel usage, cancel must be called when the lock is freed.
ReadLock adds a pending file read lock for fn to its storage, returning a context and cancel function.
Per standard WithCancel usage, cancel must be called when the lock is freed.
// ReadLock adds a pending file read lock for fn to its storage returning a context and cancel function . // Per standard WithCancel usage cancel must be called when the lock is freed .
func (m *ReadLockManager) ReadLock(ctx context.Context, fn string) *LockContext {
	retCtx, cancel := context.WithCancel(ctx)
	cancellable, ok := ctx.(Cancellable)
	if ok {
		origCancel := cancel
		cancel = func() {
			origCancel()
			cancellable.Cancel()
		}
	}
	m.mutex.Lock()
	defer m.mutex.Unlock()
	locks := m.readLocks[fn]
	cc := &LockContext{
		Context: retCtx,
		cancel:  cancel,
	}
	m.readLocks[fn] = append(locks, cc)
	go m.waitAndUnlock(fn, cc)
	return cc
}
func ( m * ReadLockManager ) ReadLock ( ctx context . Context , fn string ) * LockContext { retCtx , cancel := context . WithCancel ( ctx ) cancellable , ok := ctx . ( Cancellable ) if ok { origCancel := cancel cancel = func ( ) { origCancel ( ) cancellable . Cancel ( ) } } m . mutex . Lock ( ) defer m . mutex . Unlock ( ) locks := m . readLocks [ fn ] cc := & LockContext { Context : retCtx , cancel : cancel , } m . readLocks [ fn ] = append ( locks , cc ) go m . waitAndUnlock ( fn , cc ) return cc }
ReadLock adds a pending file read lock for fn to its storage, returning a context and cancel function.
ReadLock adds a pending file read lock for fn to its storage returning a context and cancel function .
// if Cancellable, call Cancel() when cancelled