internal static Transaction FindOrCreatePromotedTransaction(Guid transactionIdentifier, DistributedTransaction dtx) { Transaction?tx = null; Hashtable promotedTransactionTable = PromotedTransactionTable; lock (promotedTransactionTable) { WeakReference?weakRef = (WeakReference?)promotedTransactionTable[transactionIdentifier]; if (null != weakRef) { tx = weakRef.Target as Transaction; if (null != tx) { // If we found a transaction then dispose it dtx.Dispose(); return(tx.InternalClone()); } else { // an old, moldy weak reference. Let's get rid of it. lock (promotedTransactionTable) { promotedTransactionTable.Remove(transactionIdentifier); } } } tx = new Transaction(dtx); // Since we are adding this reference to the table create an object that will clean that entry up. tx._internalTransaction._finalizedObject = new FinalizedObject(tx._internalTransaction, dtx.Identifier); weakRef = new WeakReference(tx, false); promotedTransactionTable[dtx.Identifier] = weakRef; } dtx.SavedLtmPromotedTransaction = tx; FireDistributedTransactionStarted(tx); return(tx); }
/// <inheritdoc/> public void Attach(DataGrid aDataGrid) { var dataGrid = aDataGrid ?? throw new ArgumentNullException(nameof(aDataGrid)); var savedDataGrid = DataGrid; if (savedDataGrid != null && !ReferenceEquals(savedDataGrid, dataGrid)) { throw new InvalidOperationException($"Another DataGrid is already attached to this {nameof(DataGridColumnStylesHelperExtension)}"); } dataGridReference = new WeakReference(dataGrid); dataGrid.Columns.CollectionChanged -= OnColumnsCollectionChanged; dataGrid.Columns.CollectionChanged += OnColumnsCollectionChanged; foreach (var column in dataGrid.Columns) { BindColumnStyles(column); } }
public static void RemoveEventHandler <TInterface, TImplementor> ( ref WeakReference?implementor, Func <TImplementor, bool> empty, Action <TInterface?> setListener, Action <TImplementor> remove) where TImplementor : Java.Lang.Object, TInterface where TInterface : class { TImplementor?impl = null; if (implementor == null || (impl = (TImplementor?)implementor.Target) == null) { return; } remove(impl); if (empty(impl)) { impl = null; implementor = null; setListener(impl); } }
public void Should_Hold_Debounce_References_Weakly() { WeakReference?sampleRef = null; WeakReference?sampleRef2 = null; new Action(() => { var sample = new DebouncingSample(); var sample2 = new DebouncingSample(); sampleRef = new WeakReference(sample); sampleRef2 = new WeakReference(sample2); sample.DebounceHere(); sample2.DebounceHere(); }).Invoke(); GC.Collect(); Assert.False(sampleRef !.IsAlive); Assert.False(sampleRef2 !.IsAlive); }
internal static Transaction?FindPromotedTransaction(Guid transactionIdentifier) { Hashtable promotedTransactionTable = PromotedTransactionTable; WeakReference?weakRef = (WeakReference?)promotedTransactionTable[transactionIdentifier]; if (null != weakRef) { if (weakRef.Target is Transaction tx) { return(tx.InternalClone()); } else // an old, moldy weak reference. Let's get rid of it. { lock (promotedTransactionTable) { promotedTransactionTable.Remove(transactionIdentifier); } } } return(null); }
void SetCALayerDelegate(CALayerDelegate?value) { // Remove ourselves from any existing CALayerDelegate. if (calayerdelegate != null) { var del = (CALayerDelegate?)calayerdelegate.Target; if (del == value) { return; } del?.SetCALayer(null); } // Tell the new CALayerDelegate about ourselves if (value == null) { calayerdelegate = null; } else { calayerdelegate = new WeakReference(value); value.SetCALayer(this); } }
/*protected virtual*/ internal OleDbHResult RollbackInternal(bool exceptionHandling) { OleDbHResult hr = 0; if (null != _transaction) { if (null != _nestedTransaction) { OleDbTransaction?transaction = (OleDbTransaction?)_nestedTransaction.Target; if ((null != transaction) && _nestedTransaction.IsAlive) { hr = transaction.RollbackInternal(exceptionHandling); if (exceptionHandling && (hr < 0)) { SafeNativeMethods.Wrapper.ClearErrorInfo(); return(hr); } } _nestedTransaction = null; } hr = _transaction.Abort(); _transaction.Dispose(); _transaction = null; if (hr < 0) { if (exceptionHandling) { ProcessResults(hr); } else { SafeNativeMethods.Wrapper.ClearErrorInfo(); } } } return(hr); }
public override void WriteName(IDbgTextWriter output, DbgBreakpointLocationFormatterOptions options) { bool printedToken = false; if ((options & DbgBreakpointLocationFormatterOptions.Tokens) != 0) { WriteToken(output, location.Token); output.Write(DbgTextColor.Text, " "); printedToken = true; } var method = weakMethod?.Target as MethodDef ?? owner.GetDefinition <MethodDef>(location.Module, location.Token); if (method is null) { if (printedToken) { output.Write(DbgTextColor.Error, "???"); } else { WriteToken(output, location.Token); } } else { if (weakMethod?.Target != method) { weakMethod = new WeakReference(method); } owner.MethodDecompiler.Write(new DbgTextColorWriter(output), method, GetFormatterOptions(options)); } switch (location.ILOffsetMapping) { case DbgILOffsetMapping.Exact: case DbgILOffsetMapping.Approximate: output.Write(DbgTextColor.Text, " "); output.Write(DbgTextColor.Operator, "+"); output.Write(DbgTextColor.Text, " "); if (location.ILOffsetMapping == DbgILOffsetMapping.Approximate) { output.Write(DbgTextColor.Operator, "~"); } WriteILOffset(output, location.Offset); break; case DbgILOffsetMapping.Prolog: WriteText(output, "prolog"); break; case DbgILOffsetMapping.Epilog: WriteText(output, "epilog"); break; case DbgILOffsetMapping.Unknown: case DbgILOffsetMapping.NoInfo: case DbgILOffsetMapping.UnmappedAddress: WriteText(output, "???"); break; default: Debug.Fail($"Unknown IL offset mapping: {location.ILOffsetMapping}"); goto case DbgILOffsetMapping.Unknown; } output.Write(DbgTextColor.Text, " "); output.Write(DbgTextColor.Punctuation, "("); output.Write(DbgTextColor.Number, GetHexPrefix() + location.NativeAddress.Address.ToString("X8")); output.Write(DbgTextColor.Operator, "+"); output.Write(DbgTextColor.Number, (options & DbgBreakpointLocationFormatterOptions.Decimal) != 0 ? location.NativeAddress.Offset.ToString() : GetHexPrefix() + location.NativeAddress.Offset.ToString("X")); output.Write(DbgTextColor.Punctuation, ")"); }
static View.IOnClickListener?GetClickListener(WeakReference? value) { return(value != null ? (View.IOnClickListener?)value.Target : null); }
// Process a timer event private void ThreadTimer(object?state) { // // Theory of operation. // // To timeout transactions we must walk down the list starting from the head // until we find a link with an absolute timeout that is greater than our own. // At that point everything further down in the list is elegable to be timed // out. So simply remove that link in the list and walk down from that point // timing out any transaction that is found. // // There could be a race between this callback being queued and the timer // being disabled. If we get here when the timer is disabled, just return. if (!_timerEnabled) { return; } // Increment the number of ticks _ticks++; _lastTimerTime = DateTime.UtcNow.Ticks; // // First find the starting point of transactions that should time out. Every transaction after // that point will timeout so once we've found it then it is just a matter of traversing the // structure. // BucketSet?lastBucketSet = null; BucketSet currentBucketSet = _headBucketSet; // The list always has a head. // Acquire a writer lock before checking to see if we should disable the timer. // Adding of transactions acquires a reader lock and might insert a new BucketSet. // If that races with our check for a BucketSet existing, we may not timeout that // transaction that is being added. WeakReference?nextWeakSet = null; BucketSet? nextBucketSet = null; nextWeakSet = (WeakReference?)currentBucketSet.nextSetWeak; if (nextWeakSet != null) { nextBucketSet = (BucketSet?)nextWeakSet.Target; } if (nextBucketSet == null) { _rwLock.EnterWriteLock(); try { // Access the nextBucketSet again in writer lock to account for any race before disabling the timeout. nextWeakSet = (WeakReference?)currentBucketSet.nextSetWeak; if (nextWeakSet != null) { nextBucketSet = (BucketSet?)nextWeakSet.Target; } if (nextBucketSet == null) { // // Special case to allow for disabling the timer. // // If there are no transactions on the timeout list we can disable the // timer. if (!_timer.Change(Timeout.Infinite, Timeout.Infinite)) { throw TransactionException.CreateInvalidOperationException( TraceSourceType.TraceSourceLtm, SR.UnexpectedTimerFailure, null ); } _timerEnabled = false; return; } } finally { _rwLock.ExitWriteLock(); } } // Note it is slightly subtle that we always skip the head node. This is done // on purpose because the head node contains transactions with essentially // an infinite timeout. do { do { nextWeakSet = (WeakReference?)currentBucketSet.nextSetWeak; if (nextWeakSet == null) { // Nothing more to do. return; } nextBucketSet = (BucketSet?)nextWeakSet.Target; if (nextBucketSet == null) { // Again nothing more to do. return; } lastBucketSet = currentBucketSet; currentBucketSet = nextBucketSet; }while (currentBucketSet.AbsoluteTimeout > _ticks); // // Pinch off the list at this point making sure it is still the correct set. // // Note: We may lose a race with an "Add" thread that is inserting a BucketSet in this location in // the list. If that happens, this CompareExchange will not be performed and the returned abortingSetsWeak // value will NOT equal nextWeakSet. But we check for that and if this condition occurs, this iteration of // the timer thread will simply return, not timing out any transactions. When the next timer interval // expires, the thread will walk the list again, find the appropriate BucketSet to pinch off, and // then time out the transactions. This means that it is possible for a transaction to live a bit longer, // but not much. WeakReference?abortingSetsWeak = (WeakReference?)Interlocked.CompareExchange(ref lastBucketSet.nextSetWeak, null, nextWeakSet); if (abortingSetsWeak == nextWeakSet) { // Yea - now proceed to abort the transactions. BucketSet?abortingBucketSets = null; do { if (abortingSetsWeak != null) { abortingBucketSets = (BucketSet?)abortingSetsWeak.Target; } else { abortingBucketSets = null; } if (abortingBucketSets != null) { abortingBucketSets.TimeoutTransactions(); abortingSetsWeak = (WeakReference?)abortingBucketSets.nextSetWeak; } }while (abortingBucketSets != null); // That's all we needed to do. break; } // We missed pulling the right transactions off. Loop back up and try again. currentBucketSet = lastBucketSet; }while (true); }
private void AddIter(InternalTransaction txNew) { // // Theory of operation. // // Note that the head bucket contains any transaction with essentially infinite // timeout (long.MaxValue). The list is sorted in decending order. To add // a node the code must walk down the list looking for a set of bucket that matches // the absolute timeout value for the transaction. When it is found it passes // the insert down to that set. // // An importent thing to note about the list is that forward links are all weak // references and reverse links are all strong references. This allows the GC // to clean up old links in the list so that they don't need to be removed manually. // However if there is still a rooted strong reference to an old link in the // chain that link won't fall off the list because there is a strong reference held // forward. // BucketSet currentBucketSet = _headBucketSet; while (currentBucketSet.AbsoluteTimeout != txNew.AbsoluteTimeout) { BucketSet?lastBucketSet = null; do { WeakReference?nextSetWeak = (WeakReference?)currentBucketSet.nextSetWeak; BucketSet? nextBucketSet = null; if (nextSetWeak != null) { nextBucketSet = (BucketSet?)nextSetWeak.Target; } if (nextBucketSet == null) { // // We've reached the end of the list either because nextSetWeak was null or // because its reference was collected. This code doesn't care. Make a new // set, attempt to attach it and move on. // BucketSet newBucketSet = new BucketSet(this, txNew.AbsoluteTimeout); WeakReference newSetWeak = new WeakReference(newBucketSet); WeakReference?oldNextSetWeak = (WeakReference?)Interlocked.CompareExchange( ref currentBucketSet.nextSetWeak, newSetWeak, nextSetWeak); if (oldNextSetWeak == nextSetWeak) { // Ladies and Gentlemen we have a winner. newBucketSet.prevSet = currentBucketSet; } // Note that at this point we don't update currentBucketSet. On the next loop // iteration we should be able to pick up where we left off. } else { lastBucketSet = currentBucketSet; currentBucketSet = nextBucketSet; } }while (currentBucketSet.AbsoluteTimeout > txNew.AbsoluteTimeout); if (currentBucketSet.AbsoluteTimeout != txNew.AbsoluteTimeout) { // // Getting to here means that we've found a slot in the list where this bucket set should go. // BucketSet newBucketSet = new BucketSet(this, txNew.AbsoluteTimeout); WeakReference newSetWeak = new WeakReference(newBucketSet); Debug.Assert(lastBucketSet != null); newBucketSet.nextSetWeak = lastBucketSet.nextSetWeak; WeakReference?oldNextSetWeak = (WeakReference?)Interlocked.CompareExchange( ref lastBucketSet.nextSetWeak, newSetWeak, newBucketSet.nextSetWeak); if (oldNextSetWeak == newBucketSet.nextSetWeak) { // Ladies and Gentlemen we have a winner. if (oldNextSetWeak != null) { BucketSet?oldSet = (BucketSet?)oldNextSetWeak.Target; if (oldSet != null) { // prev references are just there to root things for the GC. If this object is // gone we don't really care. oldSet.prevSet = newBucketSet; } } newBucketSet.prevSet = lastBucketSet; } // Special note - We are going to loop back to the BucketSet that preceeds the one we just tried // to insert because we may have lost the race to insert our new BucketSet into the list to another // "Add" thread. By looping back, we check again to see if the BucketSet we just created actually // got added. If it did, we will exit out of the outer loop and add the transaction. But if we // lost the race, we will again try to add a new BucketSet. In the latter case, the BucketSet // we created during the first iteration will simply be Garbage Collected because there are no // strong references to it since we never added the transaction to a bucket and the act of // creating the second BucketSet with remove the backward reference that was created in the // first trip thru the loop. currentBucketSet = lastBucketSet; lastBucketSet = null; // The outer loop will iterate and pick up where we left off. } } // // Great we found a spot. // currentBucketSet.Add(txNew); }
public override void OnMouseLeftButtonDown(IGlyphTextMarkerMouseProcessorContext context, MouseButtonEventArgs e) => leftButtonDownLineIdentityTagWeakReference = new WeakReference(context.Line.IdentityTag);
void ClearPressedLine() => leftButtonDownLineIdentityTagWeakReference = null;
internal JSObject(int jsHandle, Delegate rawDelegate, bool ownsHandle = true) : base(jsHandle, ownsHandle) { WeakRawObject = new WeakReference(rawDelegate, false); }
public WeakDelegate([NotNull] MethodInfo methodInfo, [NotNull] object target) { _method = Argument.NotNull(methodInfo, nameof(methodInfo)); _reference = new WeakReference(Argument.NotNull(target, nameof(target))); }
public sealed override void OnRefreshUI() => cachedText = null;
public Subscription(WeakReference?subscriber, MethodInfo handler) { Subscriber = subscriber; Handler = handler ?? throw new ArgumentNullException(nameof(handler)); }
internal void CloseFromDataReader() { _weakDataReaderReference = null; _cmdState = ConnectionState.Closed; }
public WeakDelegate([NotNull] Delegate handler) { _weakTarget = handler.Target != null ? new WeakReference(handler.Target) : null; _method = handler.GetMethodInfo(); }