Provides transaction semantics for Agents, Refs, etc.
Пример #1
0
        public static object runInTransaction(IFn fn)
        {
            // TODO: This can be called on something more general than  an IFn.
            // We can could define a delegate for this, probably use ThreadStartDelegate.
            // Should still have a version that takes IFn.
            LockingTransaction t = _transaction;
            Object             ret;

            if (t == null)
            {
                _transaction = t = new LockingTransaction();
                try
                {
                    ret = t.Run(fn);
                }
                finally
                {
                    _transaction = null;
                }
            }
            else
            {
                if (t._info != null)
                {
                    ret = fn.invoke();
                }
                else
                {
                    ret = t.Run(fn);
                }
            }

            return(ret);
        }
Пример #2
0
        /// <summary>
        /// Get the transaction running on this thread (or null if no transaction).
        /// </summary>
        /// <returns>The running transaction if there is one, else <value>null</value>.</returns>
        static internal LockingTransaction GetRunning()
        {
            LockingTransaction t = _transaction;

            if (t == null || t._info == null)
            {
                return(null);
            }
            return(t);
        }
Пример #3
0
        /// <summary>
        /// Get the transaction running on this thread (throw exception if no transaction).
        /// </summary>
        /// <returns>The running transaction.</returns>
        public static LockingTransaction GetEx()
        {
            LockingTransaction t = _transaction;

            if (t == null || t._info == null)
            {
                throw new InvalidOperationException("No transaction running");
            }
            return(t);
        }
Пример #4
0
        /// <summary>
        /// Gets the (immutable) value the reference is holding.
        /// </summary>
        /// <returns>The value</returns>
        public override object deref()
        {
            LockingTransaction t = LockingTransaction.GetRunning();

            if (t == null)
            {
                object ret = currentVal();
                //Console.WriteLine("Thr {0}, {1}: No-trans get => {2}", Thread.CurrentThread.ManagedThreadId,DebugStr(), ret);
                return(ret);
            }
            return(t.DoGet(this));
        }
Пример #5
0
        /// <summary>
        /// Send an action (encapsulated message).
        /// </summary>
        /// <param name="action">The action to execute.</param>
        /// <remarks>
        /// <para>If there is a transaction running on this thread,
        /// defer execution until the transaction ends
        /// (enqueue the action on the transaction).</para>
        /// <para>If there is already an action running, enqueue it (nested).</para>
        /// <para>Otherwise, queue it for execution.</para>
        /// </remarks>
        internal static void DispatchAction(Action action)
        {
            LockingTransaction trans = LockingTransaction.getRunning();

            if (trans != null)
            {
                trans.enqueue(action);
            }
            else if (_nested != null)
            {
                _nested = _nested.cons(action);
            }
            else
            {
                action.Agent.Enqueue(action);
            }
        }
Пример #6
0
        public static object runInTransaction(IFn fn)
        {
            // TODO: This can be called on something more general than  an IFn.
            // We can could define a delegate for this, probably use ThreadStartDelegate.
            // Should still have a version that takes IFn.
            LockingTransaction t = _transaction;
            if (t == null)
                _transaction = t = new LockingTransaction();

            if (t._info != null)
                return fn.invoke();

            return t.Run(fn);
        }
Пример #7
0
 public void touch()
 {
     LockingTransaction.GetEx().DoEnsure(this);
 }
Пример #8
0
        public object alter(IFn fn, ISeq args)
        {
            LockingTransaction t = LockingTransaction.GetEx();

            return(t.DoSet(this, fn.applyTo(RT.cons(t.DoGet(this), args))));
        }
Пример #9
0
 public object commute(IFn fn, ISeq args)
 {
     return(LockingTransaction.GetEx().DoCommute(this, fn, args));
 }
Пример #10
0
 public object set(object val)
 {
     return(LockingTransaction.GetEx().DoSet(this, val));
 }
Пример #11
0
        /// <summary>
        /// Invoke a function in a transaction
        /// </summary>
        /// <param name="fn">The function to invoke.</param>
        /// <returns>The value computed by the function.</returns>
        public static object runInTransaction(IFn fn)
        {
            LockingTransaction t = _transaction;
            if (t == null)
                _transaction = t = new LockingTransaction();

            if (t._info != null)
                return fn.invoke();

            return t.run(fn);
        }
Пример #12
0
 /// <summary>
 /// Touch the reference.  (Add to the tracking list in the current transaction.)
 /// </summary>
 public void touch()
 {
     LockingTransaction.getEx().doTouch(this);
 }