ole32: Postpone removing a being destroyed apartment from the global list.
Dmitry Timoshkov
dmitry at baikal.ru
Fri Jun 7 04:29:29 CDT 2013
StdMarshalImpl_ReleaseMarshalData called from apartment_release() needs to
access apartment data, but fails because an apartment has already been removed
from the global list. That leads to lost connections and memory leaks.
Found with a not yet accepted local server test.
---
dlls/ole32/compobj.c | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c
index 92ace8a..d025820 100644
--- a/dlls/ole32/compobj.c
+++ b/dlls/ole32/compobj.c
@@ -960,19 +960,8 @@ DWORD apartment_release(struct apartment *apt)
{
DWORD ret;
- EnterCriticalSection(&csApartment);
-
ret = InterlockedDecrement(&apt->refs);
TRACE("%s: after = %d\n", wine_dbgstr_longlong(apt->oxid), ret);
- /* destruction stuff that needs to happen under csApartment CS */
- if (ret == 0)
- {
- if (apt == MTA) MTA = NULL;
- else if (apt == MainApartment) MainApartment = NULL;
- list_remove(&apt->entry);
- }
-
- LeaveCriticalSection(&csApartment);
if (ret == 0)
{
@@ -980,6 +969,9 @@ DWORD apartment_release(struct apartment *apt)
TRACE("destroying apartment %p, oxid %s\n", apt, wine_dbgstr_longlong(apt->oxid));
+ /* Pin the apartment reference, so it doesn't get recursively destroyed */
+ InterlockedIncrement(&apt->refs);
+
if(apt->local_server) {
LocalServer *local_server = apt->local_server;
LARGE_INTEGER zero;
@@ -1006,6 +998,13 @@ DWORD apartment_release(struct apartment *apt)
if (apt->win) DestroyWindow(apt->win);
if (apt->host_apt_tid) PostThreadMessageW(apt->host_apt_tid, WM_QUIT, 0, 0);
+ /* destruction stuff that needs to happen under csApartment CS */
+ EnterCriticalSection(&csApartment);
+ if (apt == MTA) MTA = NULL;
+ else if (apt == MainApartment) MainApartment = NULL;
+ list_remove(&apt->entry);
+ LeaveCriticalSection(&csApartment);
+
LIST_FOR_EACH_SAFE(cursor, cursor2, &apt->stubmgrs)
{
struct stub_manager *stubmgr = LIST_ENTRY(cursor, struct stub_manager, entry);
--
1.8.3
More information about the wine-patches
mailing list