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