12 int portAssociate(int port, int fd) {
13 if (port_associate(port, PORT_SOURCE_FD, fd, POLLIN | POLLHUP, NULL) < 0) {
18 port_event_t* getEvent(int e_fd) {
20 ev = (port_event_t *)malloc(sizeof(port_event_t));
21 if (port_get(e_fd, ev, NULL) < 0) {
27 int getFd(uintptr_t x) {
31 void freeEvent( port_event_t *ev){
40 "github.com/Sirupsen/logrus"
41 "github.com/containerd/containerd/runtime"
44 // NewMonitor starts a new process monitor and returns it
45 func NewMonitor() (*Monitor, error) {
47 receivers: make(map[int]interface{}),
48 exits: make(chan runtime.Process, 1024),
49 ooms: make(chan string, 1024),
51 fd, err := C.port_create()
61 // Monitor represents a runtime.Process monitor
64 receivers map[int]interface{}
65 exits chan runtime.Process
70 // Exits returns the channel used to notify of a process exit
71 func (m *Monitor) Exits() chan runtime.Process {
75 // OOMs returns the channel used to notify of a container exit due to OOM
76 func (m *Monitor) OOMs() chan string {
80 // Monitor adds a process to the list of the one being monitored
81 func (m *Monitor) Monitor(p runtime.Process) error {
85 if _, err := C.port_associate(C.int(m.epollFd), C.PORT_SOURCE_FD, C.uintptr_t(fd), C.POLLIN|C.POLLHUP, unsafe.Pointer(&fd)); err != nil {
93 // MonitorOOM adds a container to the list of the ones monitored for OOM
94 // There is no OOM-Killer on Solaris therefore nothing to setup
95 func (m *Monitor) MonitorOOM(c runtime.Container) error {
99 // Close cleans up resources allocated by NewMonitor()
100 func (m *Monitor) Close() error {
101 _, err := C.close(C.int(m.epollFd))
105 func (m *Monitor) start() {
107 ev := C.getEvent(C.int(m.epollFd))
111 fd := int(C.getFd(C.uintptr_t(uintptr((ev.portev_user)))))
114 logrus.Warnf("containerd: epoll wait")
119 switch t := r.(type) {
120 case runtime.Process:
121 if ev.portev_events == C.POLLHUP {
122 delete(m.receivers, fd)
123 if err := t.Close(); err != nil {
124 logrus.Warnf("containerd: close process IO")
126 EpollFdCounter.Dec(1)
130 // always flush the event fd
133 delete(m.receivers, fd)
134 // epoll will remove the fd from its set after it has been closed
136 EpollFdCounter.Dec(1)
138 m.ooms <- t.ContainerID()