I launch the IShellItemImageFactory::GetImage method for each item in a folder in a number of background threads. The code looks like that:
HRESULT GetImage(IShellItemImageFactory* pImgFactory,
SIZE Size, COLORREF BkColor, HBITMAP *phbm)
{
if (pImgFactory == 0 || phbm == 0)
return E_POINTER;
*phbm = 0;
HBITMAP hBmp = 0;
HRESULT hr = pImgFactory->GetImage(Size, SIIGBF_BIGGERSIZEOK, &hBmp);
if (SUCCEEDED(hr) && hBmp)
{
*phbm = CPicture::StretchBitmap(hBmp, Size, BkColor);
}
return hr;
}
Sometimes I have the all 16 threads stuck inside call to pImgFactory->GetImage for different items. They all stuck in one and the same place, which could be seen in the provided stack. I checked that different threads process different items. What can be a cause of such strange phenomenon?
EDIT:
After David Heffernan's response I realized that the IShellItemImageFactory interface itself can be not thread safe. Our threading subsystem automatically initializes each thread as STA (by the call to CoInitialize(0) function). But may be, for IShellItemImageFactory I need MTA threads. Is there a way to discover the IShellItemImageFactory's coclass CLSID, in order to find in the Registry its threading requirements?
EDIT2: Probably, our threading mechanism somehow related to the problem. In this specific case we use an engine that we call "Job Queue". It is non-blocking FIFO queue, which elements describe a job. The description contains pointers to job's algorithm and job's data. Typically (but not necessary) the main thread puts jobs to the queue. A free thread from thread pool may get element from the queue and perform the job. This mechanism worked well for us already a couple of years. But may be, it somehow affects icon extraction. May be, I wasn't sufficiently exact in defining the icon extracting algorithm and data. I don't know how can I determine it.
The phenomenon is not really a deadlock. It happens when extracting images of subfolders in a folder, which was not still cached by the Windows. Suppose there is a folder F with 20 subfolders F1,F2,...,F20, each of which contains 20+ other subfolders and files. If folder F is not cached, extraction of 20 images of its subfolders may take 15 - 25 min (on my Win10 8-core computer). After the all images were once extracted, repeated requests for images in that folder F are performed fast.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With