github.com/searKing/golang/go@v1.2.117/sync/cond.go (about) 1 // Copyright 2021 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package sync 6 7 import ( 8 "context" 9 "sync" 10 "time" 11 ) 12 13 type TimeoutCond struct { 14 cond ConditionVariable 15 16 // L is held while observing or changing the condition 17 L sync.Locker 18 } 19 20 // NewTimeoutCond returns a new TimeoutCond with Locker l. 21 func NewTimeoutCond(l sync.Locker) *TimeoutCond { 22 return &TimeoutCond{L: l} 23 } 24 25 // Wait atomically unlocks c.L and suspends execution 26 // of the calling goroutine. After later resuming execution, 27 // Wait locks c.L before returning. Unlike in other systems, 28 // Wait cannot return unless awoken by Broadcast or Signal. 29 // 30 // Because c.L is not locked when Wait first resumes, the caller 31 // typically cannot assume that the condition is true when 32 // Wait returns. Instead, the caller should Wait in a loop: 33 // 34 // c.L.Lock() 35 // for !condition() { 36 // c.Wait() 37 // } 38 // ... make use of condition ... 39 // c.L.Unlock() 40 // 41 // Wait wait until notified 42 func (c *TimeoutCond) Wait() { 43 c.cond.Wait(c.L) 44 } 45 46 // WaitPred wait until notified 47 // If pred is specified (2), the function only blocks if pred returns false, 48 // and notifications can only unblock the thread when it becomes true 49 // (which is specially useful to check against spurious wake-up calls). This version (2) behaves as if implemented as: 50 // while (!pred()) wait(lck); 51 func (c *TimeoutCond) WaitPred(pred func() bool) { 52 c.cond.WaitPred(c.L, pred) 53 } 54 55 // WaitFor The execution of the current goroutine (which shall have locked lck's mutex) is blocked during rel_time, 56 // or until notified (if the latter happens first). 57 // WaitFor wait for timeout or until notified 58 // It behaves as if implemented as: 59 // return wait_until (lck, chrono::steady_clock::now() + rel_time); 60 func (c *TimeoutCond) WaitFor(timeout time.Duration) error { 61 return c.cond.WaitFor(c.L, timeout) 62 } 63 64 // WaitForPred wait for timeout or until notified 65 // If pred is nil, do as pred returns false always, 66 // If pred is specified, the function only blocks if pred returns false, 67 // and notifications can only unblock the thread when it becomes true 68 // (which is especially useful to check against spurious wake-up calls). 69 // It behaves as if implemented as: 70 // return wait_until (lck, chrono::steady_clock::now() + rel_time, std::move(pred)); 71 func (c *TimeoutCond) WaitForPred(timeout time.Duration, pred func() bool) bool { 72 return c.cond.WaitForPred(c.L, timeout, pred) 73 } 74 75 // WaitUntil wait until notified or time point 76 // The execution of the current thread (which shall have locked lck's mutex) is blocked either 77 // until notified or until abs_time, whichever happens first. 78 func (c *TimeoutCond) WaitUntil(d time.Time) error { 79 return c.cond.WaitUntil(c.L, d) 80 } 81 82 // WaitUntilPred wait until notified or time point 83 // The execution of the current thread (which shall have locked c.L's mutex) is blocked either 84 // until notified or until abs_time, whichever happens first. 85 // If pred is nil, do as pred returns false always, 86 // If pred is specified, the function only blocks if pred returns false, 87 // and notifications can only unblock the thread when it becomes true 88 // (which is especially useful to check against spurious wake-up calls). 89 // It behaves as if implemented as: 90 // while (!pred()) 91 // 92 // if ( wait_until(lck,abs_time) == cv_status::timeout) 93 // return pred(); 94 // 95 // return true; 96 func (c *TimeoutCond) WaitUntilPred(d time.Time, pred func() bool) bool { 97 return c.cond.WaitUntilPred(c.L, d, pred) 98 } 99 100 // WaitContext wait until notified or time point 101 // The execution of the current thread (which shall have locked lck's mutex) is blocked either 102 // until notified or until ctx done, whichever happens first. 103 func (c *TimeoutCond) WaitContext(ctx context.Context) error { 104 return c.cond.WaitContext(ctx, c.L) 105 } 106 107 // WaitPredContext wait until notified or ctx done 108 // The execution of the current thread (which shall have locked lck's mutex) is blocked either 109 // until notified or until ctx, whichever happens first. 110 // If pred is nil, do as pred returns false always, 111 // If pred is specified, the function only blocks if pred returns false, 112 // and notifications can only unblock the thread when it becomes true 113 // (which is especially useful to check against spurious wake-up calls). 114 // It behaves as if implemented as: 115 // while (!pred()) 116 // 117 // if ( wait_until(ctx,lck) == cv_status::timeout) 118 // return pred(); 119 // 120 // return true; 121 func (c *TimeoutCond) WaitPredContext(ctx context.Context, pred func() bool) bool { 122 return c.cond.WaitPredContext(ctx, c.L, pred) 123 } 124 125 // Signal wakes one goroutine waiting on c, if there is any. 126 // 127 // It is allowed but not required for the caller to hold c.L 128 // during the call. 129 func (c *TimeoutCond) Signal() { 130 c.cond.Signal() 131 } 132 133 // Broadcast wakes all goroutines waiting on c. 134 // 135 // It is allowed but not required for the caller to hold c.L 136 // during the call. 137 func (c *TimeoutCond) Broadcast() { 138 c.cond.Broadcast() 139 }