callback.go 2.6 KB

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