RequestUnbind() private method

Called by children to this root, when they would like to be unbound, but are (possibly) running in a finalizer thread so it is (possibly) not safe to unbind then directly.
private RequestUnbind ( RealmHandle handleToUnbind ) : void
handleToUnbind RealmHandle The core handle that is not needed anymore and should be unbound.
return void
Exemplo n.º 1
0
        // called automatically but only once from criticalhandle when this handle is disposing or finalizing
        // see http://reflector.webtropy.com/default.aspx/4@0/4@0/DEVDIV_TFS/Dev10/Releases/RTMRel/ndp/clr/src/BCL/System/Runtime/InteropServices/CriticalHandle@cs/1305376/CriticalHandle@cs
        // and http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.criticalhandle.releasehandle(v=vs.110).aspx
        protected override bool ReleaseHandle()
        {
            // Invalid handles might occur if we throw in construction of one, after root is set, but before the handle has been acquired.
            // In that case, release should just do nothing at all - there is nothing to release.
            // Also, of course if we were called somehow with an invalid handle (should never happen except as stated above), it would not be a good idea to pass it to core
            if (IsInvalid)
            {
                return(true);
            }

            try
            {
                // if we are a root object then we can safely assume that no more user threads are going this way:
                // if we are a root object and in a finalizer thread , then we know that no more user threads will hit us
                // if we are a root object and being called via dispose, then we know that the Table(or whatever) wrapper will block any further calls
                // because we are closed(disposed)
                // in both cases unbind the list using whatever thread we are on, then unbind ourselves
                if (Root == null)
                {
                    lock (_unbindListLock)
                    {
                        _noMoreUserThread = true; // note:resurrecting a root object will not work unless you set this to false again first

                        // this call could interleave with calls from finalizing children in other threads
                        // but they or we will wait because of the unbindlistlock taken above
                        RequestUnbind(this);
                    }
                }
                else
                {
                    // as a child object we wil ask our root to unbind us (testing nomoreuserthread to determine if it can be done at once or we will just have to be put in an unbindlist)
                    // ask our root to unbind us (if it is itself finalizing) or put us into the unbind list (if it is still running)
                    // note that the this instance cannot and will never be aroot itself bc root != null
                    Root.RequestUnbind(this);
                }

                return(true);
            }
            catch (Exception)
            {
                // it would be really bad if we got an exception in here. We must not pass it on, but have to return false
                return(false);
            }
        }