attempt at fixing deadlock
This commit is contained in:
parent
2836676ff5
commit
68f1db5427
1 changed files with 22 additions and 9 deletions
|
|
@ -101,21 +101,23 @@ func NewTable(cfg Config) *Table {
|
||||||
// The caller is responsible for deducting from the player's wallet first.
|
// The caller is responsible for deducting from the player's wallet first.
|
||||||
func (t *Table) Sit(username string, seatIndex int, buyin int64) error {
|
func (t *Table) Sit(username string, seatIndex int, buyin int64) error {
|
||||||
t.mu.Lock()
|
t.mu.Lock()
|
||||||
defer t.mu.Unlock()
|
|
||||||
|
|
||||||
if seatIndex < 0 || seatIndex >= len(t.Seats) {
|
if seatIndex < 0 || seatIndex >= len(t.Seats) {
|
||||||
|
t.mu.Unlock()
|
||||||
return errors.New("invalid seat index")
|
return errors.New("invalid seat index")
|
||||||
}
|
}
|
||||||
if t.Seats[seatIndex].Username != "" {
|
if t.Seats[seatIndex].Username != "" {
|
||||||
|
t.mu.Unlock()
|
||||||
return errors.New("seat taken")
|
return errors.New("seat taken")
|
||||||
}
|
}
|
||||||
// Check player not already seated
|
|
||||||
for _, s := range t.Seats {
|
for _, s := range t.Seats {
|
||||||
if s.Username == username {
|
if s.Username == username {
|
||||||
|
t.mu.Unlock()
|
||||||
return errors.New("already seated")
|
return errors.New("already seated")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if buyin < t.Config.MinBuyin || buyin > t.Config.MaxBuyin {
|
if buyin < t.Config.MinBuyin || buyin > t.Config.MaxBuyin {
|
||||||
|
t.mu.Unlock()
|
||||||
return fmt.Errorf("buy-in must be between %d and %d", t.Config.MinBuyin, t.Config.MaxBuyin)
|
return fmt.Errorf("buy-in must be between %d and %d", t.Config.MinBuyin, t.Config.MaxBuyin)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -123,6 +125,7 @@ func (t *Table) Sit(username string, seatIndex int, buyin int64) error {
|
||||||
t.Seats[seatIndex].Stack = buyin
|
t.Seats[seatIndex].Stack = buyin
|
||||||
t.Seats[seatIndex].Folded = false
|
t.Seats[seatIndex].Folded = false
|
||||||
t.Seats[seatIndex].SitOut = false
|
t.Seats[seatIndex].SitOut = false
|
||||||
|
t.mu.Unlock()
|
||||||
|
|
||||||
t.broadcastState()
|
t.broadcastState()
|
||||||
t.maybeStartHand()
|
t.maybeStartHand()
|
||||||
|
|
@ -133,20 +136,21 @@ func (t *Table) Sit(username string, seatIndex int, buyin int64) error {
|
||||||
// Cannot stand mid-hand unless folded.
|
// Cannot stand mid-hand unless folded.
|
||||||
func (t *Table) Stand(username string) (int64, error) {
|
func (t *Table) Stand(username string) (int64, error) {
|
||||||
t.mu.Lock()
|
t.mu.Lock()
|
||||||
defer t.mu.Unlock()
|
|
||||||
|
|
||||||
seat := t.findSeat(username)
|
seat := t.findSeat(username)
|
||||||
if seat == nil {
|
if seat == nil {
|
||||||
|
t.mu.Unlock()
|
||||||
return 0, errors.New("not seated")
|
return 0, errors.New("not seated")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow standing mid-hand only if folded or hand is waiting
|
|
||||||
if t.Hand.Phase != PhaseWaiting && !seat.Folded {
|
if t.Hand.Phase != PhaseWaiting && !seat.Folded {
|
||||||
|
t.mu.Unlock()
|
||||||
return 0, errors.New("cannot stand mid-hand while active")
|
return 0, errors.New("cannot stand mid-hand while active")
|
||||||
}
|
}
|
||||||
|
|
||||||
stack := seat.Stack
|
stack := seat.Stack
|
||||||
*seat = Seat{} // clear seat
|
*seat = Seat{}
|
||||||
|
t.mu.Unlock()
|
||||||
|
|
||||||
t.broadcastState()
|
t.broadcastState()
|
||||||
return stack, nil
|
return stack, nil
|
||||||
}
|
}
|
||||||
|
|
@ -154,19 +158,23 @@ func (t *Table) Stand(username string) (int64, error) {
|
||||||
// TopUp adds chips to a seated player's stack (between hands only).
|
// TopUp adds chips to a seated player's stack (between hands only).
|
||||||
func (t *Table) TopUp(username string, amount int64) error {
|
func (t *Table) TopUp(username string, amount int64) error {
|
||||||
t.mu.Lock()
|
t.mu.Lock()
|
||||||
defer t.mu.Unlock()
|
|
||||||
|
|
||||||
if t.Hand.Phase != PhaseWaiting {
|
if t.Hand.Phase != PhaseWaiting {
|
||||||
|
t.mu.Unlock()
|
||||||
return errors.New("can only top up between hands")
|
return errors.New("can only top up between hands")
|
||||||
}
|
}
|
||||||
seat := t.findSeat(username)
|
seat := t.findSeat(username)
|
||||||
if seat == nil {
|
if seat == nil {
|
||||||
|
t.mu.Unlock()
|
||||||
return errors.New("not seated")
|
return errors.New("not seated")
|
||||||
}
|
}
|
||||||
if seat.Stack+amount > t.Config.MaxBuyin {
|
if seat.Stack+amount > t.Config.MaxBuyin {
|
||||||
|
t.mu.Unlock()
|
||||||
return fmt.Errorf("would exceed max buy-in of %d", t.Config.MaxBuyin)
|
return fmt.Errorf("would exceed max buy-in of %d", t.Config.MaxBuyin)
|
||||||
}
|
}
|
||||||
seat.Stack += amount
|
seat.Stack += amount
|
||||||
|
t.mu.Unlock()
|
||||||
|
|
||||||
t.broadcastState()
|
t.broadcastState()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -274,17 +282,19 @@ const (
|
||||||
// Action processes a player's action. Returns an error if invalid.
|
// Action processes a player's action. Returns an error if invalid.
|
||||||
func (t *Table) Action(username string, action ActionType, amount int64) error {
|
func (t *Table) Action(username string, action ActionType, amount int64) error {
|
||||||
t.mu.Lock()
|
t.mu.Lock()
|
||||||
defer t.mu.Unlock()
|
|
||||||
|
|
||||||
if t.Hand.Phase == PhaseWaiting || t.Hand.Phase == PhaseDealing || t.Hand.Phase == PhaseShowdown {
|
if t.Hand.Phase == PhaseWaiting || t.Hand.Phase == PhaseDealing || t.Hand.Phase == PhaseShowdown {
|
||||||
|
t.mu.Unlock()
|
||||||
return errors.New("no action in current phase")
|
return errors.New("no action in current phase")
|
||||||
}
|
}
|
||||||
|
|
||||||
seatIdx := t.findSeatIndex(username)
|
seatIdx := t.findSeatIndex(username)
|
||||||
if seatIdx < 0 {
|
if seatIdx < 0 {
|
||||||
|
t.mu.Unlock()
|
||||||
return errors.New("not seated")
|
return errors.New("not seated")
|
||||||
}
|
}
|
||||||
if seatIdx != t.Hand.ActionOn {
|
if seatIdx != t.Hand.ActionOn {
|
||||||
|
t.mu.Unlock()
|
||||||
return errors.New("not your turn")
|
return errors.New("not your turn")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -298,12 +308,14 @@ func (t *Table) Action(username string, action ActionType, amount int64) error {
|
||||||
|
|
||||||
case ActionCheck:
|
case ActionCheck:
|
||||||
if seat.Bet < currentBet {
|
if seat.Bet < currentBet {
|
||||||
|
t.mu.Unlock()
|
||||||
return errors.New("cannot check — must call or raise")
|
return errors.New("cannot check — must call or raise")
|
||||||
}
|
}
|
||||||
|
|
||||||
case ActionCall:
|
case ActionCall:
|
||||||
toCall := currentBet - seat.Bet
|
toCall := currentBet - seat.Bet
|
||||||
if toCall <= 0 {
|
if toCall <= 0 {
|
||||||
|
t.mu.Unlock()
|
||||||
return errors.New("nothing to call — check instead")
|
return errors.New("nothing to call — check instead")
|
||||||
}
|
}
|
||||||
if toCall > seat.Stack {
|
if toCall > seat.Stack {
|
||||||
|
|
@ -315,6 +327,7 @@ func (t *Table) Action(username string, action ActionType, amount int64) error {
|
||||||
|
|
||||||
case ActionRaise:
|
case ActionRaise:
|
||||||
if amount < t.Hand.MinRaise {
|
if amount < t.Hand.MinRaise {
|
||||||
|
t.mu.Unlock()
|
||||||
return fmt.Errorf("minimum raise is %d", t.Hand.MinRaise)
|
return fmt.Errorf("minimum raise is %d", t.Hand.MinRaise)
|
||||||
}
|
}
|
||||||
toCall := currentBet - seat.Bet
|
toCall := currentBet - seat.Bet
|
||||||
|
|
@ -330,6 +343,7 @@ func (t *Table) Action(username string, action ActionType, amount int64) error {
|
||||||
t.acted = make(map[string]bool) // raise reopens action
|
t.acted = make(map[string]bool) // raise reopens action
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
t.mu.Unlock()
|
||||||
return fmt.Errorf("unknown action: %s", action)
|
return fmt.Errorf("unknown action: %s", action)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -344,7 +358,6 @@ func (t *Table) Action(username string, action ActionType, amount int64) error {
|
||||||
t.mu.Unlock()
|
t.mu.Unlock()
|
||||||
t.broadcastAction(username, action, amount)
|
t.broadcastAction(username, action, amount)
|
||||||
t.advance()
|
t.advance()
|
||||||
t.mu.Lock()
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue