callback.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package hcs
  2. import (
  3. "sync"
  4. "syscall"
  5. "github.com/Microsoft/hcsshim/internal/interop"
  6. )
  7. var (
  8. nextCallback uintptr
  9. callbackMap = map[uintptr]*notifcationWatcherContext{}
  10. callbackMapLock = sync.RWMutex{}
  11. notificationWatcherCallback = syscall.NewCallback(notificationWatcher)
  12. // Notifications for HCS_SYSTEM handles
  13. hcsNotificationSystemExited hcsNotification = 0x00000001
  14. hcsNotificationSystemCreateCompleted hcsNotification = 0x00000002
  15. hcsNotificationSystemStartCompleted hcsNotification = 0x00000003
  16. hcsNotificationSystemPauseCompleted hcsNotification = 0x00000004
  17. hcsNotificationSystemResumeCompleted hcsNotification = 0x00000005
  18. // Notifications for HCS_PROCESS handles
  19. hcsNotificationProcessExited hcsNotification = 0x00010000
  20. // Common notifications
  21. hcsNotificationInvalid hcsNotification = 0x00000000
  22. hcsNotificationServiceDisconnect hcsNotification = 0x01000000
  23. )
  24. type hcsNotification uint32
  25. type notificationChannel chan error
  26. type notifcationWatcherContext struct {
  27. channels notificationChannels
  28. handle hcsCallback
  29. }
  30. type notificationChannels map[hcsNotification]notificationChannel
  31. func newChannels() notificationChannels {
  32. channels := make(notificationChannels)
  33. channels[hcsNotificationSystemExited] = make(notificationChannel, 1)
  34. channels[hcsNotificationSystemCreateCompleted] = make(notificationChannel, 1)
  35. channels[hcsNotificationSystemStartCompleted] = make(notificationChannel, 1)
  36. channels[hcsNotificationSystemPauseCompleted] = make(notificationChannel, 1)
  37. channels[hcsNotificationSystemResumeCompleted] = make(notificationChannel, 1)
  38. channels[hcsNotificationProcessExited] = make(notificationChannel, 1)
  39. channels[hcsNotificationServiceDisconnect] = make(notificationChannel, 1)
  40. return channels
  41. }
  42. func closeChannels(channels notificationChannels) {
  43. close(channels[hcsNotificationSystemExited])
  44. close(channels[hcsNotificationSystemCreateCompleted])
  45. close(channels[hcsNotificationSystemStartCompleted])
  46. close(channels[hcsNotificationSystemPauseCompleted])
  47. close(channels[hcsNotificationSystemResumeCompleted])
  48. close(channels[hcsNotificationProcessExited])
  49. close(channels[hcsNotificationServiceDisconnect])
  50. }
  51. func notificationWatcher(notificationType hcsNotification, callbackNumber uintptr, notificationStatus uintptr, notificationData *uint16) uintptr {
  52. var result error
  53. if int32(notificationStatus) < 0 {
  54. result = interop.Win32FromHresult(notificationStatus)
  55. }
  56. callbackMapLock.RLock()
  57. context := callbackMap[callbackNumber]
  58. callbackMapLock.RUnlock()
  59. if context == nil {
  60. return 0
  61. }
  62. context.channels[notificationType] <- result
  63. return 0
  64. }