func (gpio *GPIO) AddEdgeDetect(edge GPIOEdge) (chan bool, error) { gpio.RemoveEdgeDetect() err := gpio.SetDirection(GPIO_INPUT) if err != nil { return nil, err } err = gpio.SetEdge(edge) if err != nil { return nil, err } err = gpio.openValueFile() if err != nil { return nil, err } epfd, err := syscall.EpollCreate(1) if err != nil { return nil, err } event := &syscall.EpollEvent{ Events: syscall.EPOLLIN | _EPOLLET | syscall.EPOLLPRI, Fd: int32(gpio.value.Fd()), } err = syscall.EpollCtl(epfd, syscall.EPOLL_CTL_ADD, int(gpio.value.Fd()), event) if err != nil { syscall.Close(epfd) return nil, err } // / first time triggers with current state, so ignore _, err = syscall.EpollWait(epfd, make([]syscall.EpollEvent, 1), -1) if err != nil { syscall.Close(epfd) return nil, err } gpio.epfd.Set(epfd) valueChan := make(chan bool) go func() { for gpio.epfd.Get() != 0 { n, _ := syscall.EpollWait(epfd, make([]syscall.EpollEvent, 1), -1) if n > 0 { value, err := gpio.Value() if err == nil { valueChan <- value } } } }() return valueChan, nil }
func newpollster() (p *pollster, err os.Error) { p = new(pollster) var e int // The arg to epoll_create is a hint to the kernel // about the number of FDs we will care about. // We don't know. if p.epfd, e = syscall.EpollCreate(16); e != 0 { return nil, os.NewSyscallError("epoll_create", e) } p.events = make(map[int]uint32) return p, nil }
// epollinit opens an epoll file descriptor and creates a pipe which will be // used to wake up the epoll_wait(2) function. Then, file descriptor associated // with inotify event queue and the read end of the pipe are added to epoll set. // Note that `fd` member must be set before this function is called. func (i *inotify) epollinit() (err error) { if i.epfd, err = syscall.EpollCreate(2); err != nil { return } if err = syscall.Pipe(i.pipefd); err != nil { return } i.epes = []syscall.EpollEvent{ {Events: syscall.EPOLLIN, Fd: i.fd}, {Events: syscall.EPOLLIN, Fd: int32(i.pipefd[0])}, } if err = syscall.EpollCtl(i.epfd, syscall.EPOLL_CTL_ADD, int(i.fd), &i.epes[0]); err != nil { return } return syscall.EpollCtl(i.epfd, syscall.EPOLL_CTL_ADD, i.pipefd[0], &i.epes[1]) }
func newpollster() (p *pollster, err error) { p = new(pollster) if p.epfd, err = syscall.EpollCreate1(syscall.EPOLL_CLOEXEC); err != nil { if err != syscall.ENOSYS { return nil, os.NewSyscallError("epoll_create1", err) } // The arg to epoll_create is a hint to the kernel // about the number of FDs we will care about. // We don't know, and since 2.6.8 the kernel ignores it anyhow. if p.epfd, err = syscall.EpollCreate(16); err != nil { return nil, os.NewSyscallError("epoll_create", err) } syscall.CloseOnExec(p.epfd) } p.events = make(map[int]uint32) return p, nil }
func Run(t *Tunnel) { var err error epollFd, err = syscall.EpollCreate(1024) if err != nil { logger.Log(logger.ERR, "Create epoll fd error [%s]", err) os.Exit(-2) } for _, step := range initStep { err = step.Action(t) if err != nil { fmt.Fprintf(os.Stderr, step.ErrFmt, err) os.Exit(-2) } } runTunnel = t events := make([]syscall.EpollEvent, 10, 10) for { en, err := syscall.EpollWait(epollFd, events, 1000) if err != nil { logger.Log(logger.ERR, "Wail epoll fd error [%s]", err) os.Exit(-2) } for i := 0; i < en; i++ { ee := events[i] if runTunnel.LFd == int(ee.Fd) { runTunnel.newConn() continue } tc, ok := fdTunnelConn[int(ee.Fd)] if !ok { continue } if ee.Events&syscall.EPOLLIN != 0 { tc.handleIn(int(ee.Fd)) } if ee.Events&syscall.EPOLLOUT != 0 { tc.handleOut(int(ee.Fd)) } if ee.Events&syscall.EPOLLHUP != 0 { tc.shutdown() } } } }
// Create a new inotify poller. // This creates an inotify handler, and an epoll handler. func newFdPoller(fd int) (*fdPoller, error) { var errno error poller := emptyPoller(fd) defer func() { if errno != nil { poller.close() } }() poller.fd = fd // Create epoll fd poller.epfd, errno = syscall.EpollCreate(1) if poller.epfd == -1 { return nil, errno } // Create pipe; pipe[0] is the read end, pipe[1] the write end. errno = syscall.Pipe2(poller.pipe[:], syscall.O_NONBLOCK) if errno != nil { return nil, errno } // Register inotify fd with epoll event := syscall.EpollEvent{ Fd: int32(poller.fd), Events: syscall.EPOLLIN, } errno = syscall.EpollCtl(poller.epfd, syscall.EPOLL_CTL_ADD, poller.fd, &event) if errno != nil { return nil, errno } // Register pipe fd with epoll event = syscall.EpollEvent{ Fd: int32(poller.pipe[0]), Events: syscall.EPOLLIN, } errno = syscall.EpollCtl(poller.epfd, syscall.EPOLL_CTL_ADD, poller.pipe[0], &event) if errno != nil { return nil, errno } return poller, nil }
func (gpio *GPIO) WaitForEdge(edge Edge) (value Value, err error) { if err = gpio.setEdge(edge); err != nil { return 0, err } if err = gpio.ensureValueFileIsOpen(); err != nil { return 0, err } epollFd := gpio.epollFd.Get() if epollFd == 0 { epollFd, err = syscall.EpollCreate(1) if err != nil { return 0, err } event := &syscall.EpollEvent{ Events: syscall.EPOLLIN | syscall.EPOLLPRI | _EPOLLET, Fd: int32(gpio.valueFile.Fd()), } err = syscall.EpollCtl(epollFd, syscall.EPOLL_CTL_ADD, int(gpio.valueFile.Fd()), event) if err != nil { syscall.Close(epollFd) return 0, err } // first time triggers with current state, so ignore _, err = syscall.EpollWait(epollFd, dummyEpollEvents, -1) if err != nil { syscall.Close(epollFd) return 0, err } gpio.epollFd.Set(epollFd) } _, err = syscall.EpollWait(epollFd, dummyEpollEvents, -1) if err != nil { return 0, err } return gpio.Value() }
func init_inotify() { var err error name_by_wd = make(map[int32]string) wd_by_name = make(map[string]int32) var event syscall.InotifyEvent event_size = int(unsafe.Sizeof(event)) inotify_fd, _ = syscall.InotifyInit() if -1 == inotify_fd { bump_message("InotifyInit failed, file changes outside of tabby " + "will remain unnoticed") return } epoll_fd, err = syscall.EpollCreate(1) if -1 == epoll_fd { tabby_log("init_inotify: " + err.Error()) } var epoll_event syscall.EpollEvent epoll_event.Events = syscall.EPOLLIN syscall.EpollCtl(epoll_fd, syscall.EPOLL_CTL_ADD, inotify_fd, &epoll_event) go inotify_observe() }
func StartProxyServer(conf *ProxyConfig, proxy_log l4g.Logger) (err error) { logger = proxy_log var filter *IOFilterProtocol var netio *NetIOManager proxy := &ProxyServer{ max_listen_fds: 1024, timeout: 1000, quit: false, epoll_fd: -1, events: make([]syscall.EpollEvent, 100), sighnd: make(chan os.Signal, 1), } if !parse_config(proxy, conf) { logger.Error("Failed to initialize proxy server.") goto Error } filter = NewIOFilterProtocol(conf) if filter == nil { logger.Error("Failed to initialize filter protocol.") goto Error } else { if filter.FilterEnabled() { go filter.MonitQuotaFiles() go filter.MonitQuotaDataSize() } } netio = NewNetIOManager() netio.SetFilter(filter) proxy.epoll_fd, err = syscall.EpollCreate(proxy.max_listen_fds) if err != nil { logger.Critical("Failed to initialize epoll listener [%s].", err) goto Cleanup } netio.SetEpollFd(proxy.epoll_fd) err = netio.ProxyNetListen(&proxy.proxy_endpoint) if err != nil { logger.Critical("Failed to initialize server listener [%s].", err) goto Cleanup } setup_sighnd(proxy) logger.Info("Mongodb proxy server start.") for { wait_signal(proxy, syscall.SIGTERM) if proxy.quit { break } nfds, err := syscall.EpollWait(proxy.epoll_fd, proxy.events, proxy.timeout) if err != nil { logger.Critical("Failed to do epoll wait [%s].", err) break } for i := 0; i < nfds; i++ { fd := int(proxy.events[i].Fd) if netio.ProxyNetIsProxyServer(fd) { clientinfo, err := netio.ProxyNetAccept(&proxy.mongo_endpoint) if err != nil { logger.Critical("Failed to establish bridge between mongo client and server [%s].", err) } else { addr, port := parse_sockaddr(clientinfo) logger.Debug("Succeed to establish bridge for client [%s:%d].", addr, port) } } else { event := proxy.events[i].Events if event&syscall.EPOLLIN != 0 { errno := netio.ProxyNetRecv(fd) if errno != NO_ERROR { var addr string var port int sa := netio.ProxyNetConnInfo(fd) if sa != nil { addr, port = parse_sockaddr(sa) } switch errno { case READ_ERROR: if sa != nil { logger.Error("Failed to read data from [%s:%d].", addr, port) } case SESSION_EOF: /* normal close */ netio.ProxyNetFlush(fd) if sa != nil { logger.Debug("One side [%s:%d] close the session.", addr, port) } case UNKNOWN_ERROR: if sa != nil { logger.Debug("Unknown error during read happened at [%s:%d].", addr, port) } } netio.ProxyNetClosePeers(fd) } } if event&syscall.EPOLLOUT != 0 { errno := netio.ProxyNetSend(fd) if errno != NO_ERROR && errno != PARTIAL_SKB { var addr string var port int sa := netio.ProxyNetConnInfo(fd) if sa != nil { addr, port = parse_sockaddr(sa) } switch errno { case WRITE_ERROR: if sa != nil { logger.Error("Failed to write data to [%s:%d]", addr, port) } case FILTER_BLOCK: /* * 'block' handler only happens on 'proxy->server' io write, here * we need to log the 'client->proxy' connection information, if * we call 'ConnInfo' method we get the 'proxy->server' connection, * so we shall call 'OtherSideConnInfo' method here. */ sa = netio.ProxyNetOtherSideConnInfo(fd) if sa != nil { addr, port = parse_sockaddr(sa) logger.Error("Filter block request from client [%s:%d].", addr, port) } case UNKNOWN_ERROR: if sa != nil { logger.Debug("Unknown error during write happened at [%s:%d].", addr, port) } } netio.ProxyNetClosePeers(fd) } } if event&syscall.EPOLLRDHUP != 0 { netio.ProxyNetFlush(fd) sa := netio.ProxyNetConnInfo(fd) if sa != nil { ipaddr, port := parse_sockaddr(sa) logger.Debug("shutdown connection with [%s:%d].", ipaddr, port) netio.ProxyNetClosePeers(fd) } } if event&syscall.EPOLLHUP != 0 { netio.ProxyNetFlush(fd) sa := netio.ProxyNetConnInfo(fd) if sa != nil { ipaddr, port := parse_sockaddr(sa) logger.Debug("shutdown connection with [%s:%d].", ipaddr, port) netio.ProxyNetClosePeers(fd) } } } } } Cleanup: netio.DestroyNetIO() Error: logger.Info("Mongodb proxy server quit.") logger.Close() return err }
func StartProxyServer(conf *ProxyConfig, proxy_log l4g.Logger) (err error) { logger = proxy_log var filter *IOFilterProtocol var netio *NetIOManager proxy := &ProxyServer{ max_listen_fds: 1024, timeout: 1000, quit: false, epoll_fd: -1, events: make([]syscall.EpollEvent, 100), sighnd: make(chan os.Signal, 1), } if !parse_config(proxy, conf) { logger.Error("Failed to initialize proxy server.") goto Error } filter = NewIOFilterProtocol(conf) if filter == nil { logger.Error("Failed to initialize filter protocol.") goto Error } else { if filter.FilterEnabled() { go filter.MonitDiskUsage() } } netio = NewNetIOManager() netio.SetFilter(filter) proxy.epoll_fd, err = syscall.EpollCreate(proxy.max_listen_fds) if err != nil { logger.Critical("Failed to initialize epoll listener [%s].", err) goto Cleanup } netio.SetEpollFd(proxy.epoll_fd) err = netio.ProxyNetListen(&proxy.proxy_endpoint) if err != nil { logger.Critical("Failed to initialize server listener [%s].", err) goto Cleanup } setup_sighnd(proxy) logger.Info("Mongodb proxy server start.") for { wait_signal(proxy, syscall.SIGTERM) if proxy.quit { break } nfds, err := syscall.EpollWait(proxy.epoll_fd, proxy.events, proxy.timeout) if err != nil { logger.Critical("Failed to do epoll wait [%s].", err) break } for i := 0; i < nfds; i++ { fd := int(proxy.events[i].Fd) if netio.ProxyNetIsProxyServer(fd) { clientinfo, err := netio.ProxyNetAccept(&proxy.mongo_endpoint) if err != nil { logger.Critical("Failed to establish bridge between mongo client and server [%s].", err) } else { ipaddr, port := parse_sockaddr(clientinfo) logger.Debug("Succeed to establish bridge for client [%s:%d].", ipaddr, port) } } else { event := proxy.events[i].Events if event&syscall.EPOLLIN != 0 { errno := netio.ProxyNetRecv(fd) switch errno { case READ_ERROR: sa := netio.ProxyNetConnInfo(fd) if sa != nil { ipaddr, port := parse_sockaddr(sa) logger.Error("Failed to read data from [%s:%d].", ipaddr, port) } case SESSION_EOF: sa := netio.ProxyNetConnInfo(fd) if sa != nil { ipaddr, port := parse_sockaddr(sa) logger.Debug("One side [%s:%d] close the session.", ipaddr, port) } } if errno != NO_ERROR { netio.ProxyNetClosePeers(fd) } } if event&syscall.EPOLLOUT != 0 { errno := netio.ProxyNetSend(fd) switch errno { case WRITE_ERROR: sa := netio.ProxyNetConnInfo(fd) if sa != nil { ipaddr, port := parse_sockaddr(sa) logger.Error("Failed to write data to [%s:%d]", ipaddr, port) } case FILTER_BLOCK: sa := netio.ProxyNetConnInfo(fd) if sa != nil { ipaddr, port := parse_sockaddr(sa) logger.Error("Filter block request from client [%s:%d].", ipaddr, port) } } if errno != NO_ERROR { netio.ProxyNetClosePeers(fd) } } if event&syscall.EPOLLRDHUP != 0 { sa := netio.ProxyNetConnInfo(fd) if sa != nil { ipaddr, port := parse_sockaddr(sa) logger.Debug("shutdown connection with [%s:%d].", ipaddr, port) netio.ProxyNetClosePeers(fd) } } if event&syscall.EPOLLHUP != 0 { sa := netio.ProxyNetConnInfo(fd) if sa != nil { ipaddr, port := parse_sockaddr(sa) logger.Debug("shutdown connection with [%s:%d].", ipaddr, port) netio.ProxyNetClosePeers(fd) } } } } } Cleanup: netio.DestroyNetIO() Error: logger.Info("Mongodb proxy server quit.") logger.Close() return err }