@@ -53,17 +53,6 @@ type promiseState struct {
53
53
// the promise leaves the unresolved state.
54
54
caller PipelineCaller
55
55
56
- // ongoingCalls counts the number of calls to caller that have not
57
- // yielded an Answer yet (but not necessarily finished).
58
- ongoingCalls int
59
- // If callsStopped is non-nil, then the promise has entered into
60
- // the pending state and is waiting for ongoingCalls to drop to zero.
61
- // After decrementing ongoingCalls, callsStopped should be closed if
62
- // ongoingCalls is zero to wake up the goroutine.
63
- //
64
- // Only Fulfill or Reject will set callsStopped.
65
- callsStopped chan struct {}
66
-
67
56
// clients is a table of promised clients created to proxy the eventual
68
57
// result's clients. Even after resolution, this table may still have
69
58
// entries until the clients are released. Cannot be read or written
@@ -161,30 +150,17 @@ func (p *Promise) Resolve(r Ptr, e error) {
161
150
dq := & deferred.Queue {}
162
151
defer dq .Run ()
163
152
164
- var (
165
- // We need to access some of these fields from p.state while
166
- // not holding the lock, so we store them here while holding it.
167
- // p.clients cannot be touched in the pending resolution state,
168
- // so we have exclusive access to the variable anyway.
169
- clients map [clientPath ]* clientAndPromise
170
- callsStopped chan struct {}
171
- )
172
-
173
- p .state .With (func (p * promiseState ) {
153
+ // It's ok to extract p.clients and use it while not holding the lock:
154
+ // it may not be accessed in the pending resolution state, so we have
155
+ // exclusive access to the variable anyway.
156
+ clients := mutex .With1 (& p .state , func (p * promiseState ) map [clientPath ]* clientAndPromise {
174
157
if e != nil {
175
158
p .requireUnresolved ("Reject" )
176
159
} else {
177
160
p .requireUnresolved ("Fulfill" )
178
161
}
179
162
p .caller = nil
180
-
181
- if p .ongoingCalls > 0 {
182
- p .callsStopped = make (chan struct {})
183
- }
184
-
185
- if len (p .clients ) > 0 || p .ongoingCalls > 0 {
186
- clients = p .clients
187
- }
163
+ return p .clients
188
164
})
189
165
190
166
// Pending resolution state: wait for clients to be fulfilled
@@ -195,13 +171,9 @@ func (p *Promise) Resolve(r Ptr, e error) {
195
171
cp .promise .fulfill (dq , res .client (t ))
196
172
cp .promise = nil
197
173
}
198
- if callsStopped != nil {
199
- <- callsStopped
200
- }
201
174
202
175
p .state .With (func (p * promiseState ) {
203
176
// Move p into resolved state.
204
- p .callsStopped = nil
205
177
p .result , p .err = r , e
206
178
for _ , f := range p .signals {
207
179
f ()
@@ -351,17 +323,9 @@ func (ans *Answer) PipelineSend(ctx context.Context, transform []PipelineOp, s S
351
323
l := p .state .Lock ()
352
324
switch {
353
325
case l .Value ().isUnresolved ():
354
- l .Value ().ongoingCalls ++
355
326
caller := l .Value ().caller
356
327
l .Unlock ()
357
- ans , release := caller .PipelineSend (ctx , transform , s )
358
- p .state .With (func (p * promiseState ) {
359
- p .ongoingCalls --
360
- if p .ongoingCalls == 0 && p .callsStopped != nil {
361
- close (p .callsStopped )
362
- }
363
- })
364
- return ans , release
328
+ return caller .PipelineSend (ctx , transform , s )
365
329
case l .Value ().isPendingResolution ():
366
330
// Block new calls until resolved.
367
331
l .Unlock ()
@@ -387,17 +351,9 @@ func (ans *Answer) PipelineRecv(ctx context.Context, transform []PipelineOp, r R
387
351
l := p .state .Lock ()
388
352
switch {
389
353
case l .Value ().isUnresolved ():
390
- l .Value ().ongoingCalls ++
391
354
caller := l .Value ().caller
392
355
l .Unlock ()
393
- pcall := caller .PipelineRecv (ctx , transform , r )
394
- p .state .With (func (p * promiseState ) {
395
- p .ongoingCalls --
396
- if p .ongoingCalls == 0 && p .callsStopped != nil {
397
- close (p .callsStopped )
398
- }
399
- })
400
- return pcall
356
+ return caller .PipelineRecv (ctx , transform , r )
401
357
case l .Value ().isPendingResolution ():
402
358
// Block new calls until resolved.
403
359
l .Unlock ()
0 commit comments