A deadlock may occur when more than one client loads a multithreaded apartment singleton object that you created by using Active Template Library (811591)
The information in this article applies to:
- Microsoft Visual Studio .NET (2003), Professional Edition
- Microsoft Visual Studio .NET (2003), Enterprise Architect Edition
- Microsoft Visual Studio .NET (2003), Enterprise Developer Edition
- Microsoft Visual Studio .NET (2003), Academic Edition
SYMPTOMSA deadlock may occur when more than one client creates the same multithreaded apartment (MTA) singleton object by using Microsoft Active Template Library (ATL). When the deadlock occurs, any new calls to receive an instance of the singleton object are also in deadlock.WORKAROUNDTo work around this problem, replace the DECLARE_CLASSFACTORY_SINGLETON definition with a definition that uses a fixed implementation of the CComClassFactorySingleton class. Add the following code before the declaration of the Singleton class: #undef DECLARE_CLASSFACTORY_SINGLETON
#define DECLARE_CLASSFACTORY_SINGLETON(obj) DECLARE_CLASSFACTORY_EX(CMyComClassFactorySingleton<obj>)
template <class T>
class CMyComClassFactorySingleton : public CComClassFactory
{
public:
CMyComClassFactorySingleton() : m_hrCreate(S_OK){}
virtual ~CMyComClassFactorySingleton(){}
// IClassFactory
STDMETHOD(CreateInstance)(LPUNKNOWN pUnkOuter, REFIID riid, void** ppvObj)
{
HRESULT hRes = E_POINTER;
if (ppvObj != NULL)
{
*ppvObj = NULL;
// Aggregation is not supported in singleton objects.
ATLASSERT(pUnkOuter == NULL);
if (pUnkOuter != NULL)
hRes = CLASS_E_NOAGGREGATION;
else
{
if (m_hrCreate == S_OK && m_spObj == NULL)
{
Lock();
__try
{
// Fix: The following If statement was moved inside the __try statement.
// Did another thread arrive here first?
if (m_hrCreate == S_OK && m_spObj == NULL)
{
CComObjectCached<T> *p;
m_hrCreate = CComObjectCached<T>::CreateInstance(&p);
if (SUCCEEDED(m_hrCreate))
{
m_hrCreate = p->QueryInterface(IID_IUnknown, (void**)&m_spObj);
if (FAILED(m_hrCreate))
{
delete p;
}
}
}
}
__finally
{
Unlock();
}
}
if (m_hrCreate == S_OK)
{
hRes = m_spObj->QueryInterface(riid, ppvObj);
}
else
{
hRes = m_hrCreate;
}
}
}
return hRes;
}
HRESULT m_hrCreate;
CComPtr<IUnknown> m_spObj;
}; STATUSMicrosoft has confirmed that this is a problem in the Microsoft products that are listed in the "Applies to" section.
Modification Type: | Minor | Last Reviewed: | 5/20/2005 |
---|
Keywords: | kbATLServer kbtshoot kbbug KB811591 kbAudDeveloper |
---|
|