123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- package door
- import (
- "log"
- "syscall"
- "time"
- )
- var ReaderInterval = time.Duration(200) * time.Millisecond
- var ReaderTimeval syscall.Timeval = syscall.Timeval{0, 200}
- func clearAll(fdSetPtr *syscall.FdSet) {
- for index := range (*fdSetPtr).Bits {
- (*fdSetPtr).Bits[index] = 0
- }
- }
- func set(fdSetPtr *syscall.FdSet, fd int) {
- (*fdSetPtr).Bits[fd/64] |= 1 << uint64(fd%64)
- }
- func Reader(d *Door) {
- // I need non-blocking reads here.
- // I'm not really using either of these things.
- // d.readerFile = os.NewFile(uintptr(d.READFD), "Door FD")
- // d.runereader = bufio.NewReaderSize(d.readerFile, 1)
- defer func() {
- log.Printf("~Reader\n")
- if d.ReaderCanClose {
- d.wg.Done()
- }
- }()
- defer func() {
- if err := recover(); err != nil {
- log.Printf("Reader: %#v\n", err)
- }
- }()
- var fdset syscall.FdSet
- for {
- clearAll(&fdset)
- set(&fdset, d.READFD)
- v, err := syscall.Select(d.READFD+1, &fdset, nil, nil, &ReaderTimeval)
- if err == syscall.EINTR {
- continue
- }
- // log.Printf("Select: %#v / %#v\n", v, err)
- if v == -1 {
- log.Printf("Reader ERR: %#v\n", err)
- d.readerMutex.Lock()
- if !d.ReaderClosed {
- d.ReaderClosed = true
- close(d.readerChannel)
- }
- return
- }
- if v == 0 {
- // timeout
- continue
- }
- // d.readerFile.SetReadDeadline(time.Now().Add(ReaderInterval))
- // not on a os.File you won't. :P
- // r, _, err := d.runereader.ReadRune()
- buffer := make([]byte, 1)
- r, err := syscall.Read(d.READFD, buffer)
- if r == -1 {
- log.Println("Read -1 (closed)")
- d.readerMutex.Lock()
- defer d.readerMutex.Unlock()
- if !d.ReaderClosed {
- d.ReaderClosed = true
- d.Disconnected = true
- close(d.readerChannel)
- }
- return
- }
- if r != 1 {
- log.Printf("Select said ready, but: %#v %#v\n", r, err)
- d.readerMutex.Lock()
- defer d.readerMutex.Unlock()
- if !d.ReaderClosed {
- d.ReaderClosed = true
- d.Disconnected = true
- close(d.readerChannel)
- }
- return
- }
- if DEBUG_INPUT {
- log.Printf("Reader (byte): %#v\n", buffer[0])
- }
- d.readerChannel <- rune(buffer[0])
- /*
- if r == unicode.ReplacementChar {
- _ = d.runereader.UnreadRune()
- b, _ := d.runereader.ReadByte()
- if DEBUG_INPUT {
- log.Printf("Reader (byte): %#v\n", b)
- }
- d.readerChannel <- rune(b)
- continue
- }
- if err == nil {
- if DEBUG_INPUT {
- log.Printf("Reader (rune): %#v\n", r)
- }
- d.readerChannel <- r
- continue
- }
- */
- // I'm not sure I care what the error is we're getting here...
- /*
- if e, ok := err.(net.Error); ok && e.Timeout() {
- } else {
- }
- */
- /*
- log.Printf("Reader ERR: %#v\n", err)
- d.ReaderClosed = true
- close(d.readerChannel)
- return
- */
- }
- }
- /*
- func Reader(handle int, readerChannel *chan byte) {
- // I don't need the select anymore. Let the read block.
- defer func() {
- if err := recover(); err != nil {
- log.Printf("Reader: %#v\n", err)
- }
- }()
- buffer := make([]byte, 1)
- for {
- // blocking read in go routine
- // why doesn't this end when I close the handle?
- read, err := syscall.Read(handle, buffer)
- if err != nil {
- log.Printf("Reader ERR: %#v\n", err)
- close(*readerChannel)
- break
- }
- if read == 1 {
- *readerChannel <- buffer[0]
- } else {
- log.Printf("READ FAILED %d\n", read)
- close(*readerChannel)
- break
- }
- }
- }
- // This doesn't work. Closing the handle does not unblock the syscall.Read above.
- func CloseReader(handle int) {
- defer func() {
- if err := recover(); err != nil {
- log.Printf("CloseReader: %#v\n", err)
- }
- }()
- syscall.Close(handle)
- }
- */
|