waithelper.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. package hcs
  2. import (
  3. "time"
  4. "github.com/sirupsen/logrus"
  5. )
  6. func processAsyncHcsResult(err error, resultp *uint16, callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) ([]ErrorEvent, error) {
  7. events := processHcsResult(resultp)
  8. if IsPending(err) {
  9. return nil, waitForNotification(callbackNumber, expectedNotification, timeout)
  10. }
  11. return events, err
  12. }
  13. func waitForNotification(callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) error {
  14. callbackMapLock.RLock()
  15. channels := callbackMap[callbackNumber].channels
  16. callbackMapLock.RUnlock()
  17. expectedChannel := channels[expectedNotification]
  18. if expectedChannel == nil {
  19. logrus.Errorf("unknown notification type in waitForNotification %x", expectedNotification)
  20. return ErrInvalidNotificationType
  21. }
  22. var c <-chan time.Time
  23. if timeout != nil {
  24. timer := time.NewTimer(*timeout)
  25. c = timer.C
  26. defer timer.Stop()
  27. }
  28. select {
  29. case err, ok := <-expectedChannel:
  30. if !ok {
  31. return ErrHandleClose
  32. }
  33. return err
  34. case err, ok := <-channels[hcsNotificationSystemExited]:
  35. if !ok {
  36. return ErrHandleClose
  37. }
  38. // If the expected notification is hcsNotificationSystemExited which of the two selects
  39. // chosen is random. Return the raw error if hcsNotificationSystemExited is expected
  40. if channels[hcsNotificationSystemExited] == expectedChannel {
  41. return err
  42. }
  43. return ErrUnexpectedContainerExit
  44. case _, ok := <-channels[hcsNotificationServiceDisconnect]:
  45. if !ok {
  46. return ErrHandleClose
  47. }
  48. // hcsNotificationServiceDisconnect should never be an expected notification
  49. // it does not need the same handling as hcsNotificationSystemExited
  50. return ErrUnexpectedProcessAbort
  51. case <-c:
  52. return ErrTimeout
  53. }
  54. return nil
  55. }