text: package hcs
  
  import (
  	"context"
  	"time"
  
  	"github.com/Microsoft/hcsshim/internal/log"
  )
  
  func processAsyncHcsResult(ctx context.Context, err error, resultJSON string, callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) ([]ErrorEvent, error) {
  	events := processHcsResult(ctx, resultJSON)
  	if IsPending(err) {
  		return nil, waitForNotification(ctx, callbackNumber, expectedNotification, timeout)
  	}
  
  	return events, err
  }
  
  func waitForNotification(ctx context.Context, callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) error {
  	callbackMapLock.RLock()
  	if _, ok := callbackMap[callbackNumber]; !ok {
  		callbackMapLock.RUnlock()
  		log.G(ctx).WithField("callbackNumber", callbackNumber).Error("failed to waitForNotification: callbackNumber does not exist in callbackMap")
  		return ErrHandleClose
  	}
  	channels := callbackMap[callbackNumber].channels
  	callbackMapLock.RUnlock()
  
  	expectedChannel := channels[expectedNotification]
  	if expectedChannel == nil {
  		log.G(ctx).WithField("type", expectedNotification).Error("unknown notification type in waitForNotification")
  		return ErrInvalidNotificationType
  	}
  
  	var c <-chan time.Time
  	if timeout != nil {
  		timer := time.NewTimer(*timeout)
  		c = timer.C
  		defer timer.Stop()
  	}
  
  	select {
  	case err, ok := <-expectedChannel:
  		if !ok {
  			return ErrHandleClose
  		}
  		return err
  	case err, ok := <-channels[hcsNotificationSystemExited]:
  		if !ok {
  			return ErrHandleClose
  		}
  		// If the expected notification is hcsNotificationSystemExited which of the two selects
  		// chosen is random. Return the raw error if hcsNotificationSystemExited is expected
  		if channels[hcsNotificationSystemExited] == expectedChannel {
  			return err
  		}
  		return ErrUnexpectedContainerExit
  	case _, ok := <-channels[hcsNotificationServiceDisconnect]:
  		if !ok {
  			return ErrHandleClose
  		}
  		// hcsNotificationServiceDisconnect should never be an expected notification
  		// it does not need the same handling as hcsNotificationSystemExited
  		return ErrUnexpectedProcessAbort
  	case <-c:
  		return ErrTimeout
  	}
  	return nil
  }
  