|
- package publock
-
- import (
- "time"
-
- "gitlink.org.cn/cloudream/jcs-pub/client/internal/publock/reqbuilder"
- "gitlink.org.cn/cloudream/jcs-pub/client/internal/publock/types"
- )
-
- type Reentrant struct {
- reqbuilder.LockRequestBuilder[*Reentrant]
- p *PubLock
- reqs []types.LockRequest
- locked []LockedRequest
- }
-
- func (r *Reentrant) Lock(opts ...AcquireOptionFn) error {
- var opt = types.AcquireOption{
- Timeout: time.Second * 10,
- }
- for _, fn := range opts {
- fn(&opt)
- }
-
- var willLock []types.Lock
-
- loop:
- for _, lock := range r.LockRequestBuilder.Locks {
- for _, req := range r.reqs {
- for _, locked := range req.Locks {
- if locked.Equals(lock) {
- continue loop
- }
- }
- }
-
- willLock = append(willLock, lock)
- }
- r.LockRequestBuilder.Locks = nil
-
- if len(willLock) == 0 {
- return nil
- }
-
- newReq := types.LockRequest{
- Locks: willLock,
- }
-
- m, err := r.p.Acquire(newReq, opt)
- if err != nil {
- return err
- }
-
- r.reqs = append(r.reqs, newReq)
- r.locked = append(r.locked, m)
-
- return nil
- }
-
- func (r *Reentrant) Unlock() {
- for i := len(r.reqs) - 1; i >= 0; i-- {
- r.p.Release(r.locked[i].ReqID)
- }
- r.locked = nil
- r.reqs = nil
- }
|