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); }
/// <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); }
/// <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); }
/// <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)); }
/// <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); } }
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); }
public void touch() { LockingTransaction.GetEx().DoEnsure(this); }
public object alter(IFn fn, ISeq args) { LockingTransaction t = LockingTransaction.GetEx(); return(t.DoSet(this, fn.applyTo(RT.cons(t.DoGet(this), args)))); }
public object commute(IFn fn, ISeq args) { return(LockingTransaction.GetEx().DoCommute(this, fn, args)); }
public object set(object val) { return(LockingTransaction.GetEx().DoSet(this, val)); }
/// <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); }
/// <summary> /// Touch the reference. (Add to the tracking list in the current transaction.) /// </summary> public void touch() { LockingTransaction.getEx().doTouch(this); }