Commit 9ef4c49d authored by ceddral's avatar ceddral
Browse files

lobby: replace lock with channel based semaphore

previously a race condition when starting a game
allowed the lobby loop to run into a draw call
trying to acquire the lobby lock, while a different
routine was holding the lock and waiting for this loop
to terminate.

only pass the termination check if the lobby lock for
the draw call can be acquired.
parent 5f343e7f
......@@ -4,7 +4,6 @@ import (
tg "fahrradwurstmond2.0/telnet_gui"
common "fahrradwurstmond2.0/common"
game "fahrradwurstmond2.0/game"
"sync"
"fmt"
)
......@@ -24,7 +23,7 @@ type Player struct {
}
type Lobby struct {
lock *sync.Mutex
lock chan struct{}
agent *Player
Players map[string]*Player
playerOrder []string
......@@ -32,18 +31,18 @@ type Lobby struct {
func NewLobby() (l *Lobby) {
return &Lobby{
lock: &sync.Mutex{},
lock: make(chan struct{}, 1),
Players: make(map[string]*Player),
playerOrder: make([]string, 0),
}
}
func (l *Lobby) Lock() {
l.lock.Lock()
l.lock<-struct{}{}
}
func (l *Lobby) Unlock() {
l.lock.Unlock()
<-l.lock
}
func (l *Lobby) Register(glp *common.Player) {
......@@ -164,19 +163,18 @@ func (l *Lobby) Loop(p *Player) {
select { // check kill before doing anything that may lock
case <-p.Kill:
return
default:
case l.lock<-struct{}{}:
p.drawLobby(l)
l.Unlock()
p.Scr.Update()
}
p.DrawLobby(l)
p.Scr.Update()
}
}
func (p *Player) DrawLobby(l *Lobby) {
func (p *Player) drawLobby(l *Lobby) {
line := 0
fg := tg.ColorDefault
bg := tg.ColorDefault
l.Lock()
defer l.Unlock()
v := p.playerListv
v.Clear()
v.DrawTextClearLine(fg, bg, []byte(fmt.Sprintf(" Seats:")), 0, line)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment