...

Source file src/github.com/Microsoft/hcsshim/internal/hcs/waithelper.go

Documentation: github.com/Microsoft/hcsshim/internal/hcs

     1  //go:build windows
     2  
     3  package hcs
     4  
     5  import (
     6  	"context"
     7  	"time"
     8  
     9  	"github.com/Microsoft/hcsshim/internal/log"
    10  )
    11  
    12  func processAsyncHcsResult(
    13  	ctx context.Context,
    14  	err error,
    15  	resultJSON string,
    16  	callbackNumber uintptr,
    17  	expectedNotification hcsNotification,
    18  	timeout *time.Duration,
    19  ) ([]ErrorEvent, error) {
    20  	events := processHcsResult(ctx, resultJSON)
    21  	if IsPending(err) {
    22  		return nil, waitForNotification(ctx, callbackNumber, expectedNotification, timeout)
    23  	}
    24  
    25  	return events, err
    26  }
    27  
    28  func waitForNotification(
    29  	ctx context.Context,
    30  	callbackNumber uintptr,
    31  	expectedNotification hcsNotification,
    32  	timeout *time.Duration,
    33  ) error {
    34  	callbackMapLock.RLock()
    35  	if _, ok := callbackMap[callbackNumber]; !ok {
    36  		callbackMapLock.RUnlock()
    37  		log.G(ctx).WithField("callbackNumber", callbackNumber).Error("failed to waitForNotification: callbackNumber does not exist in callbackMap")
    38  		return ErrHandleClose
    39  	}
    40  	channels := callbackMap[callbackNumber].channels
    41  	callbackMapLock.RUnlock()
    42  
    43  	expectedChannel := channels[expectedNotification]
    44  	if expectedChannel == nil {
    45  		log.G(ctx).WithField("type", expectedNotification).Error("unknown notification type in waitForNotification")
    46  		return ErrInvalidNotificationType
    47  	}
    48  
    49  	var c <-chan time.Time
    50  	if timeout != nil {
    51  		timer := time.NewTimer(*timeout)
    52  		c = timer.C
    53  		defer timer.Stop()
    54  	}
    55  
    56  	select {
    57  	case err, ok := <-expectedChannel:
    58  		if !ok {
    59  			return ErrHandleClose
    60  		}
    61  		return err
    62  	case err, ok := <-channels[hcsNotificationSystemExited]:
    63  		if !ok {
    64  			return ErrHandleClose
    65  		}
    66  		// If the expected notification is hcsNotificationSystemExited which of the two selects
    67  		// chosen is random. Return the raw error if hcsNotificationSystemExited is expected
    68  		if channels[hcsNotificationSystemExited] == expectedChannel {
    69  			return err
    70  		}
    71  		return ErrUnexpectedContainerExit
    72  	case _, ok := <-channels[hcsNotificationServiceDisconnect]:
    73  		if !ok {
    74  			return ErrHandleClose
    75  		}
    76  		// hcsNotificationServiceDisconnect should never be an expected notification
    77  		// it does not need the same handling as hcsNotificationSystemExited
    78  		return ErrUnexpectedProcessAbort
    79  	case <-c:
    80  		return ErrTimeout
    81  	}
    82  }
    83  

View as plain text