Beispiel #1
0
        public static LifetimeDefinition Define(OuterLifetime lifetime, [CanBeNull] string id = null, [CanBeNull][InstantHandle] Action <LifetimeDefinition, Lifetime> atomicAction = null)
        {
            lifetime.AssertNotNull();

            // Fallback to defaults
            if (String.IsNullOrEmpty(id))
            {
                id = LifetimeDefinition.AnonymousLifetimeId;
            }

//      var nested = new LifetimeDefinition(id, 0, logger ?? Log.Root);
            var nested = new LifetimeDefinition {
                Id = id
            } /*{ Logger = logger ?? Log.Root }*/;

            try
            {
                // Atomic init on the new lifetime
                atomicAction?.Invoke(nested, nested.Lifetime);

                // Attach as nested to the parent lifetime
//        if(!nested.IsTerminated) // Might have been terminated by FAtomic
                lifetime.Def.Attach(nested); // Pass True: might be terminated async on another thread between our check and AttachNested body (example: Queue from another thread)
            }
            catch
            {
                nested.Terminate();
                throw;
            }
            return(nested);
        }
Beispiel #2
0
        /// <summary>
        /// Terminates current lifetime and starts new.
        /// </summary>
        /// <returns>New lifetime. Note, In case of a race condition this lifetime might be terminated.</returns>
        public Lifetime Next()
        {
            TerminateCurrent();
            var next = new LifetimeDefinition(myParentLifetime);

            return(TrySetNewAndTerminateOld(next).Lifetime);
        }
Beispiel #3
0
        /// <summary>
        ///   <para>Scopes your code in <paramref name="action" /> with a lifetime that is terminated automatically when <paramref name="action" /> completes execution, or when its execution is aborted by an exception.</para>
        ///   <para>Analogous to the <c>using</c> statement of the C# language on everything that is added to the lifetime.</para>
        /// </summary>
        /// <param name="action">The code to execute with a temporary lifetime.</param>
        public static async Task <T> UsingAsync <T>([NotNull][InstantHandle] Func <Lifetime, Task <T> > action)
        {
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            using (var def = new LifetimeDefinition())
                return(await action(def.Lifetime));
        }
Beispiel #4
0
        public static T Using <T>([NotNull, InstantHandle] Func <Lifetime, T> action)
        {
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            using (var def = new LifetimeDefinition())
                return(action(def.Lifetime));
        }
Beispiel #5
0
        public static void Using([NotNull, InstantHandle] Action <Lifetime> action)
        {
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            using (var def = new LifetimeDefinition())
                action(def.Lifetime);
        }
Beispiel #6
0
        public static LifetimeDefinition DefineIntersection([NotNull] params OuterLifetime[] lifetimes)
        {
            var res = new LifetimeDefinition();

            foreach (var lf in lifetimes)
            {
                lf.Def.Attach(res);
            }

            return(res);
        }
Beispiel #7
0
        /// <summary>
        /// Terminates the current lifetime and calls your handler with the new lifetime.
        /// </summary>
        public void Next([NotNull] Action <Lifetime> atomicAction)
        {
            if (atomicAction == null)
            {
                throw new ArgumentNullException(nameof(atomicAction));
            }
            TerminateCurrent();
            var next = new LifetimeDefinition(myParentLifetime, atomicAction);

            SetNextAndTerminateCurrent(next);
        }
Beispiel #8
0
        /// <summary>
        /// Terminates the current lifetime, calls your handler with the new lifetime and tries to set it as current.
        /// Similar to <see cref="Next(System.Action{JetBrains.Lifetimes.Lifetime})"/>
        /// </summary>
        public void DefineNext([NotNull] Action <LifetimeDefinition> atomicAction)
        {
            if (atomicAction == null)
            {
                throw new ArgumentNullException(nameof(atomicAction));
            }

            TerminateCurrent();
            var next = new LifetimeDefinition(myParentLifetime);

            TrySetNewAndTerminateOld(next, definition => definition.ExecuteOrTerminateOnFail(atomicAction));
        }
Beispiel #9
0
        public static LifetimeDefinition DefineIntersection(Lifetime lifetime1, Lifetime lifetime2) //reduces memory traffic
        {
            if (lifetime1.Status >= LifetimeStatus.Terminating || lifetime2.Status >= LifetimeStatus.Terminating)
            {
                return(LifetimeDefinition.Terminated);
            }

            var res = new LifetimeDefinition();

            lifetime1.Definition.Attach(res);
            lifetime2.Definition.Attach(res);
            return(res);
        }
Beispiel #10
0
        /// <summary>
        ///   <para>Scopes your code in <paramref name="action" /> with a lifetime that is terminated automatically when <paramref name="action" /> completes execution, or when its execution is aborted by an exception.</para>
        ///   <para>Analogous to the <c>using</c> statement of the C# language on everything that is added to the lifetime.</para>
        /// </summary>
        /// <param name="parent">A parent lifetime which limits the lifetime given to your action, and migth terminate it before the action ends.</param>
        /// <param name="action">The code to execute with a temporary lifetime.</param>
        public static async Task UsingAsync(OuterLifetime parent, [NotNull][InstantHandle] Func <Lifetime, Task> action)
        {
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            using (var def = new LifetimeDefinition())
            {
                parent.Def.Attach(def);
                await action(def.Lifetime);
            }
        }
Beispiel #11
0
        public static LifetimeDefinition DefineIntersection([NotNull] params Lifetime[] lifetimes)
        {
            if (lifetimes == null)
            {
                throw new ArgumentNullException(nameof(lifetimes));
            }

            var res = new LifetimeDefinition();

            foreach (var lf in lifetimes)
            {
                lf.Definition.Attach(res);
            }

            return(res);
        }
Beispiel #12
0
        /// <summary>
        /// Atomically, assigns the new lifetime and terminates the old one.
        /// </summary>

        private LifetimeDefinition SetNextAndTerminateCurrent([NotNull] LifetimeDefinition def)
        {
            var old = Interlocked.Exchange(ref myCurrentDef, def);

            try
            {
                old.AllowTerminationUnderExecution = true;
                old.Terminate();
            }
            catch (Exception ex)
            {
                Log.Root.Error(ex);
            }

            return(def);
        }
Beispiel #13
0
        /// <summary>
        /// Atomically, assigns the new lifetime and terminates the old one.
        /// In case of a race condition when current lifetime is overwritten new lifetime is terminated
        /// </summary>
        /// <param name="newLifetimeDefinition">New lifetime definition to set</param>
        /// <param name="actionWithNewLifetime">Action to perform once new lifetime is set</param>
        /// <returns>New lifetime definition which can be terminated in case of a race condition</returns>
        private LifetimeDefinition TrySetNewAndTerminateOld(LifetimeDefinition newLifetimeDefinition, [CanBeNull] Action <LifetimeDefinition> actionWithNewLifetime = null)
        {
            void TerminateLifetimeDefinition(LifetimeDefinition lifetimeDefinition)
            {
                lifetimeDefinition.AllowTerminationUnderExecution = true;
                lifetimeDefinition.Terminate();
            }

            // temporary lifetime definition to cope with race condition
            var tempLifetimeDefinition = new LifetimeDefinition(myParentLifetime);

            // the lifetime needs to be terminated but LifetimeDefinition.Terminated cannot be used as we will use Interlocked.CompareExchange
            tempLifetimeDefinition.Terminate();

            var old = Interlocked.Exchange(ref myCurrentDef, tempLifetimeDefinition);

            try
            {
                TerminateLifetimeDefinition(old);
            }
            catch (Exception e)
            {
                Log.Root.Error(e);
            }

            try
            {
                actionWithNewLifetime?.Invoke(newLifetimeDefinition);
            }
            finally
            {
                if (Interlocked.CompareExchange(ref myCurrentDef, newLifetimeDefinition, tempLifetimeDefinition) != tempLifetimeDefinition)
                {
                    TerminateLifetimeDefinition(newLifetimeDefinition);
                }
            }

            return(newLifetimeDefinition);
        }
Beispiel #14
0
 //ctor
 internal Lifetime([NotNull] LifetimeDefinition definition)
 {
     myDefinition = definition;
 }
Beispiel #15
0
 //ctor
 internal Lifetime([NotNull] LifetimeDefinition def)
 {
     myDef = def;
 }