⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 threadproxyfactory.h

📁 C语言库函数的原型,有用的拿去
💻 H
📖 第 1 页 / 共 2 页
字号:
                    if (pProxy->GetStackSize() == s_proxyStackSize[i])
                    {
                        // If the pool is close to full, cancel the proxy and allow the thread to exit.
                        if (m_proxyPool[i].Count() < s_bucketSize)
                        {
                            m_proxyPool[i].Push(pProxy);

                            // After adding the thread proxy to the pool, check if the factory has been shut down.
                            // At shutdown, the flag is set to true before the shutdown routine goes through
                            // and retires all the thread proxies. However, if we've added this proxy after
                            // that point, there is a good chance that the shutdown routine missed us. We
                            // need to make sure the bucket is empty and all proxies are retired, in this case.
                            if (m_fShutdown)
                            {
                                pProxy = m_proxyPool[i].Flush();
                                while (pProxy != NULL)
                                {
                                    FreeThreadProxy *pNextProxy = LockFreeStack<FreeThreadProxy>::Next(pProxy);
                                    // Retiring the proxy will cause it to perform any necessary cleanup, and exit its dispatch loop.
                                    Retire(pProxy);
                                    pProxy = pNextProxy;
                                }
                            }

                            pProxy = NULL;
                        }
                        break;
                    }
                }
            }

            if (pProxy != NULL)
            {
                Retire(pProxy);
            }
        }

        /// <summary>
        ///     Initiates shutdown of the factory, and deletes it if shutdown can be completed inline.
        /// </summary>
        virtual void ShutdownFactory()
        {
            m_fShutdown = true;
            RetireThreadProxies();
            Release();
        }

    private:

        /// <summary>
        ///     Creates a new thread proxy.
        /// </summary>
        virtual FreeThreadProxy* Create(unsigned int stackSize)
        {
            return new FreeThreadProxy(this, stackSize);
        }

        /// <summary>
        ///     Retires a thread proxy.
        /// </summary>
        virtual void Retire(FreeThreadProxy *pProxy)
        {
            // Canceling the proxy will cause it to perform any necessary cleanup, and exit its dispatch loop.
            pProxy->Cancel();
        }

        // Reference count for the thread proxy factory. For details, see comments in the constructor of ThreadProxy.
        volatile LONG m_referenceCount;

        // Flag that is set to true if shutdown has been initiated on the thread proxy factory.
        volatile bool m_fShutdown;
    };

    /// <summary>
    ///     A factory that creates UMS thread proxies for UMS thread schedulers.
    /// </summary>
    class UMSFreeThreadProxyFactory : public ThreadProxyFactory<UMSFreeThreadProxy, UMSFreeThreadProxyFactory>
    {
    public:

        /// <summary>
        ///     Creates a new UMS thread proxy factory.
        /// </summary>
        UMSFreeThreadProxyFactory(ThreadProxyFactoryManager * pManager) :
            ThreadProxyFactory(pManager),
            m_pCompletionList(NULL),
            m_hCompletionEvent(NULL)
        {
            if (!UMS::CreateUmsCompletionList(&m_pCompletionList))
                throw scheduler_resource_allocation_error(HRESULT_FROM_WIN32(GetLastError()));

            if (!UMS::GetUmsCompletionListEvent(m_pCompletionList, &m_hCompletionEvent))
                throw scheduler_resource_allocation_error(HRESULT_FROM_WIN32(GetLastError()));

            m_pUmsThreadEngine = new TransmogrifiedPrimary();
        }

        /// <summary>
        ///     Destroys a UMS thread proxy factory.
        /// </summary>
        virtual ~UMSFreeThreadProxyFactory()
        {
        }

        /// <summary>
        ///     Initiates shutdown of the factory, and deletes it if shutdown can be completed inline.
        /// </summary>
        virtual void ShutdownFactory()
        {
            RetireThreadProxies();
            m_pUmsThreadEngine->Shutdown();

            if (m_pCompletionList != NULL)
                UMS::DeleteUmsCompletionList(m_pCompletionList);

            // A UMS thread proxy factory can be deleted inline. This is because it is guaranteed that all thread proxies
            // that were loaned out to UMS scheduler proxies were added back to the idle pool before it is possible for
            // the factory to be shutdown. (The factory is shutdown by the RM only after all scheduler proxies have shutdown).
            delete this;
        }

        /// <summary>
        ///     UMS thread proxy factories do not support reference counting.
        /// </summary>
        LONG Reference()
        {
            return 0;
        }

        /// <summary>
        ///     UMS thread proxy factories do not support reference counting.
        /// </summary>
        LONG Release()
        {
            return 0;
        }

    private:

        /// <summary>
        ///     Creates a new thread proxy.
        /// </summary>
        virtual UMSFreeThreadProxy * Create(unsigned int stackSize)
        {
            HANDLE hObjects[2];

            UMSFreeThreadProxy *pProxy = new UMSFreeThreadProxy(this, m_pCompletionList, stackSize);

            hObjects[0] = pProxy->m_hBlock;
            hObjects[1] = m_hCompletionEvent;

            //
            // Make *ABSOLUTELY CERTAIN* that the thread has come back on a completion list prior to returning from Create.  This will ensure that a primary
            // can execute it right away (which is the likely use for creating one of these to begin with).
            //
            for(;;)
            {
                DWORD result = WaitForMultipleObjects(2, hObjects, FALSE, INFINITE);
                if (result == WAIT_OBJECT_0)
                {
                    return pProxy;
                }

                PUMS_CONTEXT pUMSContext;

                if (!UMS::DequeueUmsCompletionListItems(m_pCompletionList, 0, &pUMSContext))
                {
                    delete pProxy;
                    throw scheduler_resource_allocation_error(HRESULT_FROM_WIN32(GetLastError()));
                }

                while (pUMSContext != NULL)
                {
                    UMSFreeThreadProxy* pReturnedProxy = static_cast<UMSFreeThreadProxy*>(UMSFreeThreadProxy::FromUMSContext(pUMSContext));
                    RPMTRACE(MTRACE_EVT_ORIGINALCOMPLETION, pReturnedProxy, NULL, pUMSContext);
                    pUMSContext = UMS::GetNextUmsListItem(pUMSContext);

                    // Let the thread engine run it to ThreadMain
                    m_pUmsThreadEngine->QueueToCompletion(pReturnedProxy);
                }
            }
        }

        /// <summary>
        ///     Prepares a thread proxy for use.
        /// </summary>
        /// <param name="pProxy">
        ///     The proxy to prepare.
        /// </param>
        /// <param name="contextPriority">
        ///     The required thread priority for the thread proxy.
        /// <param>
        virtual void Prepare(UMSFreeThreadProxy *pProxy, int contextPriority)
        {
            ThreadProxyFactory::Prepare(pProxy, contextPriority);
            pProxy->ClearCriticalRegion();
        }

        /// <summary>
        ///     Retires a thread proxy.
        /// </summary>
        virtual void Retire(UMSFreeThreadProxy *pProxy)
        {
            RPMTRACE(MTRACE_EVT_RETIRE, pProxy, NULL, NULL);

            // Canceling the proxy will cause it to perform any necessary cleanup, and exit its dispatch loop.
            pProxy->Cancel();

            m_pUmsThreadEngine->QueueToCompletion(pProxy);
        }

        // The primary responsible for retiring UTs.
        TransmogrifiedPrimary *m_pUmsThreadEngine;

        // The initial completion list upon which threads created from this factory will be placed.  No UMS thread can be scheduled by any primary
        // until it appears on an initial UMS completion list.  We will block Create until this is done.
        PUMS_COMPLETION_LIST m_pCompletionList;

        // The UMS completion list event.
        HANDLE m_hCompletionEvent;
    };

    //
    // A class that holds a collection of thread proxy factories, one for each type of thread proxy.
    //
    class ThreadProxyFactoryManager
    {
    public:

        /// <summary>
        ///     Creates a thread proxy factory manager.
        /// </summary>
        ThreadProxyFactoryManager();

        /// <summary>
        ///     Destroys a thread proxy factory manager.
        /// </summary>
        ~ThreadProxyFactoryManager();

        /// <summary>
        ///     Returns a Win32 thread proxy factory.
        /// </summary>
        FreeThreadProxyFactory * GetFreeThreadProxyFactory();

        /// <summary>
        ///     Returns a UMS thread proxy factory.
        /// </summary>
        UMSFreeThreadProxyFactory * GetUMSFreeThreadProxyFactory();

        /// <summary>
        ///     Returns the TLS index used to store execution resource information by subscribed threads and thread proxies.
        /// </summary> 
        DWORD GetExecutionResourceTls() const
        {
            return m_dwExecutionResourceTlsIndex;
        }

    private:
        // A thread proxy factory for Win32 thread proxies.
        FreeThreadProxyFactory * m_pFreeThreadProxyFactory;

        // A thread proxy factory for UMS thread proxies.
        UMSFreeThreadProxyFactory * m_pUMSFreeThreadProxyFactory;

        // An index to a TLS slot where execution resource pointers are stored.
        DWORD m_dwExecutionResourceTlsIndex;

        // A lock that guards creation of the thread proxy factories.
        _NonReentrantBlockingLock m_proxyFactoryCreationLock;
    };

} // namespace details
} // namespace Concurrency

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -