Re-creating free threaded objects in the face of multiple threads
Howdy Gurus
I have a problem for which I am unable to come up with a decent
solution.
I have a class that encapsulates calls to a free-threaded COM object.
Many worker threads create instances of this class on-the-fly and make
method calls on the COM object. In short:
class COMWrapper
{
static IOne* pOne_;
public:
void CreateIOne(); // always called by only one thread at start-up
void CallCOMWrapperMethod()
{
HRESULT hr = pOne_->CallThisMethod();
if (FAILED(hr))
{
// how do I recreate IOne here on just one thread and let all
other worker threads slide by?
}
}
};
If the call fails, I want to release pOne_ and create it again.
The problem is the worker threads -- all of them execute something
like:
COMWrapper().CallCOMWrapperMethod();
so they are all merrily banging away at pOne_->CallThisMethod().
**If** by any chance, the call fails for some reason, it will fail for
all worker threads. I am a little confused how to recreate IOne* in
failure scenario in the presence of all waiting threads. I went in
this direction:
if (FAILED(hr))
{
someLockClass lockObj(g_GlobalLock);
ReleaseIOne();
CreateIOne();
}
that, of course, wouldn't work.
Next, I tried going down the Double-checked locking pattern route and
that didn't work either.
if (FAILED(hr))
{
// assume bTrouble is a static member var of COMWrapper
bTrouble = true;
someLockClass lockObj(g_GlobalLock);
if (bTrouble)
{
ReleaseIOne();
CreateIOne();
bTrouble = false;
}
}
The latter looks very fishy to me, in that I don't know if there is
some kind of race condition between the time I re-create the interface
pointer and set bTrouble to false and another worker thread coming
into CallCOMWrapperMethod(), failing and setting bTrouble to true
again.
Any insights?