Synchronize access to the s_COMLockCount, firstRegisteredClass,

openDllList in compobj.
This commit is contained in:
Hidenori Takeshima 2001-09-11 00:26:12 +00:00 committed by Alexandre Julliard
parent a2ae982978
commit aad36bcd59
3 changed files with 160 additions and 101 deletions

View File

@ -123,7 +123,7 @@ WORD Table_ETask[62];
* decreased every time CoUninitialize is called. When it hits 0, the COM
* libraries are freed
*/
static ULONG s_COMLockCount = 0;
static LONG s_COMLockCount = 0;
/*
* This linked list contains the list of registered class objects. These
@ -143,6 +143,7 @@ typedef struct tagRegisteredClass
struct tagRegisteredClass* nextClass;
} RegisteredClass;
static CRITICAL_SECTION csRegisteredClassList;
static RegisteredClass* firstRegisteredClass = NULL;
/* this open DLL table belongs in a per process table, but my guess is that
@ -154,6 +155,7 @@ typedef struct tagOpenDll {
struct tagOpenDll *next;
} OpenDll;
static CRITICAL_SECTION csOpenDllList;
static OpenDll *openDllList = NULL; /* linked list of open dlls */
/*****************************************************************************
@ -167,6 +169,21 @@ static HRESULT COM_GetRegisteredClassObject(REFCLSID rclsid,
static void COM_RevokeAllClasses();
/******************************************************************************
* Initialize/Uninitialize critical sections.
*/
void COMPOBJ_InitProcess( void )
{
InitializeCriticalSection( &csRegisteredClassList );
InitializeCriticalSection( &csOpenDllList );
}
void COMPOBJ_UninitProcess( void )
{
DeleteCriticalSection( &csRegisteredClassList );
DeleteCriticalSection( &csOpenDllList );
}
/******************************************************************************
* CoBuildVersion [COMPOBJ.1]
* CoBuildVersion [OLE32.4]
@ -254,14 +271,17 @@ HRESULT WINAPI CoInitializeEx(
/*
* Check the lock count. If this is the first time going through the initialize
* process, we have to initialize the libraries.
*
* And crank-up that lock count.
*/
if (s_COMLockCount==0)
if (InterlockedExchangeAdd(&s_COMLockCount,1)==0)
{
/*
* Initialize the various COM libraries and data structures.
*/
TRACE("() - Initializing the COM libraries\n");
RunningObjectTableImpl_Initialize();
hr = S_OK;
@ -269,11 +289,6 @@ HRESULT WINAPI CoInitializeEx(
else
hr = S_FALSE;
/*
* Crank-up that lock count.
*/
s_COMLockCount++;
return hr;
}
@ -298,18 +313,16 @@ void WINAPI CoUninitialize16(void)
*/
void WINAPI CoUninitialize(void)
{
LONG lCOMRefCnt;
TRACE("()\n");
/*
* Decrease the reference count.
*/
s_COMLockCount--;
/*
* If we are back to 0 locks on the COM library, make sure we free
* all the associated data structures.
*/
if (s_COMLockCount==0)
lCOMRefCnt = InterlockedExchangeAdd(&s_COMLockCount,-1);
if (lCOMRefCnt==1)
{
/*
* Release the various COM libraries and data structures.
@ -331,7 +344,12 @@ void WINAPI CoUninitialize(void)
* This will free list of external references to COM objects.
*/
COM_ExternalLockFreeList();
}
}
else if (lCOMRefCnt<1) {
ERR( "CoUninitialize() - not CoInitialized.\n" );
InterlockedExchangeAdd(&s_COMLockCount,1); /* restore the lock count. */
}
}
/***********************************************************************
@ -973,8 +991,11 @@ static HRESULT COM_GetRegisteredClassObject(
DWORD dwClsContext,
LPUNKNOWN* ppUnk)
{
HRESULT hr = S_FALSE;
RegisteredClass* curClass;
EnterCriticalSection( &csRegisteredClassList );
/*
* Sanity check
*/
@ -1004,7 +1025,8 @@ static HRESULT COM_GetRegisteredClassObject(
IUnknown_AddRef(curClass->classObject);
return S_OK;
hr = S_OK;
goto end;
}
/*
@ -1013,10 +1035,12 @@ static HRESULT COM_GetRegisteredClassObject(
curClass = curClass->nextClass;
}
end:
LeaveCriticalSection( &csRegisteredClassList );
/*
* If we get to here, we haven't found our class.
*/
return S_FALSE;
return hr;
}
/******************************************************************************
@ -1050,7 +1074,7 @@ HRESULT WINAPI CoRegisterClassObject(
if ( (lpdwRegister==0) || (pUnk==0) )
{
return E_INVALIDARG;
}
}
/*
* Initialize the cookie (out parameter)
@ -1081,7 +1105,10 @@ HRESULT WINAPI CoRegisterClassObject(
* unique.
*/
newClass = HeapAlloc(GetProcessHeap(), 0, sizeof(RegisteredClass));
if ( newClass == NULL )
return E_OUTOFMEMORY;
EnterCriticalSection( &csRegisteredClassList );
/*
* Initialize the node.
*/
@ -1100,6 +1127,8 @@ HRESULT WINAPI CoRegisterClassObject(
firstRegisteredClass = newClass;
LeaveCriticalSection( &csRegisteredClassList );
/*
* Assign the out parameter (cookie)
*/
@ -1121,11 +1150,14 @@ HRESULT WINAPI CoRegisterClassObject(
HRESULT WINAPI CoRevokeClassObject(
DWORD dwRegister)
{
HRESULT hr = E_INVALIDARG;
RegisteredClass** prevClassLink;
RegisteredClass* curClass;
TRACE("(%08lx)\n",dwRegister);
EnterCriticalSection( &csRegisteredClassList );
/*
* Iterate through the whole list and try to match the cookie.
*/
@ -1154,8 +1186,9 @@ HRESULT WINAPI CoRevokeClassObject(
*/
HeapFree(GetProcessHeap(), 0, curClass);
return S_OK;
}
hr = S_OK;
goto end;
}
/*
* Step to the next class in the list.
@ -1164,10 +1197,12 @@ HRESULT WINAPI CoRevokeClassObject(
curClass = curClass->nextClass;
}
end:
LeaveCriticalSection( &csRegisteredClassList );
/*
* If we get to here, we haven't found our class.
*/
return E_INVALIDARG;
return hr;
}
/***********************************************************************
@ -1513,6 +1548,8 @@ void WINAPI CoFreeLibrary(HINSTANCE hLibrary)
OpenDll *ptr, *prev;
OpenDll *tmp;
EnterCriticalSection( &csOpenDllList );
/* lookup library in linked list */
prev = NULL;
for (ptr = openDllList; ptr != NULL; ptr=ptr->next) {
@ -1524,7 +1561,7 @@ void WINAPI CoFreeLibrary(HINSTANCE hLibrary)
if (ptr == NULL) {
/* shouldn't happen if user passed in a valid hLibrary */
return;
goto end;
}
/* assert: ptr points to the library entry to free */
@ -1539,7 +1576,8 @@ void WINAPI CoFreeLibrary(HINSTANCE hLibrary)
HeapFree(GetProcessHeap(), 0, ptr);
prev->next = tmp;
}
end:
LeaveCriticalSection( &csOpenDllList );
}
@ -1550,11 +1588,15 @@ void WINAPI CoFreeAllLibraries(void)
{
OpenDll *ptr, *tmp;
EnterCriticalSection( &csOpenDllList );
for (ptr = openDllList; ptr != NULL; ) {
tmp=ptr->next;
CoFreeLibrary(ptr->hLibrary);
ptr = tmp;
}
LeaveCriticalSection( &csOpenDllList );
}
@ -1569,6 +1611,8 @@ void WINAPI CoFreeUnusedLibraries(void)
typedef HRESULT(*DllCanUnloadNowFunc)(void);
DllCanUnloadNowFunc DllCanUnloadNow;
EnterCriticalSection( &csOpenDllList );
for (ptr = openDllList; ptr != NULL; ) {
DllCanUnloadNow = (DllCanUnloadNowFunc)
GetProcAddress(ptr->hLibrary, "DllCanUnloadNow");
@ -1582,6 +1626,8 @@ void WINAPI CoFreeUnusedLibraries(void)
ptr=ptr->next;
}
}
LeaveCriticalSection( &csOpenDllList );
}
/***********************************************************************
@ -1662,6 +1708,8 @@ HINSTANCE WINAPI CoLoadLibrary(LPOLESTR lpszLibName, BOOL bAutoFree)
if (!bAutoFree)
return hLibrary;
EnterCriticalSection( &csOpenDllList );
if (openDllList == NULL) {
/* empty list -- add first node */
openDllList = (OpenDll*)HeapAlloc(GetProcessHeap(),0, sizeof(OpenDll));
@ -1685,6 +1733,8 @@ HINSTANCE WINAPI CoLoadLibrary(LPOLESTR lpszLibName, BOOL bAutoFree)
}
}
LeaveCriticalSection( &csOpenDllList );
return hLibrary;
}
@ -1786,10 +1836,14 @@ HRESULT WINAPI OLE32_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
*/
static void COM_RevokeAllClasses()
{
EnterCriticalSection( &csRegisteredClassList );
while (firstRegisteredClass!=0)
{
CoRevokeClassObject(firstRegisteredClass->dwCookie);
}
LeaveCriticalSection( &csRegisteredClassList );
}
/****************************************************************************

View File

@ -22,9 +22,11 @@ BOOL WINAPI OLE32_DllEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImp
switch(fdwReason) {
case DLL_PROCESS_ATTACH:
OLE32_hInstance = hinstDLL;
COMPOBJ_InitProcess();
break;
case DLL_PROCESS_DETACH:
COMPOBJ_UninitProcess();
OLE32_hInstance = 0;
break;
}

View File

@ -5,4 +5,7 @@
extern HINSTANCE OLE32_hInstance;
void COMPOBJ_InitProcess( void );
void COMPOBJ_UninitProcess( void );
#endif /* __WINE_OLE32_MAIN_H */