impl-mutex.go
func (p *process) CloseAfterChildren() error {
	p.Lock()
	select {
	case <-p.Closed():
		p.Unlock()
		return p.Close() // get error. safe, after p.Closed()
	case <-p.waiting: // already called it.
		p.Unlock()
		<-p.Closed()
		return p.Close() // get error. safe, after p.Closed()
	default:
	}
	p.Unlock()

	// here only from one goroutine.

	nextToWaitFor := func() Process {
		p.Lock()
		defer p.Unlock()
		for e, _ := range p.waitfors {
			c := e.Child()
			if c == nil {
				continue
			}

			select {
			case <-c.Closed():
			default:
				return c
			}
		}
		return nil
	}

	// wait for all processes we're waiting for are closed.
	// the semantics here are simple: we will _only_ close
	// if there are no processes currently waiting for.
	for next := nextToWaitFor(); next != nil; next = nextToWaitFor() {
		<-next.Closed()
	}

	// YAY! we're done. close
	return p.Close()
}
func (p *process) CloseAfterChildren() error {
	p.Lock()
	select {
	case <-p.Closed():
		p.Unlock()
		return p.Close() // get error. safe, after p.Closed()
	case <-p.waiting: // already called it.
		p.Unlock()
		<-p.Closed()
		return p.Close() // get error. safe, after p.Closed()
	default:
	}
	p.Unlock()

	// here only from one goroutine.

	nextToWaitFor := func() Process {
		p.Lock()
		defer p.Unlock()
		for e, _ := range p.waitfors {
			c := e.Child()
			if c == nil {
				continue
			}

			select {
			case <-c.Closed():
			default:
				return c
			}
		}
		return nil
	}

	// wait for all processes we're waiting for are closed.
	// the semantics here are simple: we will _only_ close
	// if there are no processes currently waiting for.
	for next := nextToWaitFor(); next != nil; next = nextToWaitFor() {
		<-next.Closed()
	}

	// YAY! we're done. close
	return p.Close()
}
func ( p * process ) CloseAfterChildren ( ) error { p . Lock ( ) select { case <- p . Closed ( ) : p . Unlock ( ) return p . Close ( ) // get error. safe, after p.Closed() case <- p . waiting : // already called it. p . Unlock ( ) <- p . Closed ( ) return p . Close ( ) // get error. safe, after p.Closed() default : } p . Unlock ( ) // here only from one goroutine. nextToWaitFor := func ( ) Process { p . Lock ( ) defer p . Unlock ( ) for e , _ := range p . waitfors { c := e . Child ( ) if c == nil { continue } select { case <- c . Closed ( ) : default : return c } } return nil } // wait for all processes we're waiting for are closed. // the semantics here are simple: we will _only_ close // if there are no processes currently waiting for. for next := nextToWaitFor ( ) ; next != nil ; next = nextToWaitFor ( ) { <- next . Closed ( ) } // YAY! we're done. close return p . Close ( ) }
// We will only wait on the children we have now.
// We will not wait on children added subsequently.
// this may change in the future.
We will only wait on the children we have now . We will not wait on children added subsequently . this may change in the future .