From b04758da4cab7422eee5f8a3e23c01e79cb5d696 Mon Sep 17 00:00:00 2001
From: Kevin Lyda <kevin@ie.suberic.net>
Date: Wed, 1 Feb 2017 12:29:46 +0000
Subject: [PATCH] Add mutexes for serial access.

---
 cmd/gqgmcd/main.go      |  1 -
 devices/geiger/gqgmc.go | 24 ++++++++++++++++++++++++
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/cmd/gqgmcd/main.go b/cmd/gqgmcd/main.go
index c1c415a..0e2d09a 100644
--- a/cmd/gqgmcd/main.go
+++ b/cmd/gqgmcd/main.go
@@ -13,7 +13,6 @@ import (
 	"log"
 	"net/http"
 	"path"
-	//"sync"
 
 	"github.com/prometheus/client_golang/prometheus/promhttp"
 	"gitlab.com/lyda/gqgmc/devices/geiger"
diff --git a/devices/geiger/gqgmc.go b/devices/geiger/gqgmc.go
index 06e98af..11c365c 100644
--- a/devices/geiger/gqgmc.go
+++ b/devices/geiger/gqgmc.go
@@ -12,6 +12,7 @@ import (
 	"errors"
 	"fmt"
 	"strconv"
+	"sync"
 	"time"
 
 	"github.com/tarm/serial"
@@ -55,6 +56,7 @@ type GQGMCCounter struct {
 	version,
 	model,
 	serial string
+	mutex *sync.Mutex
 }
 
 // NewGQGMC creates a new GQGMC Counter instance
@@ -72,6 +74,7 @@ func NewGQGMC(c Config) (*GQGMCCounter, error) {
 		return nil, err
 	}
 	gc.port = p
+	gc.mutex = &sync.Mutex{}
 	buf, err = gc.communicate(cmdGetVersion, 14)
 	if err == nil {
 		gc.model = string(buf[:7])
@@ -165,7 +168,9 @@ func (gc *GQGMCCounter) TurnOnCPS() error {
 		return errors.New("Unsupported version")
 	}
 
+	gc.mutex.Lock()
 	gc.sendCmd(cmdTurnOnCPS)
+	gc.mutex.Unlock()
 	return nil
 }
 
@@ -178,14 +183,19 @@ func (gc *GQGMCCounter) TurnOffCPS() error {
 		return errors.New("Unsupported version")
 	}
 
+	gc.mutex.Lock()
 	gc.sendCmd(cmdTurnOffCPS)
 	gc.Clear()
+	gc.mutex.Unlock()
 	return nil
 }
 
 // GetAutoCPS gets a reading once auto CPS is turned on
 func (gc *GQGMCCounter) GetAutoCPS() (uint16, error) {
+	gc.mutex.Lock()
 	buf, err := gc.readCmd(2)
+	gc.mutex.Unlock()
+
 	if err != nil {
 		return 0, err
 	}
@@ -203,7 +213,9 @@ func (gc *GQGMCCounter) TurnOnPower() {
 		return
 	}
 
+	gc.mutex.Lock()
 	gc.sendCmd(cmdTurnOnPwr)
+	gc.mutex.Unlock()
 	return
 }
 
@@ -216,7 +228,9 @@ func (gc *GQGMCCounter) TurnOffPower() {
 		return
 	}
 
+	gc.mutex.Lock()
 	gc.sendCmd(cmdTurnOffPwr)
+	gc.mutex.Unlock()
 	return
 }
 
@@ -256,6 +270,8 @@ func (gc *GQGMCCounter) SetTime(t time.Time) {
 	if gc.versionLT("Re 2.23") {
 		return
 	}
+	gc.mutex.Lock()
+	defer gc.mutex.Unlock()
 	if gc.versionLT("Re 3.30") {
 		gc.setTimeParts(t)
 	}
@@ -280,6 +296,7 @@ func (gc *GQGMCCounter) setTimeParts(t time.Time) {
 		copy(cmd[:], c.cmd)
 		cmd[10] = uint8(c.unit)
 		copy(cmd[11:], ">>")
+		// Mutex acquired in setTime()
 		gc.port.Write(cmd)
 		gc.readCmd(1)
 	}
@@ -295,6 +312,7 @@ func (gc *GQGMCCounter) setTimeAll(t time.Time) {
 	cmd[16] = uint8(t.Minute())
 	cmd[17] = uint8(t.Second())
 	copy(cmd[18:], ">>")
+	// Mutex acquired in setTime()
 	gc.port.Write(cmd)
 	gc.readCmd(1)
 }
@@ -373,7 +391,9 @@ func (gc *GQGMCCounter) FactoryReset() {
 		return
 	}
 
+	gc.mutex.Lock()
 	gc.sendCmd(cmdFactoryReset)
+	gc.mutex.Unlock()
 	return
 }
 
@@ -386,7 +406,9 @@ func (gc *GQGMCCounter) Reboot() {
 		return
 	}
 
+	gc.mutex.Lock()
 	gc.sendCmd(cmdReboot)
+	gc.mutex.Unlock()
 	return
 }
 
@@ -404,6 +426,8 @@ func (gc *GQGMCCounter) versionLT(version string) bool {
 }
 
 func (gc *GQGMCCounter) communicate(cmd string, length uint32) ([]byte, error) {
+	gc.mutex.Lock()
+	defer gc.mutex.Unlock()
 	gc.Clear()
 	if len(cmd) > 0 {
 		gc.sendCmd(cmd)
-- 
GitLab