code: func (e *Epoller) Add(console Console) (*EpollConsole, error) {
  	sysfd := int(console.Fd())
  	// Set sysfd to non-blocking mode
  	if err := unix.SetNonblock(sysfd, true); err != nil {
  		return nil, err
  	}
  
  	ev := unix.EpollEvent{
  		Events: unix.EPOLLIN | unix.EPOLLOUT | unix.EPOLLRDHUP | unix.EPOLLET,
  		Fd:     int32(sysfd),
  	}
  	if err := unix.EpollCtl(e.efd, unix.EPOLL_CTL_ADD, sysfd, &ev); err != nil {
  		return nil, err
  	}
  	ef := &EpollConsole{
  		Console: console,
  		sysfd:   sysfd,
  		readc:   sync.NewCond(&sync.Mutex{}),
  		writec:  sync.NewCond(&sync.Mutex{}),
  	}
  	e.mu.Lock()
  	e.fdMapping[sysfd] = ef
  	e.mu.Unlock()
  	return ef, nil
  }
docs: // Add creates an epoll console based on the provided console. The console will
  // be registered with EPOLLET (i.e. using edge-triggered notification) and its
  // file descriptor will be set to non-blocking mode. After this, user should use
  // the return console to perform I/O.