diff options
Diffstat (limited to '')
-rw-r--r-- | courses.go | 9 | ||||
-rw-r--r-- | wsm.go | 8 | ||||
-rw-r--r-- | wsp.go | 10 |
3 files changed, 15 insertions, 12 deletions
@@ -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) @@ -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 @@ -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( |