0

I am searching asynchronously for missing patches via WUAPIs. I have declared an ISearchJob object (https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-isearchjob). If I receive a timeout from WaitForSingleObject function, I call RequestAbort() then perform the CleanUp() of ISearchJob object. However, when I perform the CleanUp, sometimes it takes more than 15 minutes to complete. Do you know why? And is there any solution for this? Thank you in advance for your help!


    // List of params that will be passed to the thread that will perform the actual search for missing updates
    typedef struct Params
    {
        CComPtr<IUpdateSearcher>& updateSearcher;
        CComPtr<ISearchResult>& searchResult;
        typeCharStr& criteria;
        CComObject<SearchCompleteFunction>* searchCompleteFunc; // needs to be released after usage
        CComPtr<ISearchJob>&& searchJob;
    };


// ptrUpdateSearcher, ptrSearchResult, bstrCriteria, searchCompleteFunc are already declared and configured when reaching this part of code
Params* stParams = new Params{ ptrUpdateSearcher, ptrSearchResult, bstrCriteria, searchCompleteFunc, nullptr };

    DWORD dwThreadId;
    HANDLE hThread = CreateThread( NULL, 0, searchForMissingPatchesThreadFunc, (LPVOID) stParams, 0, &dwThreadId );
    if( !hThread )
    {
        goto error;
    }

    // Start the thread and wait for finishing 
    DWORD dwRet = WaitForSingleObject( hThread, timeout > 0 ? timeout * 1000 : INFINITE ); 
    TerminateThread( hThread , 0 );
    CloseHandle( hThread );

    // Get the search result
    ptrSearchResult = stParams->searchResult;

    if( dwRet == WAIT_TIMEOUT )
    {
        // stop the ISearchJob
        stParams->searchJob->RequestAbort();
        stParams->searchJob->CleanUp(); // HERE GETS STUCK SOMETIMES EVEN FOR 15 MINUTES

        goto error;
    }

LATER EDIT: Here is the thread function, COM is initialized with COINIT_MULTITHREADED.

    // function that will asynchronously search for missing updates
    auto searchForMissingPatchesThreadFunc = [](LPVOID data) -> DWORD
    {
        // get the data from arguments
        Params *params = static_cast<Params*>( data );

        if (S_OK == params->updateSearcher->BeginSearch(_bstr_t(params->criteria.c_str()), params->searchCompleteFunc, CComVariant("Scanning"), &params->searchJob)
            && params->searchJob)
        {
            // Check if search is completed. If not, continue to check
            CComVariant isCompleted;
            params->searchJob->get_IsCompleted(&isCompleted.boolVal);

            while (isCompleted.boolVal == VARIANT_FALSE)
            {
                std::this_thread::sleep_for(std::chrono::milliseconds(500));
                params->searchJob->get_IsCompleted( &isCompleted.boolVal ) ;
            }

            if (isCompleted.boolVal == VARIANT_TRUE)
            {
                // Search completed, get the result
                params->updateSearcher->EndSearch( params->searchJob, &params->searchResult );
            }
        }

        return 0;
    };

I already looked at the Correct way to stop asynchronous ISearchJob, if I call EndSearch right after RequestAbort, the issue is similar, still it takes sometimes 15 mins to complete. If I call only RequestAbort(), the program will crash when the search will complete (could be anytime from 5 seconds to 15 minutes or more)

theTAG
  • 21
  • 5
  • Your code is incomplete (what's in your thread, COM apartments, etc.) Have you seen this: https://stackoverflow.com/questions/40018357/correct-way-to-stop-asynchronous-isearchjob – Simon Mourier Oct 31 '19 at 13:44
  • @SimonMourier Thanks for your comment, please find my answers in the main post (LATER EDIT section). – theTAG Oct 31 '19 at 13:55
  • I have tested a similar code and it just does wait 1 or 2 seconds on CleanUp(). Maybe the time you see is normal in your context. How much time it takes if you use an INFINITE timer? Have you tried to call EndSearch before RequestAbort? – Simon Mourier Oct 31 '19 at 16:42
  • @SimonMourier The time is similar (15 mins) if I use INFINITE. I have tried to call EndSearch before RequestAbort and pretty much all the combinations using these 3 functions EndSearch, RequestAbort and CleanUp, the result is the same. If I do not call CleanUp at all, the program will crash when SearchJob completes. FYI the issue is reproducing only on a couple of machines. I suspect it's the Windows Server that is taking that much time to send the response back. – theTAG Nov 04 '19 at 11:14
  • @SimonMourier (or anybody else), do you please have any updates? – theTAG Nov 07 '19 at 11:47
  • @Nope - well, I kind said it all. It seems related to your context, so just don't wait for it if you don't want to. – Simon Mourier Nov 07 '19 at 12:18
  • I have a similar issue, but in my case WUA crashes in ISearchJob::CleanUp (which is executed in a different thread) after I call ISearchJob::RequestAbort. The documentation is really unclear of whether you need to call CleanUp after you call RequestAbort. – fmike7 Jun 03 '21 at 17:54
  • @fmike7 sorry for late reply .. In my case, I am calling RequestAbort() and then Cleanup(), but in the same thread. Everything is working as expected, two years later :) – theTAG Sep 23 '22 at 20:23

0 Answers0