Skip to content

Commit

Permalink
Merge pull request #514 from zenhack/delete-callsstopped
Browse files Browse the repository at this point in the history
promiseState: remove obsolete ongoingCalls and callsStopped fields.
  • Loading branch information
zenhack authored May 11, 2023
2 parents 3467b70 + f7e48e6 commit c434d9f
Showing 1 changed file with 8 additions and 52 deletions.
60 changes: 8 additions & 52 deletions answer.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,6 @@ type promiseState struct {
// the promise leaves the unresolved state.
caller PipelineCaller

// ongoingCalls counts the number of calls to caller that have not
// yielded an Answer yet (but not necessarily finished).
ongoingCalls int
// If callsStopped is non-nil, then the promise has entered into
// the pending state and is waiting for ongoingCalls to drop to zero.
// After decrementing ongoingCalls, callsStopped should be closed if
// ongoingCalls is zero to wake up the goroutine.
//
// Only Fulfill or Reject will set callsStopped.
callsStopped chan struct{}

// clients is a table of promised clients created to proxy the eventual
// result's clients. Even after resolution, this table may still have
// entries until the clients are released. Cannot be read or written
Expand Down Expand Up @@ -157,32 +146,19 @@ func (p *Promise) Reject(e error) {
// If e != nil, then this is equivalent to p.Reject(e).
// Otherwise, it is equivalent to p.Fulfill(r).
func (p *Promise) Resolve(r Ptr, e error) {
var (
shutdownPromises []*clientPromise

// We need to access some of these fields from p.state while
// not holding the lock, so we store them here while holding it.
// p.clients cannot be touched in the pending resolution state,
// so we have exclusive access to the variable anyway.
clients map[clientPath]*clientAndPromise
callsStopped chan struct{}
)
var shutdownPromises []*clientPromise

p.state.With(func(p *promiseState) {
// It's ok to extract p.clients and use it while not holding the lock:
// it may not be accessed in the pending resolution state, so we have
// exclusive access to the variable anyway.
clients := mutex.With1(&p.state, func(p *promiseState) map[clientPath]*clientAndPromise {
if e != nil {
p.requireUnresolved("Reject")
} else {
p.requireUnresolved("Fulfill")
}
p.caller = nil

if p.ongoingCalls > 0 {
p.callsStopped = make(chan struct{})
}

if len(p.clients) > 0 || p.ongoingCalls > 0 {
clients = p.clients
}
return p.clients
})

// Pending resolution state: wait for clients to be fulfilled
Expand All @@ -194,13 +170,9 @@ func (p *Promise) Resolve(r Ptr, e error) {
shutdownPromises = append(shutdownPromises, cp.promise)
cp.promise = nil
}
if callsStopped != nil {
<-callsStopped
}

p.state.With(func(p *promiseState) {
// Move p into resolved state.
p.callsStopped = nil
p.result, p.err = r, e
for _, f := range p.signals {
f()
Expand Down Expand Up @@ -353,17 +325,9 @@ func (ans *Answer) PipelineSend(ctx context.Context, transform []PipelineOp, s S
l := p.state.Lock()
switch {
case l.Value().isUnresolved():
l.Value().ongoingCalls++
caller := l.Value().caller
l.Unlock()
ans, release := caller.PipelineSend(ctx, transform, s)
p.state.With(func(p *promiseState) {
p.ongoingCalls--
if p.ongoingCalls == 0 && p.callsStopped != nil {
close(p.callsStopped)
}
})
return ans, release
return caller.PipelineSend(ctx, transform, s)
case l.Value().isPendingResolution():
// Block new calls until resolved.
l.Unlock()
Expand All @@ -389,17 +353,9 @@ func (ans *Answer) PipelineRecv(ctx context.Context, transform []PipelineOp, r R
l := p.state.Lock()
switch {
case l.Value().isUnresolved():
l.Value().ongoingCalls++
caller := l.Value().caller
l.Unlock()
pcall := caller.PipelineRecv(ctx, transform, r)
p.state.With(func(p *promiseState) {
p.ongoingCalls--
if p.ongoingCalls == 0 && p.callsStopped != nil {
close(p.callsStopped)
}
})
return pcall
return caller.PipelineRecv(ctx, transform, r)
case l.Value().isPendingResolution():
// Block new calls until resolved.
l.Unlock()
Expand Down

0 comments on commit c434d9f

Please sign in to comment.