VirtualBox

Changeset 63182 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Aug 8, 2016 4:16:42 PM (8 years ago)
Author:
vboxsync
Message:

ThreadTask: split createThread up into three methods to avoid having to pass NULL all the time when the type needs specifying. Also, explictly marked the racy variant.

Location:
trunk/src/VBox/Main
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/ThreadTask.h

    r63181 r63182  
    3939    { };
    4040
    41     HRESULT createThread(PRTTHREAD pThread = NULL, RTTHREADTYPE enmType = RTTHREADTYPE_MAIN_WORKER);
     41    HRESULT createThread(void);
     42    HRESULT createThreadWithType(RTTHREADTYPE enmType);
     43    HRESULT createThreadWithRaceCondition(PRTTHREAD pThread);
    4244
    4345    virtual void handler() = 0;
     
    4547
    4648protected:
     49    HRESULT createThreadInternal(RTTHREADTYPE enmType, PRTTHREAD pThread);
    4750    static DECLCALLBACK(int) taskHandlerThreadProc(RTTHREAD thread, void *pvUser);
    4851
  • trunk/src/VBox/Main/src-all/ExtPackManagerImpl.cpp

    r63181 r63182  
    660660            {
    661661                ComPtr<Progress> ptrProgress = pTask->ptrProgress;
    662                 hrc = pTask->createThread(NULL /*phThread*/, RTTHREADTYPE_DEFAULT);
     662                hrc = pTask->createThreadWithType(RTTHREADTYPE_DEFAULT);
    663663                pTask = NULL; /* The _completely_ _undocumented_ createThread method always consumes pTask. */
    664664                if (SUCCEEDED(hrc))
     
    20882088        {
    20892089            ComPtr<Progress> ptrProgress = pTask->ptrProgress;
    2090             hrc = pTask->createThread(NULL, RTTHREADTYPE_DEFAULT);
     2090            hrc = pTask->createThreadWithType(RTTHREADTYPE_DEFAULT);
    20912091            pTask = NULL;               /* always consumed by createThread */
    20922092            if (SUCCEEDED(hrc))
  • trunk/src/VBox/Main/src-all/ThreadTask.cpp

    r63181 r63182  
    2020#include "ThreadTask.h"
    2121
     22
    2223/**
    2324 * Starts the task (on separate thread), consuming @a this.
     
    2829 *
    2930 * Possible way of usage:
     31 * @code{.cpp}
     32        HRESULT hr;
     33        SomeTaskInheritedFromThreadTask *pTask = NULL;
     34        try
     35        {
     36            pTask = new SomeTaskInheritedFromThreadTask(this);
     37            if (!pTask->Init()) // some init procedure
     38                throw E_FAIL;
     39        }
     40        catch (...)
     41        {
     42            if (pTask);
     43                delete pTask;
     44            return E_FAIL;
     45        }
     46        return pTask->createThread(); // pTask is always consumed
     47   @endcode
    3048 *
    31  * @code{.cpp}
    32  * int vrc = VINF_SUCCESS;
    33  * HRESULT hr = S_OK;
     49 * @sa createThreadWithType, createThreadWithRaceCondition
     50 */
     51HRESULT ThreadTask::createThread(void)
     52{
     53    return createThreadInternal(RTTHREADTYPE_MAIN_WORKER, NULL /*pThread*/);
     54}
     55
     56
     57/**
     58 * Same ThreadTask::createThread(), except it takes a thread type parameter.
    3459 *
    35  * SomeTaskInheritedFromThreadTask* pTask = NULL;
    36  * try
    37  * {
    38  *     pTask = new SomeTaskInheritedFromThreadTask(this);
    39  *     if (!pTask->Init())//some init procedure
    40  *     {
    41  *         delete pTask;
    42  *         throw E_FAIL;
    43  *     }
    44  *     //this function delete pTask in case of exceptions, so
    45  *     there is no need the call of delete operator
     60 * @param   enmType     The thread type.
     61 */
     62HRESULT ThreadTask::createThreadWithType(RTTHREADTYPE enmType)
     63{
     64    return createThreadInternal(enmType, NULL /*pThread*/);
     65}
     66
     67
     68/**
     69 * Same ThreadTask::createThread(), except it returns a thread handle.
    4670 *
    47  *     hr = pTask->createThread();
    48  * }
    49  * catch(...)
    50  * {
    51  *     vrc = E_FAIL;
    52  * }
    53  * @endcode
     71 * If the task thread is incorrectly mananged, the caller may easily race the
     72 * completion and termination of the task thread!  Use with care!
     73 *
     74 * @param   pThread     Handle of the worker thread.
    5475 */
    55 HRESULT ThreadTask::createThread(PRTTHREAD pThread /*= NULL*/, RTTHREADTYPE enmType /*= RTTHREADTYPE_MAIN_WORKER*/)
     76HRESULT ThreadTask::createThreadWithRaceCondition(PRTTHREAD pThread)
    5677{
    57     m_pThread = pThread;
     78    return createThreadInternal(RTTHREADTYPE_MAIN_WORKER, pThread);
     79}
     80
     81
     82/**
     83 * Internal worker for ThreadTask::createThread,
     84 * ThreadTask::createThreadWithType, ThreadTask::createThreadwithRaceCondition.
     85 *
     86 * @note Always consumes @a this!
     87 */
     88HRESULT ThreadTask::createThreadInternal(RTTHREADTYPE enmType, PRTTHREAD pThread)
     89{
     90    m_pThread = pThread; /** @todo this is utter non-sense! */
    5891    int vrc = RTThreadCreate(m_pThread,
    5992                             taskHandlerThreadProc,
     
    69102    return E_FAIL;
    70103}
     104
    71105
    72106/**
  • trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp

    r60622 r63182  
    584584                }
    585585
    586                 hr = pTask->createThread(NULL, RTTHREADTYPE_MAIN_HEAVY_WORKER);
     586                hr = pTask->createThreadWithType(RTTHREADTYPE_MAIN_HEAVY_WORKER);
    587587
    588588                if (SUCCEEDED(hr))
  • trunk/src/VBox/Main/src-client/GuestDnDSourceImpl.cpp

    r63180 r63182  
    383383/** @todo r=bird: The code using hThreadRcv is racing the thread termination. Since the thread isn't
    384384 * created waitable, the handle goes away if we it terminates before our RTThreadUserWait call returns. */
    385         hr = pTask->createThread(&hThreadRcv);
     385        hr = pTask->createThreadWithRaceCondition(&hThreadRcv);
    386386
    387387    }
  • trunk/src/VBox/Main/src-client/GuestDnDTargetImpl.cpp

    r63180 r63182  
    655655/** @todo r=bird: The code using hThreadSend is racing the thread termination. Since the thread isn't
    656656 * created waitable, the handle goes away if we it terminates before our RTThreadUserWait call returns. */
    657         hr = pTask->createThread(&rcThreadSend);
     657        hr = pTask->createThreadWithRaceCondition(&rcThreadSend);
    658658
    659659    }
  • trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp

    r63157 r63182  
    25122512        }
    25132513
    2514         hr = pTask->createThread(NULL, RTTHREADTYPE_MAIN_HEAVY_WORKER);
     2514        hr = pTask->createThreadWithType(RTTHREADTYPE_MAIN_HEAVY_WORKER);
    25152515
    25162516        if (SUCCEEDED(hr))
     
    25852585        }
    25862586
    2587         hr = pTask->createThread(NULL, RTTHREADTYPE_MAIN_HEAVY_WORKER);
     2587        hr = pTask->createThreadWithType(RTTHREADTYPE_MAIN_HEAVY_WORKER);
    25882588
    25892589        if (SUCCEEDED(hr))
  • trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp

    r63152 r63182  
    10641064                }
    10651065
    1066                 hr = pTask->createThread(NULL, RTTHREADTYPE_MAIN_HEAVY_WORKER);
     1066                hr = pTask->createThreadWithType(RTTHREADTYPE_MAIN_HEAVY_WORKER);
    10671067
    10681068                if (SUCCEEDED(hr))
  • trunk/src/VBox/Main/src-server/VFSExplorerImpl.cpp

    r62485 r63182  
    413413
    414414        //this function delete task in case of exceptions, so there is no need in the call of delete operator
    415         rc = pTask->createThread(NULL, RTTHREADTYPE_MAIN_HEAVY_WORKER);
     415        rc = pTask->createThreadWithType(RTTHREADTYPE_MAIN_HEAVY_WORKER);
    416416    }
    417417    catch (HRESULT aRC)
     
    531531
    532532        //this function delete task in case of exceptions, so there is no need in the call of delete operator
    533         rc = pTask->createThread(NULL, RTTHREADTYPE_MAIN_HEAVY_WORKER);
     533        rc = pTask->createThreadWithType(RTTHREADTYPE_MAIN_HEAVY_WORKER);
    534534    }
    535535    catch (HRESULT aRC)
  • trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp

    r63181 r63182  
    25672567
    25682568        //this function delete pTask in case of exceptions, so there is no need in the call of delete operator
    2569         hr = pTask->createThread(NULL, RTTHREADTYPE_MAIN_WORKER);
     2569        hr = pTask->createThreadWithType(RTTHREADTYPE_MAIN_WORKER);
    25702570
    25712571    }
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette