Rob Shearman : rpcss: Use context handles to automatically free running object table entries if the client process quits without calling IrotRevoke .
Alexandre Julliard
julliard at winehq.org
Wed Dec 26 10:05:06 CST 2007
Module: wine
Branch: master
Commit: 9804aba758ca5eba5c92a2dabeb965fb170992da
URL: http://source.winehq.org/git/wine.git/?a=commit;h=9804aba758ca5eba5c92a2dabeb965fb170992da
Author: Rob Shearman <rob at codeweavers.com>
Date: Tue Dec 25 19:08:25 2007 +0000
rpcss: Use context handles to automatically free running object table entries if the client process quits without calling IrotRevoke.
---
dlls/ole32/moniker.c | 9 +++++++--
include/wine/irot.idl | 5 ++++-
programs/rpcss/irotp.c | 46 +++++++++++++++++++++++++++++++++-------------
3 files changed, 44 insertions(+), 16 deletions(-)
diff --git a/dlls/ole32/moniker.c b/dlls/ole32/moniker.c
index 8511a9f..e77c8c4 100644
--- a/dlls/ole32/moniker.c
+++ b/dlls/ole32/moniker.c
@@ -73,6 +73,7 @@ struct rot_entry
MonikerComparisonData* moniker_data; /* moniker comparison data that identifies this object */
DWORD cookie; /* cookie identifying this object */
FILETIME last_modified;
+ IrotContextHandle ctxt_handle;
};
/* define the RunningObjectTableImpl structure */
@@ -183,7 +184,8 @@ static inline void rot_entry_delete(struct rot_entry *rot_entry)
InterfaceData *moniker = NULL;
__TRY
{
- IrotRevoke(get_irot_handle(), rot_entry->cookie, &object, &moniker);
+ IrotRevoke(get_irot_handle(), rot_entry->cookie,
+ &rot_entry->ctxt_handle, &object, &moniker);
}
__EXCEPT(rpc_filter)
{
@@ -554,7 +556,10 @@ RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,
{
__TRY
{
- hr = IrotRegister(get_irot_handle(), rot_entry->moniker_data, rot_entry->object, moniker, &rot_entry->last_modified, grfFlags, &rot_entry->cookie);
+ hr = IrotRegister(get_irot_handle(), rot_entry->moniker_data,
+ rot_entry->object, moniker,
+ &rot_entry->last_modified, grfFlags,
+ &rot_entry->cookie, &rot_entry->ctxt_handle);
}
__EXCEPT(rpc_filter)
{
diff --git a/include/wine/irot.idl b/include/wine/irot.idl
index e480b45..f14af13 100644
--- a/include/wine/irot.idl
+++ b/include/wine/irot.idl
@@ -51,6 +51,7 @@ interface Irot
typedef DWORD IrotCookie;
typedef handle_t IrotHandle;
+ typedef [context_handle] void *IrotContextHandle;
HRESULT IrotRegister(
[in] IrotHandle h,
@@ -59,11 +60,13 @@ interface Irot
[in] const InterfaceData *moniker,
[in] const FILETIME *time,
[in] DWORD grfFlags,
- [out] IrotCookie *cookie);
+ [out] IrotCookie *cookie,
+ [out] IrotContextHandle *ctxt_handle);
HRESULT IrotRevoke(
[in] IrotHandle h,
[in] IrotCookie cookie,
+ [in, out] IrotContextHandle *ctxt_handle,
[out] PInterfaceData *object,
[out] PInterfaceData *moniker);
diff --git a/programs/rpcss/irotp.c b/programs/rpcss/irotp.c
index fd40625..7832ac7 100644
--- a/programs/rpcss/irotp.c
+++ b/programs/rpcss/irotp.c
@@ -41,6 +41,7 @@ struct rot_entry
MonikerComparisonData *moniker_data; /* moniker comparison data that identifies this object */
DWORD cookie; /* cookie identifying this object */
FILETIME last_modified;
+ LONG refs;
};
static struct list RunningObjectTable = LIST_INIT(RunningObjectTable);
@@ -56,12 +57,15 @@ static CRITICAL_SECTION csRunningObjectTable = { &critsect_debug, -1, 0, 0, 0, 0
static LONG last_cookie = 1;
-static inline void rot_entry_delete(struct rot_entry *rot_entry)
+static inline void rot_entry_release(struct rot_entry *rot_entry)
{
- HeapFree(GetProcessHeap(), 0, rot_entry->object);
- HeapFree(GetProcessHeap(), 0, rot_entry->moniker);
- HeapFree(GetProcessHeap(), 0, rot_entry->moniker_data);
- HeapFree(GetProcessHeap(), 0, rot_entry);
+ if (!InterlockedDecrement(&rot_entry->refs))
+ {
+ HeapFree(GetProcessHeap(), 0, rot_entry->object);
+ HeapFree(GetProcessHeap(), 0, rot_entry->moniker);
+ HeapFree(GetProcessHeap(), 0, rot_entry->moniker_data);
+ HeapFree(GetProcessHeap(), 0, rot_entry);
+ }
}
HRESULT IrotRegister(
@@ -71,10 +75,11 @@ HRESULT IrotRegister(
const InterfaceData *mk,
const FILETIME *time,
DWORD grfFlags,
- IrotCookie *cookie)
+ IrotCookie *cookie,
+ IrotContextHandle *ctxt_handle)
{
struct rot_entry *rot_entry;
- const struct rot_entry *existing_rot_entry;
+ struct rot_entry *existing_rot_entry;
HRESULT hr;
if (grfFlags & ~(ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT))
@@ -87,10 +92,11 @@ HRESULT IrotRegister(
if (!rot_entry)
return E_OUTOFMEMORY;
+ rot_entry->refs = 1;
rot_entry->object = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(InterfaceData, abData[obj->ulCntData]));
if (!rot_entry->object)
{
- rot_entry_delete(rot_entry);
+ rot_entry_release(rot_entry);
return E_OUTOFMEMORY;
}
rot_entry->object->ulCntData = obj->ulCntData;
@@ -101,7 +107,7 @@ HRESULT IrotRegister(
rot_entry->moniker = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(InterfaceData, abData[mk->ulCntData]));
if (!rot_entry->moniker)
{
- rot_entry_delete(rot_entry);
+ rot_entry_release(rot_entry);
return E_OUTOFMEMORY;
}
rot_entry->moniker->ulCntData = mk->ulCntData;
@@ -110,7 +116,7 @@ HRESULT IrotRegister(
rot_entry->moniker_data = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(MonikerComparisonData, abData[data->ulCntData]));
if (!rot_entry->moniker_data)
{
- rot_entry_delete(rot_entry);
+ rot_entry_release(rot_entry);
return E_OUTOFMEMORY;
}
rot_entry->moniker_data->ulCntData = data->ulCntData;
@@ -120,7 +126,7 @@ HRESULT IrotRegister(
hr = S_OK;
- LIST_FOR_EACH_ENTRY(existing_rot_entry, &RunningObjectTable, const struct rot_entry, entry)
+ LIST_FOR_EACH_ENTRY(existing_rot_entry, &RunningObjectTable, struct rot_entry, entry)
{
if ((existing_rot_entry->moniker_data->ulCntData == data->ulCntData) &&
!memcmp(&data->abData, &existing_rot_entry->moniker_data->abData, data->ulCntData))
@@ -136,11 +142,14 @@ HRESULT IrotRegister(
list_add_tail(&RunningObjectTable, &rot_entry->entry);
/* gives a registration identifier to the registered object*/
*cookie = rot_entry->cookie = InterlockedIncrement(&last_cookie);
+ *ctxt_handle = rot_entry;
}
else
{
- rot_entry_delete(rot_entry);
+ rot_entry_release(rot_entry);
*cookie = existing_rot_entry->cookie;
+ InterlockedIncrement(&existing_rot_entry->refs);
+ *ctxt_handle = existing_rot_entry;
}
@@ -152,6 +161,7 @@ HRESULT IrotRegister(
HRESULT IrotRevoke(
IrotHandle h,
IrotCookie cookie,
+ IrotContextHandle *ctxt_handle,
PInterfaceData *obj,
PInterfaceData *mk)
{
@@ -185,7 +195,8 @@ HRESULT IrotRevoke(
hr = E_OUTOFMEMORY;
}
- rot_entry_delete(rot_entry);
+ rot_entry_release(rot_entry);
+ *ctxt_handle = NULL;
return hr;
}
}
@@ -354,6 +365,15 @@ HRESULT IrotEnumRunning(
return hr;
}
+void __RPC_USER IrotContextHandle_rundown(IrotContextHandle ctxt_handle)
+{
+ struct rot_entry *rot_entry = ctxt_handle;
+ EnterCriticalSection(&csRunningObjectTable);
+ list_remove(&rot_entry->entry);
+ LeaveCriticalSection(&csRunningObjectTable);
+ rot_entry_release(rot_entry);
+}
+
void * __RPC_USER MIDL_user_allocate(size_t size)
{
return HeapAlloc(GetProcessHeap(), 0, size);
More information about the wine-cvs
mailing list