func test4() error { rFDSet := &goselect.FDSet{} buf := make([]byte, 1024) for { // TODO: this can be cached and changed only upon controlePipe event. rFDSet.Zero() rFDSet.Set(os.Stdin.Fd()) if err := goselect.Select(int(os.Stdin.Fd())+1, rFDSet, nil, nil, -1); err != nil { return err } for i := uintptr(0); i < syscall.FD_SETSIZE; i++ { if rFDSet.IsSet(i) { println(i, "is ready") } } if rFDSet.IsSet(os.Stdin.Fd()) { n, err := os.Stdin.Read(buf) if err != nil { if err == io.EOF { break } return err } fmt.Printf("---->: %s\n", buf[:n]) } } return nil }
func (s *Select) run() { rFDSet := &goselect.FDSet{} var max uintptr var fd uintptr for { // TODO: this can be cached and changed only upon controlePipe event. rFDSet.Zero() fd = s.controlPipeR.Fd() max = fd rFDSet.Set(fd) for _, r := range s.readers { fd = r.Fd() if max < fd { max = fd } rFDSet.Set(fd) } println("-------> preselect") if err := goselect.Select(int(max)+1, rFDSet, nil, nil, -1); err != nil { log.Fatal(err) } for i := uintptr(0); i < syscall.FD_SETSIZE; i++ { if rFDSet.IsSet(i) { println(i, "is ready") } } println("<-------- postselect") for _, r := range s.readers { if rFDSet.IsSet(r.Fd()) { func(r *selectReader) { r.ready <- struct{}{} }(r) } } if rFDSet.IsSet(s.controlPipeR.Fd()) { buf := make([]byte, 1024) n, err := s.controlPipeR.Read(buf) if err != nil { if err == io.EOF { break } log.Fatal(err) } fmt.Printf("----> control: %s\n", buf[:n]) } } }
func (c *Client) writeLoop(done chan bool, wg *sync.WaitGroup) { defer wg.Done() buff := make([]byte, 128) oldState, err := terminal.MakeRaw(0) if err == nil { defer terminal.Restore(0, oldState) } rdfs := &goselect.FDSet{} reader := io.Reader(os.Stdin) for { rdfs.Zero() rdfs.Set(reader.(exposeFd).Fd()) err := goselect.Select(1, rdfs, nil, nil, 50*time.Millisecond) if err != nil { done <- true return } if rdfs.IsSet(reader.(exposeFd).Fd()) { size, err := reader.Read(buff) if size <= 0 || err != nil { done <- true return } data := buff[:size] err = c.write(append([]byte("0"), data...)) if err != nil { done <- true return } } select { case <-c.QuitChan: return default: break } } }
func testServer() error { l, err := net.Listen("tcp", "0.0.0.0:8080") if err != nil { return err } ll, ok := l.(*net.TCPListener) if !ok { return fmt.Errorf("wrong listener type") } llf, err := ll.File() if err != nil { return err } rFDSet := &goselect.FDSet{} wFDSet := &goselect.FDSet{} buf := make([]byte, 1024) var max, fd uintptr clients := []*Client{} for { // TODO: this can be cached and changed only upon controlePipe event. rFDSet.Zero() wFDSet.Zero() fd = llf.Fd() max = fd rFDSet.Set(fd) for _, c := range clients { fd = c.f.Fd() rFDSet.Set(fd) if len(c.queue) > 0 { wFDSet.Set(fd) } if max < fd { max = fd } } if err := goselect.Select(int(max)+1, rFDSet, wFDSet, nil, -1); err != nil { return err } println("-->") // Watch for new clients if rFDSet.IsSet(llf.Fd()) { c, err := ll.AcceptTCP() if err != nil { return err } f, err := c.File() if err != nil { return err } fd = f.Fd() println("New client:", fd) clients = append(clients, &Client{f: f}) } // Watch for client activity for _, c := range clients { fd = c.f.Fd() if rFDSet.IsSet(fd) { n, err := c.f.Read(buf) if err != nil { return err } fmt.Printf("%s", buf[:n]) for _, cc := range clients { if c != cc { cc.Push(buf[:n]) } } } } // Send message to clients for _, c := range clients { fd = c.f.Fd() if wFDSet.IsSet(fd) { msg := c.Pop() fmt.Printf("%d write ready: %v\n", fd, msg) if msg != nil { _, err := c.f.Write(msg) if err != nil { return err } } } } } }