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.
|
||||
func (t *Table) Sit(username string, seatIndex int, buyin int64) error {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
|
||||
if seatIndex < 0 || seatIndex >= len(t.Seats) {
|
||||
t.mu.Unlock()
|
||||
return errors.New("invalid seat index")
|
||||
}
|
||||
if t.Seats[seatIndex].Username != "" {
|
||||
t.mu.Unlock()
|
||||
return errors.New("seat taken")
|
||||
}
|
||||
// Check player not already seated
|
||||
for _, s := range t.Seats {
|
||||
if s.Username == username {
|
||||
t.mu.Unlock()
|
||||
return errors.New("already seated")
|
||||
}
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
|
|
@ -123,6 +125,7 @@ func (t *Table) Sit(username string, seatIndex int, buyin int64) error {
|
|||
t.Seats[seatIndex].Stack = buyin
|
||||
t.Seats[seatIndex].Folded = false
|
||||
t.Seats[seatIndex].SitOut = false
|
||||
t.mu.Unlock()
|
||||
|
||||
t.broadcastState()
|
||||
t.maybeStartHand()
|
||||
|
|
@ -133,20 +136,21 @@ func (t *Table) Sit(username string, seatIndex int, buyin int64) error {
|
|||
// Cannot stand mid-hand unless folded.
|
||||
func (t *Table) Stand(username string) (int64, error) {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
|
||||
seat := t.findSeat(username)
|
||||
if seat == nil {
|
||||
t.mu.Unlock()
|
||||
return 0, errors.New("not seated")
|
||||
}
|
||||
|
||||
// Allow standing mid-hand only if folded or hand is waiting
|
||||
if t.Hand.Phase != PhaseWaiting && !seat.Folded {
|
||||
t.mu.Unlock()
|
||||
return 0, errors.New("cannot stand mid-hand while active")
|
||||
}
|
||||
|
||||
stack := seat.Stack
|
||||
*seat = Seat{} // clear seat
|
||||
*seat = Seat{}
|
||||
t.mu.Unlock()
|
||||
|
||||
t.broadcastState()
|
||||
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).
|
||||
func (t *Table) TopUp(username string, amount int64) error {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
|
||||
if t.Hand.Phase != PhaseWaiting {
|
||||
t.mu.Unlock()
|
||||
return errors.New("can only top up between hands")
|
||||
}
|
||||
seat := t.findSeat(username)
|
||||
if seat == nil {
|
||||
t.mu.Unlock()
|
||||
return errors.New("not seated")
|
||||
}
|
||||
if seat.Stack+amount > t.Config.MaxBuyin {
|
||||
t.mu.Unlock()
|
||||
return fmt.Errorf("would exceed max buy-in of %d", t.Config.MaxBuyin)
|
||||
}
|
||||
seat.Stack += amount
|
||||
t.mu.Unlock()
|
||||
|
||||
t.broadcastState()
|
||||
return nil
|
||||
}
|
||||
|
|
@ -274,17 +282,19 @@ const (
|
|||
// Action processes a player's action. Returns an error if invalid.
|
||||
func (t *Table) Action(username string, action ActionType, amount int64) error {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
|
||||
if t.Hand.Phase == PhaseWaiting || t.Hand.Phase == PhaseDealing || t.Hand.Phase == PhaseShowdown {
|
||||
t.mu.Unlock()
|
||||
return errors.New("no action in current phase")
|
||||
}
|
||||
|
||||
seatIdx := t.findSeatIndex(username)
|
||||
if seatIdx < 0 {
|
||||
t.mu.Unlock()
|
||||
return errors.New("not seated")
|
||||
}
|
||||
if seatIdx != t.Hand.ActionOn {
|
||||
t.mu.Unlock()
|
||||
return errors.New("not your turn")
|
||||
}
|
||||
|
||||
|
|
@ -298,12 +308,14 @@ func (t *Table) Action(username string, action ActionType, amount int64) error {
|
|||
|
||||
case ActionCheck:
|
||||
if seat.Bet < currentBet {
|
||||
t.mu.Unlock()
|
||||
return errors.New("cannot check — must call or raise")
|
||||
}
|
||||
|
||||
case ActionCall:
|
||||
toCall := currentBet - seat.Bet
|
||||
if toCall <= 0 {
|
||||
t.mu.Unlock()
|
||||
return errors.New("nothing to call — check instead")
|
||||
}
|
||||
if toCall > seat.Stack {
|
||||
|
|
@ -315,6 +327,7 @@ func (t *Table) Action(username string, action ActionType, amount int64) error {
|
|||
|
||||
case ActionRaise:
|
||||
if amount < t.Hand.MinRaise {
|
||||
t.mu.Unlock()
|
||||
return fmt.Errorf("minimum raise is %d", t.Hand.MinRaise)
|
||||
}
|
||||
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
|
||||
|
||||
default:
|
||||
t.mu.Unlock()
|
||||
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.broadcastAction(username, action, amount)
|
||||
t.advance()
|
||||
t.mu.Lock()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue