Skip to content

Add SynchronizedBehavior with non-reentrant lock - #283

Closed
kzu wants to merge 2 commits into
mainfrom
synchronized-behavior-271
Closed

kzu wants to merge 2 commits into
mainfrom
synchronized-behavior-271

Conversation

@kzu

@kzu kzu commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

Fixes #271.

SynchronizedBehavior Design

Summary

Adds SynchronizedBehavior, an IStuntBehavior that serializes overlapping calls on a stunt using a standard object lock (normal lock statement semantics, reentrant).

This follows the normal pattern used by Castle DynamicProxy interceptors and .NET in general: lock (syncRoot) { next(); }. No custom lock types, no shared tables.

API

public class SynchronizedBehavior : IStuntBehavior, ICloneable
{
    public SynchronizedBehavior(object? syncRoot = null);
    public bool AppliesTo(IMethodInvocation invocation); // true for all
    public IMethodReturn Execute(IMethodInvocation invocation, ExecuteHandler next);
    public object Clone();
}
  • syncRoot: optional lock object. Default is a private object owned by the behavior, so one behavior locks one stunt. Passing an explicit object lets multiple behaviors coordinate on the same lock (standard lock semantics).
  • Implements ICloneable so BehaviorPipeline.Materialize gives each stunt its own lock by default; an explicit lock object stays shared across clones.

Behavior

flowchart TD
    A[Execute] --> B[lock syncRoot]
    B --> C[next invocation]
    C --> D[return IMethodReturn]
Loading

Simple: acquire the lock, invoke next, release. Reentrant (same thread can re-enter, like Monitor).

Acceptance tests (scenarios)

  • Two overlapping calls run one at a time (barrier + counter).
  • Re-entrant call on same thread succeeds (reentrant lock, no deadlock).
  • Explicit shared lock coordinates two stunts; default does not.

Files

  • src/Stunts/SynchronizedBehavior.cs (new)
  • src/Stunts.UnitTests/Scenarios/Synchronized.cs (new)

Notes

Deviates from the original issue text (which specified non-reentrant): per discussion, we follow the normal .NET/Castle lock semantics (reentrant Monitor).

@kzu
kzu force-pushed the synchronized-behavior-271 branch from e785b26 to 97ed19d Compare October 8, 2026 00:11
@kzu kzu closed this Oct 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a synchronized behavior

1 participant