HRESULT CLR_HW_Hardware::SpawnDispatcher()
{
    NATIVE_PROFILE_CLR_HARDWARE();
    TINYCLR_HEADER();

    CLR_RT_ApplicationInterrupt* interrupt;
    CLR_RT_HeapBlock_NativeEventDispatcher* ioPort;
    CLR_RT_HeapBlock_NativeEventDispatcher ::InterruptPortInterrupt *interruptData;

    // if reboot is in progress, just bail out
    if(CLR_EE_DBG_IS( RebootPending )) 
    {
        return S_OK;
    }

    interrupt = (CLR_RT_ApplicationInterrupt*)m_interruptData.m_applicationQueue.FirstValidNode();

    if((interrupt == NULL) || !g_CLR_RT_ExecutionEngine.EnsureSystemThread( g_CLR_RT_ExecutionEngine.m_interruptThread, ThreadPriority::System_Highest ))
    {
        return S_OK;
    }

    interrupt->Unlink();

    interruptData = &interrupt->m_interruptPortInterrupt;
    ioPort = interruptData->m_context;

    CLR_RT_ProtectFromGC gc1 ( *ioPort );
                    
    TINYCLR_SET_AND_LEAVE(ioPort->StartDispatch( interrupt, g_CLR_RT_ExecutionEngine.m_interruptThread ));
            
    TINYCLR_CLEANUP();

    if(FAILED(hr))
    {
        ioPort->ThreadTerminationCallback( interrupt );
    }

    --m_interruptData.m_queuedInterrupts;

    TINYCLR_CLEANUP_END();    
}