예제 #1
0
func (ar *AsyncReader) Run() {
	fd := int(ar.rd.Fd())
	cfd := int(ar.rCtrl.Fd())
	maxfd := max(fd, cfd)
	fs := sys.NewFdSet()
	var cBuf [1]byte

	if nonblock, _ := sys.GetNonblock(fd); !nonblock {
		sys.SetNonblock(fd, true)
		defer sys.SetNonblock(fd, false)
	}

	for {
		fs.Set(fd, cfd)
		err := sys.Select(maxfd+1, fs, nil, nil, nil)
		if err != nil {
			switch err {
			case syscall.EINTR:
				continue
			default:
				panic(err)
			}
		}
		if fs.IsSet(cfd) {
			// Consume the written byte
			ar.rCtrl.Read(cBuf[:])
			ar.ackCtrl <- true
			return
		} else {
			r, _, err := ar.bufrd.ReadRune()
			switch err {
			case nil:
				ar.ch <- r
			case io.EOF:
				return
			default:
				// BUG(xiaq): AsyncReader relies on the undocumented fact
				// that (*os.File).Read returns an *os.File.PathError
				e := err.(*os.PathError).Err
				if e != syscall.EWOULDBLOCK && e != syscall.EAGAIN {
					panic(err)
				}
			}
		}
	}
}
예제 #2
0
// Run runs the AsyncReader. It blocks until Quit is called and should be
// called in a separate goroutine.
func (ar *AsyncReader) Run() {
	fd := int(ar.rd.Fd())
	cfd := int(ar.rCtrl.Fd())
	maxfd := max(fd, cfd)
	fs := sys.NewFdSet()
	var cBuf [1]byte

	if nonblock, _ := sys.GetNonblock(fd); !nonblock {
		sys.SetNonblock(fd, true)
		defer sys.SetNonblock(fd, false)
	}

	for {
		fs.Set(fd, cfd)
		err := sys.Select(maxfd+1, fs, nil, nil, nil)
		if err != nil {
			switch err {
			case syscall.EINTR:
				continue
			default:
				ar.errCh <- err
				return
			}
		}
		if fs.IsSet(cfd) {
			// Consume the written byte
			ar.rCtrl.Read(cBuf[:])
			<-ar.ctrlCh
			return
		}
	ReadRune:
		for {
			r, _, err := ar.bufrd.ReadRune()
			switch err {
			case nil:
				// Logger.Printf("read rune: %q", r)
				select {
				case ar.ch <- r:
				case <-ar.ctrlCh:
					ar.rCtrl.Read(cBuf[:])
					return
				}
			case io.EOF:
				return
			default:
				// BUG(xiaq): AsyncReader relies on the undocumented fact
				// that (*os.File).Read returns an *os.File.PathError
				patherr, ok := err.(*os.PathError) //.Err
				if !ok {
					ar.errCh <- err
					return
				}
				e := patherr.Err
				if e == syscall.EWOULDBLOCK || e == syscall.EAGAIN {
					break ReadRune
				} else {
					ar.errCh <- err
					return
				}
			}
		}
	}
}
예제 #3
0
func (ar *AsyncReader) run() {
	fd := int(ar.rd.Fd())
	cfd := int(ar.rCtrl.Fd())
	maxfd := max(fd, cfd)
	fs := sys.NewFdSet()
	var cBuf [1]byte

	defer close(ar.ch)

	sys.SetNonblock(fd, true)

	for {
		fs.Set(fd, cfd)
		err := sys.Select(maxfd+1, fs, nil, nil, nil)
		if err != nil {
			switch err {
			case syscall.EINTR:
				continue
			default:
				panic(err)
			}
		}
		if fs.IsSet(cfd) {
			// Consume the written byte
			ar.rCtrl.Read(cBuf[:])
			switch cBuf[0] {
			case asyncReaderQuit:
				sys.SetNonblock(fd, false)
				ar.ackCtrl <- true
				return
			case asyncReaderContinue:
				ar.ackCtrl <- true
			case asyncReaderStop:
				sys.SetNonblock(fd, false)
				ar.ackCtrl <- true
			Stop:
				for {
					ar.rCtrl.Read(cBuf[:])
					switch cBuf[0] {
					case asyncReaderQuit:
						ar.ackCtrl <- true
						return
					case asyncReaderContinue:
						sys.SetNonblock(fd, true)
						ar.ackCtrl <- true
						break Stop
					case asyncReaderStop:
						ar.ackCtrl <- true
					}
				}
			}
		} else {
		ReadRune:
			for {
				r, _, err := ar.bufrd.ReadRune()
				switch err {
				case nil:
					ar.ch <- r
				case io.EOF:
					return
				default:
					// BUG(xiaq): AsyncReader relies on the undocumented fact
					// that (*os.File).Read returns an *os.File.PathError
					e := err.(*os.PathError).Err
					if e == syscall.EWOULDBLOCK || e == syscall.EAGAIN {
						break ReadRune
					} else {
						panic(err)
					}
				}
			}
		}
	}
}