Deadlock Detection RWMutex
This Go package provides a custom implementation of RWMutex with built-in deadlock detection and timeout handling. It aims to enhance the standard sync.RWMutex by preventing deadlocks and providing useful debugging information when a deadlock situation is detected.
Features
- Deadlock Detection: Automatically detects and prevents double locking scenarios within the same goroutine, including both
Lock and RLock operations.
- Timeout Handling: Configurable lock timeout with customizable timeout handlers to notify or take action when a lock exceeds the specified duration.
- Detailed Debugging Information: Captures and reports the file and line number where the lock was last held, providing valuable insights for debugging.
- Global and Instance-Specific Configuration: Supports both global and per-instance lock timeout settings and handlers.
Usage
-
Import the Package:
import "github.com/goupdate/deadlock"
-
Initialize RWMutex:
var mutex deadlock.RWMutex
-
Lock and Unlock:
go func() {
mutex.Lock()
defer mutex.Unlock()
// Critical section
}()
-
Read Lock and Unlock:
go func() {
mutex.RLock()
defer mutex.RUnlock()
// Read-only section
}()
-
Set Global Lock Timeout and Handler:
deadlock.SetGlobalLockTimeout(time.Second*5, func(dur time.Duration, file string, line int) {
fmt.Printf("Global lock timeout: %s at %s:%d\n", dur, file, line)
})
-
Set Instance-Specific Lock Timeout and Handler:
mutex.SetLockTimeout(time.Second*2, func(dur time.Duration, file string, line int) {
fmt.Printf("Instance lock timeout: %s at %s:%d\n", dur, file, line)
})
Example
Here's a simple example demonstrating the usage of RWMutex with deadlock detection and timeout handling:
package main
import (
"fmt"
"time"
"github.com/goupdate/deadlock"
)
func main() {
var mutex deadlock.RWMutex
deadlock.SetGlobalLockTimeout(time.Second*5, func(dur time.Duration, file string, line int) {
fmt.Printf("Global lock timeout: %s at %s:%d\n", dur, file, line)
})
go func() {
mutex.Lock()
defer mutex.Unlock()
time.Sleep(time.Second * 6) // Simulate long operation
}()
time.Sleep(time.Second * 7) // Wait for timeout to trigger
}