// Background task, must call waitg.Done() once at end
543348
func pruneTaskGetRetainedUnpushed(gitscanner *lfs.GitScanner, fetchconf lfs.FetchPruneConfig, retainChan chan string, errorChan chan error, waitg *sync.WaitGroup, sem *semaphore.Weighted) {
	defer waitg.Done()

	err := gitscanner.ScanUnpushed(fetchconf.PruneRemoteName, func(p *lfs.WrappedPointer, err error) {
		if err != nil {
			errorChan <- err
		} else {
			retainChan <- p.Pointer.Oid
			tracerx.Printf("RETAIN: %v unpushed", p.Pointer.Oid)
		}
	})

	if err != nil {
		errorChan <- err
		return
	}
}
644584
func NewBackgroundTask(g *libkb.GlobalContext, args *BackgroundTaskArgs) *BackgroundTask {
	return &BackgroundTask{
		Contextified: libkb.NewContextified(g),
		args:         args,
		shutdownFunc: nil,
	}
}
526517
func (s *DeleteByQueryService) DoAsync(ctx context.Context) (*StartTaskResult, error) {
	// Check pre-conditions
	if err := s.Validate(); err != nil {
		return nil, err
	}

	// DoAsync only makes sense with WaitForCompletion set to true
	if s.waitForCompletion != nil && *s.waitForCompletion {
		return nil, fmt.Errorf("cannot start a task with WaitForCompletion set to true")
	}
	f := false
	s.waitForCompletion = &f

	// Get URL for request
	path, params, err := s.buildURL()
	if err != nil {
		return nil, err
	}

	// Set body if there is a query set
	var body interface{}
	if s.body != nil {
		body = s.body
	} else if s.query != nil {
		src, err := s.query.Source()
		if err != nil {
			return nil, err
		}
		body = map[string]interface{}{
			"query": src,
		}
	}

	// Get HTTP response
	res, err := s.client.PerformRequest(ctx, PerformRequestOptions{
		Method: "POST",
		Path:   path,
		Params: params,
		Body:   body,
	})
	if err != nil {
		return nil, err
	}

	// Return operation response
	ret := new(StartTaskResult)
	if err := s.client.decoder.Decode(res.Body, ret); err != nil {
		return nil, err
	}
	return ret, nil
}
1245979
func (task *UDPListenerTask) Start(wg *sync.WaitGroup) StopChan {
	return task.ExtendedStart(nil, wg)
}
80801
func (c *EMR) WaitUntilClusterRunning(input *DescribeClusterInput) error {
	return c.WaitUntilClusterRunningWithContext(aws.BackgroundContext(), input)
}
1037100
func (t *ActivatedTask) Finish(resultJSON string, expire ...time.Time) {
	req := &dm.FinishAttemptReq{
		Auth: t.Auth,
		Data: dm.NewJsonResult(resultJSON),
	}
	switch len(expire) {
	case 0:
	case 1:
		req.Data.Expiration = googlepb.NewTimestamp(expire[0])
	default:
		panic("may only specify 0 or 1 expire values")
	}

	_, err := t.s.FinishAttempt(t.c, req)
	panicIf(err)
}
623647
func (c *CloudFormation) WaitUntilStackDeleteComplete(input *DescribeStacksInput) error {
	return c.WaitUntilStackDeleteCompleteWithContext(aws.BackgroundContext(), input)
}
1195217
func (_class TaskClass) GetFinished(sessionID SessionRef, self TaskRef) (_retval time.Time, _err error) {
	_method := "task.get_finished"
	_sessionIDArg, _err := convertSessionRefToXen(fmt.Sprintf("%s(%s)", _method, "session_id"), sessionID)
	if _err != nil {
		return
	}
	_selfArg, _err := convertTaskRefToXen(fmt.Sprintf("%s(%s)", _method, "self"), self)
	if _err != nil {
		return
	}
	_result, _err := _class.client.APICall(_method, _sessionIDArg, _selfArg)
	if _err != nil {
		return
	}
	_retval, _err = convertTimeToGo(_method + " -> ", _result.Value)
	return
}
367314
func TaskWaitC(ctx types.Context, taskID int) <-chan int {
	return getTaskService(ctx).TaskWaitC(taskID)
}
374414
func (t *Task) Wait(ctx context.Context) (*runtime.Exit, error) {
	r, err := t.shim.Wait(ctx, &shim.WaitRequest{
		ID: t.id,
	})
	if err != nil {
		return nil, err
	}
	return &runtime.Exit{
		Timestamp: r.ExitedAt,
		Status:    r.ExitStatus,
	}, nil
}
37496
func (s *service) Wait(ctx context.Context, r *taskAPI.WaitRequest) (*taskAPI.WaitResponse, error) {
	log.G(ctx).Debugf("Wait: %s: %s", r.ID, r.ExecID)

	var p *process
	var err error
	if p, err = s.getProcess(r.ID, r.ExecID); err != nil {
		return nil, err
	}
	pe := p.wait()
	return &taskAPI.WaitResponse{
		ExitedAt:   pe.exitedAt,
		ExitStatus: pe.exitStatus,
	}, nil
}
108168
func (rwg *RepeatedWaitGroup) WaitUnlessPaused(ctx context.Context) (
	bool, error) {
	paused, isIdleCh, pauseCh := func() (bool, chan struct{}, chan struct{}) {
		rwg.lock.Lock()
		defer rwg.lock.Unlock()
		if !rwg.paused && rwg.pauseCh == nil {
			rwg.pauseCh = make(chan struct{})
		}
		return rwg.paused, rwg.isIdleCh, rwg.pauseCh
	}()

	if isIdleCh == nil {
		return false, nil
	}

	if paused {
		return true, nil
	}

	select {
	case <-isIdleCh:
		return false, nil
	case <-pauseCh:
		return true, nil
	case <-ctx.Done():
		return false, ctx.Err()
	}
}
282710
func (o *WaitOptions) RunWait() error {
	visitCount := 0
	err := o.ResourceFinder.Do().Visit(func(info *resource.Info, err error) error {
		if err != nil {
			return err
		}

		visitCount++
		finalObject, success, err := o.ConditionFn(info, o)
		if success {
			o.Printer.PrintObj(finalObject, o.Out)
			return nil
		}
		if err == nil {
			return fmt.Errorf("%v unsatisified for unknown reason", finalObject)
		}
		return err
	})
	if err != nil {
		return err
	}
	if visitCount == 0 {
		return errNoMatchingResources
	}
	return err
}
787193
func (s *ExtensionManagerServer) waitStarted() {
	for {
		s.mutex.Lock()
		started := s.started
		s.mutex.Unlock()
		if started {
			time.Sleep(10 * time.Millisecond)
			break
		}
	}
}
884699
func (api *TasksAPI) WaitTimeout(id string, timeout time.Duration) (task *Task, err error) {
	start := time.Now()
	numErrors := 0
	maxErrors := api.client.options.TaskRetryCount

	for time.Since(start) < timeout {
		task, err = api.Get(id)
		if err != nil {
			switch err.(type) {
			// If an ApiError comes back, something is wrong, return the error to the caller
			case ApiError:
				return
			// For other errors, retry before giving up
			default:
				numErrors++
				if numErrors > maxErrors {
					return
				}
			}
		} else {
			// Reset the error count any time a successful call is made
			numErrors = 0
			if task.State == "COMPLETED" {
				return
			}
			if task.State == "ERROR" {
				err = TaskError{task.ID, getFailedStep(task)}
				return
			}
		}
		time.Sleep(api.client.options.TaskPollDelay)
	}
	err = TaskTimeoutError{id}
	return
}
1129550
func (c *SpentnessNotificationsClient) Done() {
	go func() {
		// Drain notifications until the client channel is removed from
		// the server and closed.
		for range c.C {
		}
	}()
	go func() {
		s := c.server
		s.mu.Lock()
		clients := s.spentness[c.account]
		for i, ch := range clients {
			if c.C == ch {
				clients[i] = clients[len(clients)-1]
				s.spentness[c.account] = clients[:len(clients)-1]
				close(ch)
				break
			}
		}
		s.mu.Unlock()
	}()
}
359909
func (p *asyncRunPromise) followQuery(wg *sync.WaitGroup) {
	defer wg.Done()
	// Always need to call Done after query is finished.
	defer p.q.Done()

	select {
	case <-p.ready:
		// The promise was finished somewhere else, so we don't need to call p.finish.
		// But we do need to cancel the flux. This could be a no-op.
		p.q.Cancel()
	case results, ok := <-p.q.Ready():
		if !ok {
			// Something went wrong with the flux. Set the error in the run result.
			rr := &runResult{err: p.q.Err()}
			p.finish(rr, nil)
			return
		}

		// Exhaust the results so we don't leave unfinished iterators around.
		var wg sync.WaitGroup
		wg.Add(len(results))
		for _, res := range results {
			r := res
			go func() {
				defer wg.Done()
				if err := exhaustResultIterators(r); err != nil {
					p.logger.Info("Error exhausting result iterator", zap.Error(err), zap.String("name", r.Name()))
				}
			}()
		}
		wg.Wait()

		// Otherwise, query was successful.
		// TODO(mr): collect query statistics, once RunResult interface supports them?
		p.finish(new(runResult), nil)
	}
}