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 }