Inheritance: System.Runtime.InteropServices.SafeHandle
 internal OverlappedCache(System.Threading.Overlapped overlapped, object[] pinnedObjectsArray, IOCompletionCallback callback)
 {
     this.m_Overlapped         = overlapped;
     this.m_PinnedObjects      = pinnedObjectsArray;
     this.m_PinnedObjectsArray = pinnedObjectsArray;
     this.m_NativeOverlapped   = new SafeNativeOverlapped(overlapped.UnsafePack(callback, pinnedObjectsArray));
 }
        // SetUnmanagedStructures
        //
        // This needs to be called for overlapped IO to function properly.
        //
        // Fills in overlapped Structures used in an async overlapped Winsock call.
        // These calls are outside the runtime and are unmanaged code, so we need
        // to prepare specific structures and ints that lie in unmanaged memory
        // since the overlapped calls may complete asynchronously.
        internal void SetUnmanagedStructures(object objectsToPin)
        {
            Socket s = (Socket)AsyncObject;

            // Bind the Win32 Socket Handle to the ThreadPool
            Debug.Assert(s != null, "m_CurrentSocket is null");
            Debug.Assert(s.SafeHandle != null, "m_CurrentSocket.SafeHandle is null");

            if (s.SafeHandle.IsInvalid)
            {
                throw new ObjectDisposedException(s.GetType().FullName);
            }

            ThreadPoolBoundHandle boundHandle = s.SafeHandle.GetOrAllocateThreadPoolBoundHandle();

            unsafe
            {
                NativeOverlapped *overlapped = boundHandle.AllocateNativeOverlapped(s_ioCallback, this, objectsToPin);
                _nativeOverlapped = new SafeNativeOverlapped(s.SafeHandle, overlapped);
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Info(this, $"{boundHandle}::AllocateNativeOverlapped. return={_nativeOverlapped}");
                }
            }
        }
 internal OverlappedCache(System.Threading.Overlapped overlapped, object pinnedObjects, IOCompletionCallback callback, bool alreadyTriedCast)
 {
     this.m_Overlapped         = overlapped;
     this.m_PinnedObjects      = pinnedObjects;
     this.m_PinnedObjectsArray = alreadyTriedCast ? null : NclConstants.EmptyObjectArray;
     this.m_NativeOverlapped   = new SafeNativeOverlapped(overlapped.UnsafePack(callback, pinnedObjects));
 }
Exemple #4
0
        // SetUnmanagedStructures
        //
        // This needs to be called for overlapped IO to function properly.
        //
        // Fills in overlapped Structures used in an async overlapped Winsock call.
        // These calls are outside the runtime and are unmanaged code, so we need
        // to prepare specific structures and ints that lie in unmanaged memory
        // since the overlapped calls may complete asynchronously.
        internal void SetUnmanagedStructures(object objectsToPin)
        {
            Socket s = (Socket)AsyncObject;

            // Bind the Win32 Socket Handle to the ThreadPool
            Debug.Assert(s != null, "m_CurrentSocket is null");
            Debug.Assert(s.SafeHandle != null, "m_CurrentSocket.SafeHandle is null");

            if (s.SafeHandle.IsInvalid)
            {
                throw new ObjectDisposedException(s.GetType().FullName);
            }

            ThreadPoolBoundHandle boundHandle = s.SafeHandle.GetOrAllocateThreadPoolBoundHandle();

            unsafe
            {
                NativeOverlapped *overlapped = boundHandle.AllocateNativeOverlapped(s_ioCallback, this, objectsToPin);
                _nativeOverlapped = new SafeNativeOverlapped(s.SafeHandle, overlapped);
                if (GlobalLog.IsEnabled)
                {
                    GlobalLog.Print(
                        "BaseOverlappedAsyncResult#" + LoggingHash.HashString(this) +
                        "::boundHandle#" + LoggingHash.HashString(boundHandle) +
                        "::AllocateNativeOverlapped. Return=" +
                        _nativeOverlapped.DangerousGetHandle().ToString("x"));
                }
            }
        }
 // Utility cleanup routine. Frees the overlapped structure.
 // This should be overridden to free pinned and unmanaged memory in the subclass.
 // It needs to also be invoked from the subclass.
 protected virtual void ForceReleaseUnmanagedStructures()
 {
     // Free the unmanaged memory if allocated.
     if (NetEventSource.IsEnabled)
     {
         NetEventSource.Enter(this);
     }
     _nativeOverlapped.Dispose();
     _nativeOverlapped = null;
     GC.SuppressFinalize(this);
 }
        internal OverlappedCache(Overlapped overlapped, object[] pinnedObjectsArray, IOCompletionCallback callback)
        {
            m_Overlapped         = overlapped;
            m_PinnedObjects      = pinnedObjectsArray;
            m_PinnedObjectsArray = pinnedObjectsArray;

            unsafe
            {
                m_NativeOverlapped = new SafeNativeOverlapped(overlapped.UnsafePack(callback, pinnedObjectsArray));
            }
        }
        // Utility cleanup routine. Frees the overlapped structure.
        // This should be overriden to free pinned and unmanaged memory in the subclass.
        // It needs to also be invoked from the subclass.
        protected virtual void ForceReleaseUnmanagedStructures()
        {
            // Free the unmanaged memory if allocated.
            GlobalLog.Print(
                "BaseOverlappedAsyncResult#" + Logging.HashString(this) +
                "::ForceReleaseUnmanagedStructures");

            _nativeOverlapped.Dispose();
            _nativeOverlapped = null;
            GC.SuppressFinalize(this);
        }
 private void InternalFree()
 {
     this.m_Overlapped    = null;
     this.m_PinnedObjects = null;
     if (this.m_NativeOverlapped != null)
     {
         if (!this.m_NativeOverlapped.IsInvalid)
         {
             this.m_NativeOverlapped.Dispose();
         }
         this.m_NativeOverlapped = null;
     }
 }
        private void InternalFree()
        {
            m_Overlapped    = null;
            m_PinnedObjects = null;

            if (m_NativeOverlapped != null)
            {
                if (!m_NativeOverlapped.IsInvalid)
                {
                    m_NativeOverlapped.Dispose();
                }
                m_NativeOverlapped = null;
            }
        }
        internal bool TransmitPackets(SafeCloseSocket socketHandle, IntPtr packetArray, int elementCount, int sendSize, SafeNativeOverlapped overlapped)
        {
            EnsureDynamicWinsockMethods();
            TransmitPacketsDelegate transmitPackets = _dynamicWinsockMethods.GetDelegate <TransmitPacketsDelegate>(socketHandle);

            // UseDefaultWorkerThread = 0.
            return(transmitPackets(socketHandle, packetArray, elementCount, sendSize, overlapped, 0));
        }
Exemple #11
0
        internal bool TransmitPackets(SafeCloseSocket socketHandle, IntPtr packetArray, int elementCount, int sendSize, SafeNativeOverlapped overlapped, TransmitFileOptions flags)
        {
            EnsureDynamicWinsockMethods();
            TransmitPacketsDelegate transmitPackets = _dynamicWinsockMethods.GetDelegate <TransmitPacketsDelegate>(socketHandle);

            return(transmitPackets(socketHandle, packetArray, elementCount, sendSize, overlapped, flags));
        }
        //
        // This method is called after an asynchronous call is made for the user,
        // it checks and acts accordingly if the IO:
        // 1) completed synchronously.
        // 2) was pended.
        // 3) failed.
        //
        internal unsafe SocketError CheckAsyncCallOverlappedResult(SocketError errorCode)
        {
#if DEBUG
            m_SavedErrorCode = errorCode;
#endif

            //
            // Check if the Async IO call:
            // 1) was pended.
            // 2) completed synchronously.
            // 3) failed.
            //
            if (m_UseOverlappedIO)
            {
                //
                // we're using overlapped IO under Win9x (or NT with registry setting overriding
                // completion port usage)
                //
                switch (errorCode)
                {
                case 0:
                case SocketError.IOPending:

                    //
                    // the Async IO call was pended:
                    // Queue our event to the thread pool.
                    //
                    GlobalLog.Assert(m_UnmanagedBlob != null, "BaseOverlappedAsyncResult#{0}::CheckAsyncCallOverlappedResult()|Unmanaged blob isn't allocated.", ValidationHelper.HashString(this));
                    ThreadPool.UnsafeRegisterWaitForSingleObject(
                        m_OverlappedEvent,
                        new WaitOrTimerCallback(OverlappedCallback),
                        this,
                        -1,
                        true);

                    //
                    // we're done, completion will be asynchronous
                    // in the callback. return
                    //
                    return(SocketError.Success);

                default:
                    //
                    // the Async IO call failed:
                    // set the number of bytes transferred to -1 (error)
                    //
                    ErrorCode = (int)errorCode;
                    Result    = -1;
                    ReleaseUnmanagedStructures();
                    break;
                }
            }
            else
            {
#if DEBUG
                OverlappedCache cache = m_Cache;
                if (cache != null)
                {
                    SafeNativeOverlapped nativeOverlappedPtr = cache.NativeOverlapped;
                    if (nativeOverlappedPtr != null)
                    {
                        m_IntermediateNativeOverlapped = nativeOverlappedPtr;
                    }
                }
#endif
                //
                // We're using completion ports under WinNT.  Release one reference on the structures for
                // the main thread.
                //
                ReleaseUnmanagedStructures();

                switch (errorCode)
                {
                //
                // ignore cases in which a completion packet will be queued:
                // we'll deal with this IO in the callback
                //
                case 0:
                case SocketError.IOPending:
                    //
                    // ignore, do nothing
                    //
                    return(SocketError.Success);

                //
                // in the remaining cases a completion packet will NOT be queued:
                // we'll have to call the callback explicitly signaling an error
                //
                default:
                    //
                    // call the callback with error code
                    //
                    ErrorCode = (int)errorCode;
                    Result    = -1;

                    // The AsyncResult must be cleared since the callback isn't going to be called.
                    // Not doing so leads to a leak where the pinned cached OverlappedData continues to point to the async result object,
                    // which points to the Socket (as well as user data) and to the OverlappedCache, preventing the OverlappedCache
                    // finalizer from freeing the pinned OverlappedData.
                    if (m_Cache != null)
                    {
                        // Could be null only if SetUnmanagedStructures weren't called.
                        m_Cache.Overlapped.AsyncResult = null;
                    }

                    ReleaseUnmanagedStructures();  // Additional release for the completion that won't happen.
                    break;
                }
            }
            return(errorCode);
        }
Exemple #13
0
        internal bool TransmitPackets(SafeCloseSocket socketHandle, IntPtr packetArray, int elementCount, int sendSize, SafeNativeOverlapped overlapped, TransmitFileOptions flags)
        {
            EnsureDynamicWinsockMethods();
            TransmitPacketsDelegate transmitPackets = _dynamicWinsockMethods.GetDelegate<TransmitPacketsDelegate>(socketHandle);

            return transmitPackets(socketHandle, packetArray, elementCount, sendSize, overlapped, flags);
        }