+ //
+ // I do not know when we could not be able to increment the
+ // reference count and set success to false. It might just
+ // be a convention used for the following code pattern:
+ //
+ // bool release = false
+ // try { x.DangerousAddRef (ref release); ... }
+ // finally { if (release) x.DangerousRelease (); }
+ //
+ [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
+ public void DangerousAddRef (ref bool success)
+ {
+ if (refcount <= 0)
+ throw new ObjectDisposedException (GetType ().FullName);
+
+ bool registered = false;
+ int newcount, current;
+ do {
+ current = refcount;
+ newcount = current + 1;
+
+ if (current <= 0){
+ //
+ // In MS, calling sf.Close () followed by a call
+ // to P/Invoke with SafeHandles throws this, but
+ // am left wondering: when would "success" be
+ // set to false?
+ //
+ throw new ObjectDisposedException (GetType ().FullName);
+ }
+
+ // perform changes in finally to avoid async interruptions
+ RuntimeHelpers.PrepareConstrainedRegions ();
+ try {}
+ finally {
+ if (Interlocked.CompareExchange (ref refcount, newcount, current) == current)
+ registered = success = true;
+ }
+ } while (!registered);