|
@@ -30,7 +30,6 @@ import (
|
|
"strconv"
|
|
"strconv"
|
|
"strings"
|
|
"strings"
|
|
"sync"
|
|
"sync"
|
|
- "sync/atomic"
|
|
|
|
"time"
|
|
"time"
|
|
)
|
|
)
|
|
|
|
|
|
@@ -92,16 +91,34 @@ type Door struct {
|
|
Config DropfileConfig
|
|
Config DropfileConfig
|
|
READFD int
|
|
READFD int
|
|
WRITEFD int
|
|
WRITEFD int
|
|
- Disconnected int32 // atomic bool // Has User disconnected/Hung up?
|
|
|
|
- TimeOut time.Time // Fixed point in time, when time expires
|
|
|
|
- StartTime time.Time // Time when User started door
|
|
|
|
- Pushback FIFOBuffer // Key buffer
|
|
|
|
- LastColor []int // Track the last color sent for restore color
|
|
|
|
- readerChannel chan byte // Reading from the User
|
|
|
|
- ReaderCanClose bool // We can close the reader (in tests)
|
|
|
|
- writerChannel chan string // Writing to the User
|
|
|
|
- closeChannel chan struct{} // Closing
|
|
|
|
- wg sync.WaitGroup
|
|
|
|
|
|
+ Disconnected bool // int32 // atomic bool // Has User disconnected/Hung up?
|
|
|
|
+ TimeOut time.Time // Fixed point in time, when time expires
|
|
|
|
+ StartTime time.Time // Time when User started door
|
|
|
|
+ Pushback FIFOBuffer // Key buffer
|
|
|
|
+ LastColor []int // Track the last color sent for restore color
|
|
|
|
+ ReaderClosed bool // Reader close
|
|
|
|
+ readerChannel chan byte // Reading from the User
|
|
|
|
+ ReaderCanClose bool // We can close the reader (in tests)
|
|
|
|
+ WriterClosed bool // Writer closed
|
|
|
|
+ writerChannel chan string // Writing to the User
|
|
|
|
+ writerMutex sync.RWMutex
|
|
|
|
+ // closeChannel chan struct{} // Closing
|
|
|
|
+ wg sync.WaitGroup
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (d *Door) SafeWriterClose() {
|
|
|
|
+ d.writerMutex.Lock()
|
|
|
|
+ defer d.writerMutex.Unlock()
|
|
|
|
+ if !d.WriterClosed {
|
|
|
|
+ d.WriterClosed = true
|
|
|
|
+ close(d.writerChannel)
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (d *Door) WriterIsClosed() bool {
|
|
|
|
+ d.writerMutex.RLock()
|
|
|
|
+ defer d.writerMutex.RUnlock()
|
|
|
|
+ return d.WriterClosed
|
|
}
|
|
}
|
|
|
|
|
|
// Return the amount of time left as time.Duration
|
|
// Return the amount of time left as time.Duration
|
|
@@ -114,7 +131,7 @@ func (d *Door) TimeUsed() time.Duration {
|
|
}
|
|
}
|
|
|
|
|
|
func (d *Door) Disconnect() bool {
|
|
func (d *Door) Disconnect() bool {
|
|
- return atomic.LoadInt32(&d.Disconnected) != 0
|
|
|
|
|
|
+ return d.Disconnected // atomic.LoadInt32(&d.Disconnected) != 0
|
|
}
|
|
}
|
|
|
|
|
|
// Read the BBS door file. We only support door32.sys.
|
|
// Read the BBS door file. We only support door32.sys.
|
|
@@ -290,8 +307,10 @@ func (d *Door) Init(doorname string) {
|
|
log.Printf("BBS %s, User %s / Handle %s / File %d\n", d.Config.BBSID, d.Config.Real_name, d.Config.Handle, d.Config.Comm_handle)
|
|
log.Printf("BBS %s, User %s / Handle %s / File %d\n", d.Config.BBSID, d.Config.Real_name, d.Config.Handle, d.Config.Comm_handle)
|
|
|
|
|
|
d.readerChannel = make(chan byte, 8)
|
|
d.readerChannel = make(chan byte, 8)
|
|
- d.writerChannel = make(chan string)
|
|
|
|
- d.closeChannel = make(chan struct{}, 2) // reader & door.Close
|
|
|
|
|
|
+ d.writerChannel = make(chan string) // unbuffered
|
|
|
|
+
|
|
|
|
+ // changing this to unbound/sync hangs tests.
|
|
|
|
+ // d.closeChannel = make(chan struct{}, 2) // reader & door.Close
|
|
|
|
|
|
d.setupChannels()
|
|
d.setupChannels()
|
|
|
|
|
|
@@ -315,7 +334,10 @@ func (d *Door) Close() {
|
|
}()
|
|
}()
|
|
|
|
|
|
log.Println("Closing...")
|
|
log.Println("Closing...")
|
|
- d.closeChannel <- struct{}{}
|
|
|
|
|
|
+ // d.closeChannel <- struct{}{}
|
|
|
|
+ if !d.WriterClosed {
|
|
|
|
+ d.writerChannel <- ""
|
|
|
|
+ }
|
|
|
|
|
|
// CloseReader(d.Config.Comm_handle)
|
|
// CloseReader(d.Config.Comm_handle)
|
|
|
|
|