Acquire acquires a token, blocking if necessary until one is available. Returns an error if the context is cancelled or the timeout expires. Always uses timer to guarantee FIFO ordering (no fast path).
(ctx context.Context, timeout time.Duration, timeoutErr error)
| 150 | // Returns an error if the context is cancelled or the timeout expires. |
| 151 | // Always uses timer to guarantee FIFO ordering (no fast path). |
| 152 | func (s *FIFOSemaphore) Acquire(ctx context.Context, timeout time.Duration, timeoutErr error) error { |
| 153 | // No fast path - always use timer to guarantee FIFO |
| 154 | timer := semTimers.Get().(*time.Timer) |
| 155 | defer semTimers.Put(timer) |
| 156 | timer.Reset(timeout) |
| 157 | |
| 158 | select { |
| 159 | case <-s.tokens: |
| 160 | if !timer.Stop() { |
| 161 | <-timer.C |
| 162 | } |
| 163 | return nil |
| 164 | case <-ctx.Done(): |
| 165 | if !timer.Stop() { |
| 166 | <-timer.C |
| 167 | } |
| 168 | return ctx.Err() |
| 169 | case <-timer.C: |
| 170 | return timeoutErr |
| 171 | } |
| 172 | } |
| 173 | |
| 174 | // AcquireBlocking acquires a token, blocking indefinitely until one is available. |
| 175 | func (s *FIFOSemaphore) AcquireBlocking() { |