|
|
|
date: Fri, 4 Apr 2008 16:21:25 -0500,
group: microsoft.public.platformsdk.shell
back
Shell thumbnails and multithreading
Hey folks,
In a pre-Vista shell extension thumbnail extractor, I'm trying to figure out
exactly what's going on with the IExtractImage:::GetLocation's "DWORD
*pdwFlags" IEIFLAG_ASYNC bit that's supposed to request the extractor object
to indicate if it supports free threaded extraction or not by returning
E_PENDING. Other than needing to implement the IRunnableTask interface,
does anyone know what the actual implications of returning E_PENDING to the
Shell are in terms of the component's implementation? (Interestingly, the
current IExtractImage documentation indicates that Vista doesn't use this
flag.)
The protocol already seems serialized - IPersistFile::Load passes the
component the pathname, IExtractImage::GetLocation is called with the
requested size, color depth and the flag settings, and then
IExtractImage::Extract is called to return the bitmap handle.
(IExtractImage2::GetDateStamp is in here somewhere too to check if a cached
thumbnail is current.)
If the object returns E_PENDING, is the Shell going to call the same object
instance for additional thumbnails while the Extract method is running, etc.
so that I need to synchronize access to the file pathname and image
attributes, or is the only purpose to determine if the Shell can start and
stop the Extract method via IRunnableTask calls?
Side question 1: if the extractor COM object is free-threaded, are there any
implications on the HBITMAP that must be returned to the Shell?
Side question 2: Does anyone know if using GDI+ in the Extract method is
thread-safe in this case?
Thanks.
date: Fri, 4 Apr 2008 16:21:25 -0500
author: linearred noway
Re: Shell thumbnails and multithreading
There's an interesting wrinkle in the current IExtractImage::GetLocation()
method documentation.
In the description of the pdwFlags IEFLAG_ASYNC bit, it says:
"Microsoft Windows XP and earlier. Used to ask if this instance supports
asynchronous (free-threaded) extraction. If this flag is set by the calling
applications, IExtractImage::GetLocation may return E_PENDING, indicating to
the calling application to extract the image on another thread. If E_PENDING
is returned, the priority of the item is returned in pdwPriority."
Then, in the Remarks section, it says:
"Microsoft Windows XP and earlier: This method returns the path to an image
and specifies how the image should be rendered. IExtractImage::GetLocation
is free-threaded-that is, supports the Multi-threaded Apartment Model (MTA)-
therefore it can be placed in a background thread. The object must also
expose an IRunnableTask interface, so the calling application can start and
stop the extraction process as needed."
On the one hand, it seems that free-threading by the server object is
optional, on the other hand, it seems that it's required, and IRunnableTask
must be implemented.
Also, the "Professional ATL COM Programming" (v3.0) book I'm using indicates
a number of distinctions between using the "MTA", "Both" or "Free" threading
models for multi-threading that can impact performance. The documentation
above implies that "free" and "MTA" are equivalent (at least in this case).
In the case of the (pre-Vista) thumbnail shell extension, I haven't seen
anything that actually indicates which kind of COM threading model context
the shell is creating the extractor object in, or whether it tailors its
calling context to the capabilities of the supplied object so as to avoid
the marshalling overhead the older COM books warn about if the client and
server threading models differ.
date: Mon, 7 Apr 2008 12:54:21 -0500
author: linearred noway
Re: Shell thumbnails and multithreading
As I understand it, "Apartment" objects are STA objects. "Free"
objects are MTA objects. "Both" objects can run in either the STA or
the MTA - they can cope with the threading constraints of each.
What the E_PENDING stuff is all about is a way for explorer to see if
the object will follow the rules for an object marked "Both". It's
kind of short-cutting COM. It's saying, I'd like to call you
asynchronously. If the object supports it, it can return E_PENDING.
Explorer will now simply use the same interface pointer, to call the
same method, directly, from another thread, without any kind of
marshalling.
Because of this, I think it's ok to register your object as single
threaded ("Apartment". You and explorer (via E_PENDING) will privately
negotiate that you can be safely called on a background thread).
I'm not really sure what the IRunnableTask is for. The docs are very
weak - they say you should only implement Run and IsRunning. And if
you're using IExtractImage::Extract, it says Run is not necessary. I'd
guess it's because you're really using a single threaded object in a
multi-threaded way, so IsRunning is there to signify that the
interface is busy on another thread.
Cheers
Matt
On Apr 7, 10:18 pm, "linearred" <noway> wrote:
> "linearred" <noway> wrote in message
>
> news:%23CmgWMPmIHA.1368@TK2MSFTNGP02.phx.gbl...>But both examples declare their
> > ATL-based extractor COM object as being "Single" threaded (not even
> > Apartment/STA), and neither actually implements threading or the
> > IRunnableTask interface. What gives?
>
> My bad on the thread model declarations -- the ATL template declarations
> they use has "CComSingleThreadModel", but the dll's are actually registered
> "Apartment". Still, neither example declares itself as using a
> multi-threaded model.
date: Mon, 7 Apr 2008 16:20:19 -0700 (PDT)
author: Matt Ellis
|
|