[转]WaitForAllObjects to wait on more than MAXIMUM_WAIT_OBJECTS handles

转: http://www.ksingla.net/2010/01/waitforallobjects-to-wait-on-more-than-maximum_wait_objects-handles/

typedef struct _WAIT_THREAD_INFORMATION
{
    DWORD      dwWaitObjectCount;
    PHANDLE    pWaitHandles;
    DWORD      dwWaitMSeconds;
} WAIT_THREAD_INFORMATION, *PWAIT_THREAD_INFORMATION;

VOID
WaitForAllObjects(
    DWORD     dwWaitHandleCount,
    HANDLE *  pWaitHandles,
    DWORD     dwMaxWaitMSeconds
)
{
    HANDLE *                  pThreadWaitHandles    = NULL;
    WAIT_THREAD_INFORMATION * pWaitInformationArray = NULL;

    DWORD                     dwThreadCount         = 0;
    DWORD                     dwLastWaitCount       = 0;
    DWORD                     dwWaitHandleIndex     = 0;
    DWORD                     dwMaximumWaitObjects  = MAXIMUM_WAIT_OBJECTS;

    ASSERT( dwWaitHandleCount    >  0 );
    ASSERT( pWaitHandles         != NULL );
    ASSERT( dwMaxWaitMSeconds    >= 1000 );
    ASSERT( dwMaximumWaitObjects <= MAXIMUM_WAIT_OBJECTS );

    if( dwWaitHandleCount <= dwMaximumWaitObjects )
    {
        WaitForMultipleObjects( dwWaitHandleCount,
                                pWaitHandles,
                                TRUE,
                                dwMaxWaitMSeconds );
    }
    else
    {
        //
        // Create separate threads to wait on maximum wait objects
        // and then make this thread wait on thread handles
        //
        dwThreadCount   = dwWaitHandleCount / dwMaximumWaitObjects;
        dwLastWaitCount = dwWaitHandleCount % dwMaximumWaitObjects;

        if( dwLastWaitCount > 0 )
        {
            dwThreadCount++;
        }

        //
        // This function can handle a maximum of
        // MAXIMUM_WAIT_OBJECTS * MAXIMUM_WAIT_OBJECT handles
        //
        if( dwThreadCount > dwMaximumWaitObjects )
        {
            dwThreadCount     = dwMaximumWaitObjects;
            dwLastWaitCount   = 0;
        }

        pThreadWaitHandles    = new HANDLE[ dwThreadCount ];
        pWaitInformationArray = new WAIT_THREAD_INFORMATION[ dwThreadCount ];

        if( pThreadWaitHandles == NULL || pWaitInformationArray == NULL )
        {
            //
            // Failure
            //
            goto Finished;
        }

        for( DWORD count = 0; count < dwThreadCount; count++)
        {
            //
            // Set information for the thread
            //
            pWaitInformationArray[ count ].dwWaitMSeconds =
                dwMaxWaitMSeconds;
            pWaitInformationArray[ count ].pWaitHandles =
                &pWaitHandles[ dwWaitHandleIndex ];

            if( count != dwThreadCount - 1 || dwLastWaitCount == 0 )
            {
                pWaitInformationArray[ count ].dwWaitObjectCount =
                    dwMaximumWaitObjects;
                dwWaitHandleIndex += dwMaximumWaitObjects;
            }
            else
            {
                pWaitInformationArray[count].dwWaitObjectCount =
                    dwLastWaitCount;
                dwWaitHandleIndex += dwLastWaitCount;
            }

            pThreadWaitHandles[ count ] =
                CreateThread( NULL,
                              0,
                              WaitForMultipleObjectsThread,
                              &pWaitInformationArray[ count ],
                              0,
                              NULL );
            if( pThreadWaitHandles[ count ] == NULL )
            {
                //
                // Not able to create threads break from the loop
                // and wait for threads we already created. 
                // dwThreadCount doesnt include this iteration
                //
                dwThreadCount = count;
                break;
            }
        }

        //
        // Failure is ignored
        //
        WaitForMultipleObjects( dwThreadCount,
                                pThreadWaitHandles,
                                TRUE,
                                dwMaxWaitMSeconds );
    }

Finished:

    if( pThreadWaitHandles != NULL )
    {
        for( DWORD count = 0; count < dwThreadCount; count++)
        {
            if( pThreadWaitHandles[ count ] != NULL )
            {
                CloseHandle( pThreadWaitHandles[ count ] );
                pThreadWaitHandles[ count ] = NULL;
            }
        }

        delete [] pThreadWaitHandles;
        pThreadWaitHandles = NULL;
    }

    if( pWaitInformationArray != NULL )
    {
        delete [] pWaitInformationArray;
        pWaitInformationArray = NULL;
    }

    return;
}

//static
DWORD
WINAPI
WaitForMultipleObjectsThread(
    LPVOID lpParameter = NULL
)
//
// Thread routine which calls WaitForMultipleObjects
// This is used to wait for more than MAXIMUM_WAIT_OBJECTS objects
//
{
    DWORD                    dwReturnValue      = 0;
    PWAIT_THREAD_INFORMATION pThreadInformation = NULL;

    ASSERT( lpParameter != NULL );

    pThreadInformation = ( PWAIT_THREAD_INFORMATION )lpParameter;

    ASSERT(pThreadInformation->dwWaitObjectCount <= MAXIMUM_WAIT_OBJECTS );
    ASSERT(pThreadInformation->pWaitHandles      != NULL );
    ASSERT(pThreadInformation->dwWaitMSeconds    != INFINITE );
    ASSERT(pThreadInformation->dwWaitMSeconds    >= 1000 );

    dwReturnValue = WaitForMultipleObjects(
                        pThreadInformation->dwWaitObjectCount,
                        pThreadInformation->pWaitHandles,
                        TRUE,
                        pThreadInformation->dwWaitMSeconds );

    return dwReturnValue;

}

Sample usage of this method will look like below.

//
// Allocate memory for wait handle array
//
pWaitHandles = new HANDLE[ dwWaitHandleCount ];

...

//
// Call WaitForAllObjects
//
WaitForAllObjects( dwWaitHandleCount,
                   pWaitHandles,
                   dwMaximumWait );

...

//
// Free memory held by pWaitHandles
//
if( pWaitHandles != NULL )
{
    delete [] pWaitHandles;
    pWaitHandles = NULL;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值