// Add registers a socket for sending and/or receiving. The caller can't // access the socket directly after this. The send channel (if any) should be // closed by the caller. func (io *IO) Add(s *zmq.Socket, send <-chan Data, recv chan<- Data) (err error) { fd, err := s.GetFd() if err != nil { return } w := newWorker() io.lock.Lock() io.workers[int32(fd)] = w io.lock.Unlock() defer func() { if err != nil { io.lock.Lock() delete(io.workers, int32(fd)) io.lock.Unlock() } }() e := &syscall.EpollEvent{ Events: syscall.EPOLLIN | syscall.EPOLLET&0xffffffff, Fd: int32(fd), } if err = syscall.EpollCtl(io.epollFd, syscall.EPOLL_CTL_ADD, fd, e); err != nil { return } state, err := s.GetEvents() if err != nil { syscall.EpollCtl(io.epollFd, syscall.EPOLL_CTL_DEL, fd, nil) return } go func() { defer s.Close() defer syscall.EpollCtl(io.epollFd, syscall.EPOLL_CTL_DEL, fd, nil) w.socketLoop(s, send, recv, state) }() return }
// Remove closes a socket. If it has been registered, it will be removed. The // recv channel (if any) will be closed. func (io *IO) Remove(s *zmq.Socket) (err error) { fd, err := s.GetFd() if err != nil { return } io.lock.Lock() w := io.workers[int32(fd)] if w != nil { delete(io.workers, int32(fd)) } io.lock.Unlock() if w != nil { w.close() } else { err = s.Close() } return }