Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
ab7f796f
Commit
ab7f796f
authored
Apr 04, 2007
by
Rob Shearman
Committed by
Alexandre Julliard
Apr 04, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ole32: Keep a list of the loaded dlls for each apartment.
Use it to make CoFreeUnusedLibraries per-apartment.
parent
30721a88
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
82 additions
and
31 deletions
+82
-31
compobj.c
dlls/ole32/compobj.c
+81
-30
compobj_private.h
dlls/ole32/compobj_private.h
+1
-0
compobj.c
dlls/ole32/tests/compobj.c
+0
-1
No files found.
dlls/ole32/compobj.c
View file @
ab7f796f
...
...
@@ -175,6 +175,12 @@ static CRITICAL_SECTION_DEBUG dll_cs_debug =
};
static
CRITICAL_SECTION
csOpenDllList
=
{
&
dll_cs_debug
,
-
1
,
0
,
0
,
0
,
0
};
struct
apartment_loaded_dll
{
struct
list
entry
;
OpenDll
*
dll
;
};
static
const
WCHAR
wszAptWinClass
[]
=
{
'O'
,
'l'
,
'e'
,
'M'
,
'a'
,
'i'
,
'n'
,
'T'
,
'h'
,
'r'
,
'e'
,
'a'
,
'd'
,
'W'
,
'n'
,
'd'
,
'C'
,
'l'
,
'a'
,
's'
,
's'
,
' '
,
'0'
,
'x'
,
'#'
,
'#'
,
'#'
,
'#'
,
'#'
,
'#'
,
'#'
,
'#'
,
' '
,
0
};
static
LRESULT
CALLBACK
apartment_wndproc
(
HWND
hWnd
,
UINT
msg
,
WPARAM
wParam
,
LPARAM
lParam
);
...
...
@@ -184,7 +190,6 @@ static HRESULT apartment_getclassobject(struct apartment *apt, LPCWSTR dllpath,
static
HRESULT
COMPOBJ_DllList_Add
(
LPCWSTR
library_name
,
OpenDll
**
ret
);
static
OpenDll
*
COMPOBJ_DllList_Get
(
LPCWSTR
library_name
);
static
void
COMPOBJ_DllList_ReleaseRef
(
OpenDll
*
entry
);
static
void
COMPOBJ_DllList_FreeUnused
(
int
Timeout
);
static
DWORD
COM_RegReadPath
(
HKEY
hkeyroot
,
const
WCHAR
*
keyname
,
const
WCHAR
*
valuename
,
WCHAR
*
dst
,
DWORD
dstlen
);
...
...
@@ -244,6 +249,7 @@ static APARTMENT *apartment_construct(DWORD model)
list_init
(
&
apt
->
proxies
);
list_init
(
&
apt
->
stubmgrs
);
list_init
(
&
apt
->
psclsids
);
list_init
(
&
apt
->
loaded_dlls
);
apt
->
ipidc
=
0
;
apt
->
refs
=
1
;
apt
->
remunk_exported
=
FALSE
;
...
...
@@ -389,6 +395,14 @@ DWORD apartment_release(struct apartment *apt)
if
(
apt
->
filter
)
IUnknown_Release
(
apt
->
filter
);
while
((
cursor
=
list_head
(
&
apt
->
loaded_dlls
)))
{
struct
apartment_loaded_dll
*
apartment_loaded_dll
=
LIST_ENTRY
(
cursor
,
struct
apartment_loaded_dll
,
entry
);
COMPOBJ_DllList_ReleaseRef
(
apartment_loaded_dll
->
dll
);
list_remove
(
cursor
);
HeapFree
(
GetProcessHeap
(),
0
,
apartment_loaded_dll
);
}
DEBUG_CLEAR_CRITSEC_NAME
(
&
apt
->
cs
);
DeleteCriticalSection
(
&
apt
->
cs
);
...
...
@@ -569,21 +583,69 @@ void apartment_joinmta(void)
static
HRESULT
apartment_getclassobject
(
struct
apartment
*
apt
,
LPCWSTR
dllpath
,
REFCLSID
rclsid
,
REFIID
riid
,
void
**
ppv
)
{
OpenDll
*
open_dll_entry
;
HRESULT
hr
;
HRESULT
hr
=
S_OK
;
BOOL
found
=
FALSE
;
struct
apartment_loaded_dll
*
apartment_loaded_dll
;
hr
=
COMPOBJ_DllList_Add
(
dllpath
,
&
open_dll_entry
);
if
(
FAILED
(
hr
))
return
hr
;
EnterCriticalSection
(
&
apt
->
cs
);
hr
=
open_dll_entry
->
DllGetClassObject
(
rclsid
,
riid
,
ppv
);
LIST_FOR_EACH_ENTRY
(
apartment_loaded_dll
,
&
apt
->
loaded_dlls
,
struct
apartment_loaded_dll
,
entry
)
if
(
!
strcmpiW
(
dllpath
,
apartment_loaded_dll
->
dll
->
library_name
))
{
TRACE
(
"found %s already loaded
\n
"
,
debugstr_w
(
dllpath
));
found
=
TRUE
;
break
;
}
if
(
hr
!=
S_OK
)
ERR
(
"DllGetClassObject returned error 0x%08x
\n
"
,
hr
);
if
(
!
found
)
{
apartment_loaded_dll
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
apartment_loaded_dll
));
if
(
!
apartment_loaded_dll
)
hr
=
E_OUTOFMEMORY
;
if
(
SUCCEEDED
(
hr
))
{
hr
=
COMPOBJ_DllList_Add
(
dllpath
,
&
apartment_loaded_dll
->
dll
);
if
(
FAILED
(
hr
))
HeapFree
(
GetProcessHeap
(),
0
,
apartment_loaded_dll
);
}
if
(
SUCCEEDED
(
hr
))
{
TRACE
(
"added new loaded dll %s
\n
"
,
debugstr_w
(
dllpath
));
list_add_tail
(
&
apt
->
loaded_dlls
,
&
apartment_loaded_dll
->
entry
);
}
}
LeaveCriticalSection
(
&
apt
->
cs
);
if
(
SUCCEEDED
(
hr
))
{
TRACE
(
"calling DllGetClassObject %p
\n
"
,
apartment_loaded_dll
->
dll
->
DllGetClassObject
);
/* OK: get the ClassObject */
hr
=
apartment_loaded_dll
->
dll
->
DllGetClassObject
(
rclsid
,
riid
,
ppv
);
if
(
hr
!=
S_OK
)
ERR
(
"DllGetClassObject returned error 0x%08x
\n
"
,
hr
);
}
return
hr
;
}
static
void
apartment_freeunusedlibraries
(
struct
apartment
*
apt
)
{
struct
apartment_loaded_dll
*
entry
,
*
next
;
EnterCriticalSection
(
&
apt
->
cs
);
LIST_FOR_EACH_ENTRY_SAFE
(
entry
,
next
,
&
apt
->
loaded_dlls
,
struct
apartment_loaded_dll
,
entry
)
{
if
(
entry
->
dll
->
DllCanUnloadNow
&&
(
entry
->
dll
->
DllCanUnloadNow
()
==
S_OK
))
{
list_remove
(
&
entry
->
entry
);
COMPOBJ_DllList_ReleaseRef
(
entry
->
dll
);
HeapFree
(
GetProcessHeap
(),
0
,
entry
);
}
}
LeaveCriticalSection
(
&
apt
->
cs
);
}
/*****************************************************************************
* This section contains OpenDllList implementation
*/
...
...
@@ -668,7 +730,8 @@ static OpenDll *COMPOBJ_DllList_Get(LPCWSTR library_name)
EnterCriticalSection
(
&
csOpenDllList
);
LIST_FOR_EACH_ENTRY
(
ptr
,
&
openDllList
,
OpenDll
,
entry
)
{
if
(
!
strcmpiW
(
library_name
,
ptr
->
library_name
))
if
(
!
strcmpiW
(
library_name
,
ptr
->
library_name
)
&&
(
InterlockedIncrement
(
&
ptr
->
refs
)
!=
1
)
/* entry is being destroy if == 1 */
)
{
ret
=
ptr
;
break
;
...
...
@@ -694,23 +757,6 @@ static void COMPOBJ_DllList_ReleaseRef(OpenDll *entry)
}
}
static
void
COMPOBJ_DllList_FreeUnused
(
int
Timeout
)
{
OpenDll
*
curr
,
*
next
;
TRACE
(
"
\n
"
);
EnterCriticalSection
(
&
csOpenDllList
);
LIST_FOR_EACH_ENTRY_SAFE
(
curr
,
next
,
&
openDllList
,
OpenDll
,
entry
)
{
if
(
(
curr
->
DllCanUnloadNow
!=
NULL
)
&&
(
curr
->
DllCanUnloadNow
()
==
S_OK
)
)
COMPOBJ_DllList_ReleaseRef
(
curr
);
}
LeaveCriticalSection
(
&
csOpenDllList
);
}
/******************************************************************************
* CoBuildVersion [OLE32.@]
* CoBuildVersion [COMPOBJ.1]
...
...
@@ -2314,9 +2360,14 @@ void WINAPI CoFreeAllLibraries(void)
*/
void
WINAPI
CoFreeUnusedLibraries
(
void
)
{
/* FIXME: Calls to CoFreeUnusedLibraries from any thread always route
* through the main apartment's thread to call DllCanUnloadNow */
COMPOBJ_DllList_FreeUnused
(
0
);
struct
apartment
*
apt
=
COM_CurrentApt
();
if
(
!
apt
)
{
ERR
(
"apartment not initialised
\n
"
);
return
;
}
apartment_freeunusedlibraries
(
apt
);
}
/***********************************************************************
...
...
dlls/ole32/compobj_private.h
View file @
ab7f796f
...
...
@@ -154,6 +154,7 @@ struct apartment
BOOL
remunk_exported
;
/* has the IRemUnknown interface for this apartment been created yet? (CS cs) */
LONG
remoting_started
;
/* has the RPC system been started for this apartment? (LOCK) */
struct
list
psclsids
;
/* list of registered PS CLSIDs (CS cs) */
struct
list
loaded_dlls
;
/* list of dlls loaded by this apartment (CS cs) */
/* FIXME: OID's should be given out by RPCSS */
OID
oidc
;
/* object ID counter, starts at 1, zero is invalid OID (CS cs) */
...
...
dlls/ole32/tests/compobj.c
View file @
ab7f796f
...
...
@@ -742,7 +742,6 @@ static void test_CoFreeUnusedLibraries(void)
WaitForSingleObject
(
thread
,
INFINITE
);
CloseHandle
(
thread
);
todo_wine
ok
(
is_module_loaded
(
"urlmon.dll"
),
"urlmon.dll should be loaded
\n
"
);
CoFreeUnusedLibraries
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment