diff --git a/serial_unix.go b/serial_unix.go index c796c30..c33bca8 100644 --- a/serial_unix.go +++ b/serial_unix.go @@ -13,6 +13,7 @@ import ( "regexp" "strings" "sync" + "sync/atomic" "unsafe" "go.bug.st/serial/unixutils" @@ -24,16 +25,18 @@ type unixPort struct { closeLock sync.RWMutex closeSignal *unixutils.Pipe - opened bool + opened uint32 } func (port *unixPort) Close() error { + if !atomic.CompareAndSwapUint32(&port.opened, 1, 0) { + return &PortError{code: PortClosed} + } // Close port port.releaseExclusiveAccess() if err := unix.Close(port.handle); err != nil { return err } - port.opened = false if port.closeSignal != nil { // Send close signal to all pending reads (if any) @@ -54,7 +57,7 @@ func (port *unixPort) Close() error { func (port *unixPort) Read(p []byte) (int, error) { port.closeLock.RLock() defer port.closeLock.RUnlock() - if !port.opened { + if atomic.LoadUint32(&port.opened) != 1 { return 0, &PortError{code: PortClosed} } @@ -169,7 +172,7 @@ func nativeOpen(portName string, mode *Mode) (*unixPort, error) { } port := &unixPort{ handle: h, - opened: true, + opened: 1, } // Setup serial port