Skip to content

Instantly share code, notes, and snippets.

@CAFxX
Last active December 13, 2022 02:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CAFxX/882685c450afc0f49e21cd490820b119 to your computer and use it in GitHub Desktop.
Save CAFxX/882685c450afc0f49e21cd490820b119 to your computer and use it in GitHub Desktop.
package xsync
import "sync"
type TryLocker interface {
sync.Locker // Lock(); Unlock()
TryLock() bool
}
// LockAndDo will acquire the lock l and execute fn.
// It will execute fn immediately if the lock was not locked
// when LockAndDo is called, and will execute fn in a goroutine
// otherwise.
// The lock is released once fn has completed execution.
//
// LockAndDo is mostly useful to efficiently execute short,
// non-blocking logic that must be executed protected by a lock
// that may be contended, while avoiding blocking the caller
// of LockAndDo (e.g. because the logic in the callee has lower
// priority compared to the logic executed by the caller).
func LockAndDo(l TryLocker, fn func()) {
if l.TryLock() {
defer l.Unlock()
fn()
return
}
go func() {
l.Lock()
defer l.Unlock()
fn()
}()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment