Document the cross-player persistence lock-ordering invariant
The packet handler funnel now holds each player's persistence lock for the whole handler. Acquiring a second player's lock from inside a handler is therefore a lock-ordering hazard; note the invariant on the guard method so a future cross-player save cannot silently open an AB-BA cycle. Documentation only, no behavioural change.
This commit is contained in:
@@ -1917,6 +1917,14 @@ public class Player : AsyncDisposable, IBucketMapObserver, IAttackable, IAttacke
|
|||||||
/// save fails too, so the whole session is lost on relog. Serializing the packet handler funnel
|
/// save fails too, so the whole session is lost on relog. Serializing the packet handler funnel
|
||||||
/// and the save against each other closes that window. The lock is re-entrant per asynchronous
|
/// and the save against each other closes that window. The lock is re-entrant per asynchronous
|
||||||
/// flow, so an inline save inside an already-serialized handler does not deadlock.
|
/// flow, so an inline save inside an already-serialized handler does not deadlock.
|
||||||
|
/// <para>
|
||||||
|
/// Invariant: never acquire another player's persistence lock (via their
|
||||||
|
/// <see cref="SaveProgressAsync"/> or <see cref="RunPersistenceExclusiveAsync{T}"/>) from inside a
|
||||||
|
/// packet handler, which already holds this player's lock, unless a global lock order is enforced.
|
||||||
|
/// Today only the trade accept does a cross-player save, and it cannot form a cycle because a trade
|
||||||
|
/// has a single accepting side (so the A-then-B acquisition order has no concurrent B-then-A
|
||||||
|
/// counterpart). A second cross-player caller with the opposite order could deadlock.
|
||||||
|
/// </para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <typeparam name="T">The result type of the operation.</typeparam>
|
/// <typeparam name="T">The result type of the operation.</typeparam>
|
||||||
/// <param name="operation">The operation to run exclusively.</param>
|
/// <param name="operation">The operation to run exclusively.</param>
|
||||||
|
|||||||
Reference in New Issue
Block a user