From 6536261d9941ee32fc6376bfc8caa0f81a42e913 Mon Sep 17 00:00:00 2001 From: uiosun Date: Mon, 4 Mar 2024 21:08:55 +0800 Subject: [PATCH] fix deadlock when clear client --- README.md | 3 +-- swr/act_wiz.go | 2 +- swr/db.go | 10 ++++++---- swr/fight.go | 2 +- swr/item.go | 2 +- swr/net.go | 2 -- 6 files changed, 10 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 9a28ac1..512f6ef 100644 --- a/README.md +++ b/README.md @@ -14,10 +14,9 @@ Growing up I used to play muds. I loved them. There was a mud called SWR based o that recreated the Star Wars universe in text based form. It was pretty good and other muds formed by forking the source and adding their contributions. -SWR is a reimagining of that codebase without the merc/diku/smaug legacy. Instead it's a pure go mud with some javascript for scripting +SWR is a reimagining of that codebase without the merc/diku/smaug legacy. Instead, it's a pure go mud with some javascript for scripting that is more flexible and robust than the C mud engines of old. - ## Features - TELNET echo/no-echo - ANSI Colors diff --git a/swr/act_wiz.go b/swr/act_wiz.go index fd76409..d291fb0 100644 --- a/swr/act_wiz.go +++ b/swr/act_wiz.go @@ -1005,7 +1005,7 @@ func do_mob_remove(entity Entity, args ...string) { return } tch := target.GetCharData() - DB().RemoveEntity(target) + DB().RemoveEntity(target, false) delete(DB().mobs, tch.OId) err := os.Remove(tch.Filename) ErrorCheck(err) diff --git a/swr/db.go b/swr/db.go index 556250d..063be7f 100644 --- a/swr/db.go +++ b/swr/db.go @@ -112,7 +112,7 @@ func (d *GameDatabase) RemoveClient(client Client) { p := e.(*PlayerProfile) if p.Client != nil { if p.Client == client { - d.RemoveEntity(e) + d.RemoveEntity(e, true) } } } @@ -134,9 +134,11 @@ func (d *GameDatabase) RemoveClient(client Client) { } } -func (d *GameDatabase) RemoveEntity(entity Entity) { - d.Lock() - defer d.Unlock() +func (d *GameDatabase) RemoveEntity(entity Entity, isLocked bool) { + if !isLocked { + d.Lock() + defer d.Unlock() + } if entity == nil { return } diff --git a/swr/fight.go b/swr/fight.go index 98d8f70..41009b3 100644 --- a/swr/fight.go +++ b/swr/fight.go @@ -293,7 +293,7 @@ func make_corpse(entity Entity) { DB().SavePlayerData(entity.(*PlayerProfile)) return } else { - DB().RemoveEntity(entity) + DB().RemoveEntity(entity, false) } } } diff --git a/swr/item.go b/swr/item.go index 2aa2492..c8af98a 100644 --- a/swr/item.go +++ b/swr/item.go @@ -84,7 +84,7 @@ type ItemData struct { Type string `yaml:"type"` // item type, a value of ITEM_TYPE_* const. Value int `yaml:"value"` // how much is this item generally worth? Weight int `yaml:"weight"` // how much does this item weigh? - AC int `yaml:"ac,omitempty"` // If armor, what's the AC (common AC values are 1-8 for torso, 2-3 for hands/head/feet, 0-1 for waist) + AC int `yaml:"ac,omitempty"` // If armored, what's the AC (common AC values are 1-8 for torso, 2-3 for hands/head/feet, 0-1 for waist) WearLoc *string `yaml:"wearLoc,omitempty"` // where is this item worn? nil means it's not wearable. WeaponType *string `yaml:"weaponType,omitempty"` // weapon type from ITEM_WEAPON_TYPE_* const, nil means it's not a weapon. Dmg *string `yaml:"dmgRoll,omitempty"` // Damage roll represented by a D20 compatible string. Weapons do damage. diff --git a/swr/net.go b/swr/net.go index 34a85ca..7168919 100644 --- a/swr/net.go +++ b/swr/net.go @@ -95,7 +95,6 @@ func (c *TCPClient) Read() string { i, err := c.Con.Read(b) if err != nil { c.Close() - c.Con.Close() return buf } if i > 0 { @@ -205,7 +204,6 @@ func ServerStart(addr string) { go acceptClient(c) log.Printf("Accepted client connection from %s", c.RemoteAddr()) } - } ServerRunning = false }