2019-02-02 16:18:25 +08:00
|
|
|
// Copyright 2018 gf Author(https://github.com/gogf/gf). All Rights Reserved.
|
2018-08-30 00:00:15 +08:00
|
|
|
//
|
|
|
|
// This Source Code Form is subject to the terms of the MIT License.
|
|
|
|
// If a copy of the MIT was not distributed with this file,
|
2019-02-02 16:18:25 +08:00
|
|
|
// You can obtain one at https://github.com/gogf/gf.
|
2018-08-30 00:00:15 +08:00
|
|
|
|
|
|
|
package gmlock
|
|
|
|
|
|
|
|
import (
|
2019-02-02 16:18:25 +08:00
|
|
|
"github.com/gogf/gf/g/container/gtype"
|
2019-01-18 11:30:52 +08:00
|
|
|
"sync"
|
2018-08-30 00:00:15 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
// 互斥锁对象
|
|
|
|
type Mutex struct {
|
|
|
|
mu sync.RWMutex
|
2018-08-30 23:21:53 +08:00
|
|
|
wid *gtype.Int64 // 当前Lock产生的唯一id(主要用于计时Unlock的校验)
|
2018-08-30 00:00:15 +08:00
|
|
|
rcount *gtype.Int // RLock次数
|
|
|
|
wcount *gtype.Int // Lock次数
|
|
|
|
}
|
|
|
|
|
|
|
|
// 创建一把内存锁使用的底层RWMutex
|
|
|
|
func NewMutex() *Mutex {
|
|
|
|
return &Mutex{
|
2018-08-30 23:21:53 +08:00
|
|
|
wid : gtype.NewInt64(),
|
2018-08-30 00:00:15 +08:00
|
|
|
rcount : gtype.NewInt(),
|
|
|
|
wcount : gtype.NewInt(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Mutex) Lock() {
|
|
|
|
l.wcount.Add(1)
|
|
|
|
l.mu.Lock()
|
2019-01-18 11:30:52 +08:00
|
|
|
l.wid.Add(1)
|
2018-08-30 00:00:15 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// 安全的Unlock
|
|
|
|
func (l *Mutex) Unlock() {
|
|
|
|
if l.wcount.Val() > 0 {
|
2018-12-30 14:53:16 +08:00
|
|
|
if l.wcount.Add(-1) >= 0 {
|
|
|
|
l.mu.Unlock()
|
2019-01-18 11:30:52 +08:00
|
|
|
} else {
|
|
|
|
// 标准库这里会panic
|
|
|
|
l.wcount.Add(1)
|
2018-12-30 14:53:16 +08:00
|
|
|
}
|
2018-08-30 00:00:15 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Mutex) RLock() {
|
|
|
|
l.rcount.Add(1)
|
|
|
|
l.mu.RLock()
|
|
|
|
}
|
|
|
|
|
|
|
|
// 安全的RUnlock
|
|
|
|
func (l *Mutex) RUnlock() {
|
|
|
|
if l.rcount.Val() > 0 {
|
2019-01-18 11:30:52 +08:00
|
|
|
if l.rcount.Add(-1) >= 0 {
|
2018-12-30 14:53:16 +08:00
|
|
|
l.mu.RUnlock()
|
2019-01-18 11:30:52 +08:00
|
|
|
} else {
|
|
|
|
// 标准库这里会panic
|
|
|
|
l.rcount.Add(1)
|
2018-12-30 14:53:16 +08:00
|
|
|
}
|
2018-08-30 00:00:15 +08:00
|
|
|
}
|
|
|
|
}
|
2018-12-30 14:53:16 +08:00
|
|
|
|
|
|
|
// 不阻塞Lock
|
|
|
|
func (l *Mutex) TryLock() bool {
|
|
|
|
// 初步读写次数检查, 但无法保证原子性
|
|
|
|
if l.wcount.Val() == 0 && l.rcount.Val() == 0 {
|
|
|
|
// 第二次检查, 保证原子操作
|
|
|
|
if l.wcount.Add(1) == 1 {
|
|
|
|
l.mu.Lock()
|
2019-01-18 11:30:52 +08:00
|
|
|
l.wid.Add(1)
|
2018-12-30 14:53:16 +08:00
|
|
|
return true
|
2019-01-18 11:30:52 +08:00
|
|
|
} else {
|
|
|
|
l.wcount.Add(-1)
|
2018-12-30 14:53:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// 不阻塞RLock
|
|
|
|
func (l *Mutex) TryRLock() bool {
|
|
|
|
// 只要不存在写锁
|
|
|
|
if l.wcount.Val() == 0 {
|
|
|
|
l.rcount.Add(1)
|
|
|
|
l.mu.RLock()
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|