Example #1
0
    public void AsCancellationToken()
    {
        ((CancellationToken)Lifetime.Immortal).CanBeCanceled.AssertIsFalse();
        ((CancellationToken)Lifetime.Dead).IsCancellationRequested.AssertIsTrue();

        // cancelled on death
        var doomed           = new LifetimeSource();
        CancellationToken dt = doomed.Lifetime;

        dt.CanBeCanceled.AssertIsTrue();
        dt.IsCancellationRequested.AssertIsFalse();
        doomed.EndLifetime();
        dt.IsCancellationRequested.AssertIsTrue();
        // already cancelled when already dead
        ((CancellationToken)doomed.Lifetime).IsCancellationRequested.AssertIsTrue();

        // hangs on immortal
        var blessed          = new LifetimeSource();
        CancellationToken bt = blessed.Lifetime;

        bt.CanBeCanceled.AssertIsTrue();
        bt.IsCancellationRequested.AssertIsFalse();
        blessed.ImmortalizeLifetime();
        bt.IsCancellationRequested.AssertIsFalse();
        // knows can't be cancelled when already immortal
        ((CancellationToken)blessed.Lifetime).CanBeCanceled.AssertIsFalse();

        // hangs on limbo
        InvalidCallbackMaker.AssertNotCollectedAfter(action => {
            var r = new LifetimeSource();
            CancellationToken ct = r.Lifetime;
            ct.Register(action);
            return(ct);
        });
    }
    public void Max()
    {
        Lifetime.Dead.Max(Lifetime.Dead).IsDead.AssertIsTrue();
        Lifetime.Dead.Max(Lifetime.Immortal).IsImmortal.AssertIsTrue();
        Lifetime.Immortal.Max(Lifetime.Dead).IsImmortal.AssertIsTrue();
        Lifetime.Immortal.Max(Lifetime.Immortal).IsImmortal.AssertIsTrue();

        var s1 = new LifetimeSource();
        var s2 = new LifetimeSource();
        var s3 = new LifetimeSource();
        var m1 = s1.Lifetime.Max(s2.Lifetime);
        var m2 = s1.Lifetime.Max(s3.Lifetime);
        var m3 = s2.Lifetime.Max(s3.Lifetime);
        var t1 = m1.WhenDeadTask();
        var t2 = m2.WhenDeadTask();
        var t3 = m3.WhenDeadTask();

        // equality optimization
        s1.Lifetime.Max(s1.Lifetime).AssertEquals(s1.Lifetime);
        m1.Max(m1).AssertEquals(m1);
        // dead optimization
        s1.Lifetime.Max(Lifetime.Dead).AssertEquals(s1.Lifetime);
        Lifetime.Dead.Max(m1).AssertEquals(m1);

        // when one becomes immortal, max becomes immortal
        (m1.IsImmortal || m1.IsDead).AssertIsFalse();
        (m2.IsImmortal || m2.IsDead).AssertIsFalse();
        s1.ImmortalizeLifetime();
        m1.IsImmortal.AssertIsTrue();
        m2.IsImmortal.AssertIsTrue();

        // when one becomes dead, max is unaffected
        s2.EndLifetime();

        // when both become dead, max is dead
        (m3.IsImmortal || m3.IsDead).AssertIsFalse();
        t3.AssertNotCompleted();
        s3.EndLifetime();
        m3.IsDead.AssertIsTrue();
        t3.AssertRanToCompletion();

        Task.WhenAny(t1, t2).AssertNotCompleted();

        // limbo allows collection
        InvalidCallbackMaker.AssertCollectedAfter(a => {
            var r1    = new LifetimeSource();
            var r2    = new LifetimeSource();
            var r3    = new LifetimeSource();
            var life1 = r1.Lifetime.Max(r2.Lifetime);
            var life2 = r1.Lifetime.Max(r3.Lifetime);
            var life3 = r2.Lifetime.Max(r3.Lifetime);
            life1.WhenDead(a);
            life2.WhenDead(a);
            life3.WhenDead(a);
            r1.EndLifetime(); // one dead has no effect on max going to limbo
            return(Tuple.Create(life1, life2, life3));
        });
    }
Example #3
0
    public void LifetimeImmortalityConcurrency()
    {
        var repeats = 5;

        foreach (var _ in Enumerable.Range(0, repeats))
        {
            var n      = 0;
            var source = new LifetimeSource();
            TestUtil.ConcurrencyTest(
                threadCount: 4,
                callbackCount: 3000,
                repeatedWork: (t, i) => source.Lifetime.WhenDead(() => Interlocked.Increment(ref n)),
                finalWork: t => source.ImmortalizeLifetime());
            n.AssertEquals(0);
        }
    }
Example #4
0
    public void Status()
    {
        // status of constants
        Lifetime.Immortal.IsMortal.AssertIsFalse();
        Lifetime.Immortal.IsImmortal.AssertIsTrue();
        Lifetime.Immortal.IsDead.AssertIsFalse();
        Lifetime.Dead.IsMortal.AssertIsFalse();
        Lifetime.Dead.IsImmortal.AssertIsFalse();
        Lifetime.Dead.IsDead.AssertIsTrue();

        // state before transition
        var mortal = new LifetimeSource();

        mortal.Lifetime.IsMortal.AssertIsTrue();
        mortal.Lifetime.IsImmortal.AssertIsFalse();
        mortal.Lifetime.IsDead.AssertIsFalse();

        // transition to dead
        var doomed = new LifetimeSource();

        doomed.EndLifetime();
        doomed.Lifetime.IsMortal.AssertIsFalse();
        doomed.Lifetime.IsImmortal.AssertIsFalse();
        doomed.Lifetime.IsDead.AssertIsTrue();

        // transition to immortal
        var blessed = new LifetimeSource();

        blessed.ImmortalizeLifetime();
        blessed.Lifetime.IsMortal.AssertIsFalse();
        blessed.Lifetime.IsImmortal.AssertIsTrue();
        blessed.Lifetime.IsDead.AssertIsFalse();

        // transition to immortal via limbo
        var limbo = new LimboLife();

        limbo.Dispose();
        GC.Collect();
        limbo.Lifetime.IsMortal.AssertIsFalse();
        limbo.Lifetime.IsImmortal.AssertIsTrue();
        limbo.Lifetime.IsDead.AssertIsFalse();
    }
Example #5
0
    public void WhenSet()
    {
        // called when immortal?
        var blessed        = new LifetimeSource();
        var preBlessedLife = blessed.Lifetime.WhenDeadTask();

        blessed.ImmortalizeLifetime();
        var bt = new[] {
            Lifetime.Immortal.WhenDeadTask(),
            blessed.Lifetime.WhenDeadTask(),
            preBlessedLife
        };

        Task.WhenAny(bt).AssertNotCompleted();

        // called when dead?
        var doomed        = new LifetimeSource();
        var preDoomedLife = doomed.Lifetime.WhenDeadTask();

        doomed.EndLifetime();
        var dt = new[] {
            preDoomedLife,
            doomed.Lifetime.WhenDeadTask(),
            Lifetime.Dead.WhenDeadTask()
        };

        Task.WhenAll(dt).AssertRanToCompletion();

        // never called from limbo
        var limboed      = new LimboLife();
        var preLimboLife = limboed.Lifetime.WhenDeadTask();

        limboed.Dispose();
        Task.WhenAny(
            preLimboLife,
            limboed.Lifetime.WhenDeadTask()
            ).AssertNotCompleted();
    }
Example #6
0
    public static void Main()
    {
        "=== Hit 'Enter' to advance ===".WriteLine();
        Break();

        ///////////////////////////////////////////////////
        "Manually inspecting a lifetime as it is killed:".WriteLine();
        var lifesource1 = new LifetimeSource();

        "Life #1: {0}".WriteLine(lifesource1);
        "Ending Life #1".WriteLine();
        lifesource1.EndLifetime();
        "Life #1: {0}".WriteLine(lifesource1);
        Break();

        ///////////////////////////////////////////////////
        "Manually inspecting a lifetime as it is immortalized:".WriteLine();
        var lifesource2 = new LifetimeSource();

        "Life #2: {0}".WriteLine(lifesource2);
        "Immortalizing Life #2".WriteLine();
        lifesource2.ImmortalizeLifetime();
        "Life #2: {0}".WriteLine(lifesource2);
        Break();

        ///////////////////////////////////////////////////
        "Using callbacks to inspect a lifetime as it is killed:".WriteLine();
        var lifesource3 = new LifetimeSource();

        "Life #3: {0}".WriteLine(lifesource3);
        "Registering WhenDead Life #3 (before)".WriteLine();
        lifesource3.Lifetime.WhenDead(() => "WhenDead Life #3 (before)".WriteLine());
        "Ending Life #3".WriteLine();
        lifesource3.EndLifetime();
        "Life #3: {0}".WriteLine(lifesource3);
        "Registering WhenDead Life #3 (after)".WriteLine();
        lifesource3.Lifetime.WhenDead(() => "WhenDead Life #3 (after)".WriteLine());
        Break();

        ///////////////////////////////////////////////////
        "Using conditional callbacks:".WriteLine();
        var lifesource4 = new LifetimeSource();
        var lifesource5 = new LifetimeSource();

        "Life #4: {0}".WriteLine(lifesource4);
        "Life #5: {0}".WriteLine(lifesource5);
        "Registering WhenDead 4 (requires 5)".WriteLine();
        lifesource4.Lifetime.WhenDead(
            () => "Running WhenDead 4 (requires 5)".WriteLine(),
            lifesource5.Lifetime);
        "Registering WhenDead 5 (requires 4)".WriteLine();
        lifesource5.Lifetime.WhenDead(
            () => "Running WhenDead 5 (requires 4)".WriteLine(),
            lifesource4.Lifetime);
        "Ending Life #4".WriteLine();
        lifesource4.EndLifetime();
        "Life #4: {0}".WriteLine(lifesource4);
        "Ending Life #5".WriteLine();
        lifesource5.EndLifetime();
        "Life #5: {0}".WriteLine(lifesource5);
        Break();

        ///////////////////////////////////////////////////
        CallbackGarbageTest(
            "Immortal Lifetime collectable callback test:",
            () => new LifetimeSource().Lifetime,
            (e, a) => e.WhenDead(a));
        ///////////////////////////////////////////////////
        var lifetimeMortal = new LifetimeSource();

        CallbackGarbageTest(
            "Conditioned-on-dying Lifetime collectable callback test:",
            () => lifetimeMortal.Lifetime,
            (e, a) => {
            var r = new LifetimeSource();
            e.WhenDead(a, r.Lifetime);
            r.EndLifetime();
        });
        GC.KeepAlive(lifetimeMortal);
        ///////////////////////////////////////////////////
        CallbackGarbageTest(
            "Immortal CancellationToken collectable callback test:",
            () => new CancellationTokenSource().Token,
            (e, a) => e.Register(a));

        ///////////////////////////////////////////////////
        "Garbage collection of a lifetime's source:".WriteLine();
        var lifesource6 = new LifetimeSource();
        var life6       = lifesource6.Lifetime;

        "Life #6: {0}".WriteLine(life6);
        "Allowing garbage collection of Life #6's source".WriteLine();
        lifesource6 = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();
        "Life #6: {0}".WriteLine(life6);
        Break();

        ///////////////////////////////////////////////////
        "=== Hit 'Enter' to close ===".WriteLine();
        Break();
    }
Example #7
0
 public void Dispose()
 {
     _source.ImmortalizeLifetime();
 }