summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--courses.go9
-rw-r--r--wsm.go8
-rw-r--r--wsp.go10
3 files changed, 15 insertions, 12 deletions
diff --git a/courses.go b/courses.go
index 4f4d0cf..bc3ca9a 100644
--- a/courses.go
+++ b/courses.go
@@ -25,6 +25,7 @@ import (
"errors"
"fmt"
"sync"
+ "sync/atomic"
"github.com/coder/websocket"
)
@@ -45,9 +46,9 @@ type courseT struct {
* on the CPU so I'd have to look into how mutexes/semaphores are
* actually implemented and how I could interact with the runtime.
*/
- Selected int
- SelectedLock sync.RWMutex
- Max int
+ Selected uint32
+ SelectedLock sync.Mutex
+ Max uint32
Title string
Type courseTypeT
Group courseGroupT
@@ -260,7 +261,7 @@ func (course *courseT) decrementSelectedAndPropagate(
func() {
course.SelectedLock.Lock()
defer course.SelectedLock.Unlock()
- course.Selected--
+ atomic.AddUint32(&course.Selected, ^uint32(0))
}()
go propagateSelectedUpdate(course.ID)
err := sendSelectedUpdate(ctx, conn, course.ID)
diff --git a/wsm.go b/wsm.go
index 797475c..4360e75 100644
--- a/wsm.go
+++ b/wsm.go
@@ -26,6 +26,7 @@ import (
"fmt"
"strconv"
"strings"
+ "sync/atomic"
"time"
"github.com/coder/websocket"
@@ -164,8 +165,13 @@ func messageChooseCourse(
ok := func() bool {
course.SelectedLock.Lock()
defer course.SelectedLock.Unlock()
+ /*
+ * The read here doesn't have to be atomic because the
+ * lock guarantees that no other goroutine is writing to
+ * it.
+ */
if course.Selected < course.Max {
- course.Selected++
+ atomic.AddUint32(&course.Selected, 1)
return true
}
return false
diff --git a/wsp.go b/wsp.go
index 09a1360..1c30d4a 100644
--- a/wsp.go
+++ b/wsp.go
@@ -23,6 +23,7 @@ package main
import (
"context"
"fmt"
+ "sync/atomic"
"github.com/coder/websocket"
)
@@ -93,13 +94,8 @@ func sendSelectedUpdate(
conn *websocket.Conn,
courseID int,
) error {
- var selected int
- func() {
- course := courses[courseID]
- course.SelectedLock.RLock()
- defer course.SelectedLock.RUnlock()
- selected = course.Selected
- }()
+ course := courses[courseID]
+ selected := atomic.LoadUint32(&course.Selected)
err := writeText(ctx, conn, fmt.Sprintf("M %d %d", courseID, selected))
if err != nil {
return fmt.Errorf(