func runForWaitForInstancesSignal()

in step_wait_for_instances_signal.go [349:418]


func runForWaitForInstancesSignal(w *[]*InstanceSignal, s *Step, waitAll bool) DError {
	var wg sync.WaitGroup
	e := make(chan DError)
	for _, is := range *w {
		wg.Add(1)
		go func(is *InstanceSignal) {
			defer wg.Done()
			i, ok := s.w.instances.get(is.Name)
			if !ok {
				e <- Errf("unresolved instance %q", is.Name)
				return
			}
			m := NamedSubexp(instanceURLRgx, i.link)
			serialSig := make(chan struct{})
			guestSig := make(chan struct{})
			statusSig := make(chan struct{})
			if is.Stopped {
				go func() {
					if err := waitForInstanceStopped(s, m["project"], m["zone"], m["instance"], is.interval); err != nil {
						e <- err
					}
					close(statusSig)
				}()
			} else if len(is.Status) > 0 {
				go func() {
					if err := waitForInstanceStatus(s, m["project"], m["zone"], m["instance"], is.interval, is.Status); err != nil {
						e <- err
					}
					close(statusSig)
				}()
			}
			if is.SerialOutput != nil {
				go func() {
					if err := waitForSerialOutput(s, m["project"], m["zone"], m["instance"], is.SerialOutput, is.interval); err != nil || !waitAll {
						// send a signal to end other waiting instances
						e <- err
					}
					close(serialSig)
				}()
			}
			if is.GuestAttribute != nil {
				go func() {
					if err := waitForGuestAttribute(s, m["project"], m["zone"], m["instance"], is.GuestAttribute, is.interval); err != nil || !waitAll {
						// send a signal to end other waiting instances
						e <- err
					}
					close(guestSig)
				}()
			}
			select {
			case <-guestSig:
				return
			case <-serialSig:
				return
			case <-statusSig:
				return
			}
		}(is)
	}
	go func() {
		wg.Wait()
		e <- nil
	}()
	select {
	case err := <-e:
		return err
	case <-s.w.Cancel:
		return nil
	}
}