DCOM: Proxy Disconnect
Robert Shearman
rob at codeweavers.com
Wed Jul 28 13:22:56 CDT 2004
Changelog:
Mike Hearn <mh at codeweavers.com>
Implement disconnect for proxies so that stubs are properly destroyed.
-------------- next part --------------
Index: wine/dlls/ole32/compobj_private.h
===================================================================
RCS file: /home/wine/wine/dlls/ole32/compobj_private.h,v
retrieving revision 1.14
diff -u -r1.14 compobj_private.h
--- wine/dlls/ole32/compobj_private.h 22 Jul 2004 23:44:54 -0000 1.14
+++ wine/dlls/ole32/compobj_private.h 28 Jul 2004 13:43:47 -0000
@@ -147,6 +147,7 @@
}
HRESULT MARSHAL_Find_Stub_Buffer(wine_marshal_id *mid,IRpcStubBuffer **stub);
+void MARSHAL_Invalidate_Stub_From_MID(wine_marshal_id *mid);
HRESULT MARSHAL_GetStandardMarshalCF(LPVOID *ppv);
Index: wine/dlls/ole32/marshal.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/marshal.c,v
retrieving revision 1.23
diff -u -r1.23 marshal.c
--- wine/dlls/ole32/marshal.c 23 Jul 2004 19:10:13 -0000 1.23
+++ wine/dlls/ole32/marshal.c 28 Jul 2004 13:43:47 -0000
@@ -91,6 +91,21 @@
static mid2unknown *proxies = NULL;
static int nrofproxies = 0;
+void MARSHAL_Invalidate_Stub_From_MID(wine_marshal_id *mid) {
+ int i;
+
+ for (i=0;i<nrofstubs;i++) {
+ if (!stubs[i].valid) continue;
+
+ if (MARSHAL_Compare_Mids(mid,&(stubs[i].mid))) {
+ stubs[i].valid = FALSE;
+ return;
+ }
+ }
+
+ return;
+}
+
HRESULT
MARSHAL_Find_Stub_Server(wine_marshal_id *mid,LPUNKNOWN *punk) {
int i;
Index: wine/dlls/ole32/rpc.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/rpc.c,v
retrieving revision 1.19
diff -u -r1.19 rpc.c
--- wine/dlls/ole32/rpc.c 23 Jul 2004 22:58:13 -0000 1.19
+++ wine/dlls/ole32/rpc.c 28 Jul 2004 13:43:48 -0000
@@ -65,6 +65,14 @@
DWORD retval;
} wine_rpc_response_header;
+/* used when shutting down a pipe, e.g. at the end of a process */
+#define REQTYPE_DISCONNECT 2
+typedef struct _wine_rpc_disconnect_header {
+ DWORD reqid;
+ wine_marshal_id mid; /* mid of stub to delete */
+} wine_rpc_disconnect_header;
+
+
#define REQSTATE_START 0
#define REQSTATE_REQ_QUEUED 1
#define REQSTATE_REQ_WAITING_FOR_REPLY 2
@@ -284,10 +292,25 @@
static ULONG WINAPI
PipeBuf_Release(LPRPCCHANNELBUFFER iface) {
ICOM_THIS(PipeBuf,iface);
+ wine_rpc_disconnect_header header;
+ HANDLE pipe;
+ DWORD reqtype = REQTYPE_DISCONNECT;
+
This->ref--;
if (This->ref)
return This->ref;
- ERR("Free all stuff.\n");
+
+ FIXME("Free all stuff\n");
+
+ memcpy(&header.mid, &This->mid, sizeof(wine_marshal_id));
+
+ pipe = PIPE_FindByMID(&This->mid);
+
+ _xwrite(pipe, &reqtype, sizeof(reqtype));
+ _xwrite(pipe, &header, sizeof(wine_rpc_disconnect_header));
+
+ TRACE("written disconnect packet\n");
+
HeapFree(GetProcessHeap(),0,This);
return 0;
}
@@ -629,7 +655,35 @@
EnterCriticalSection(&(xpipe->crit));
/*FIXME("%lx got reqtype %ld\n",GetCurrentProcessId(),reqtype);*/
- if (reqtype == REQTYPE_REQUEST) {
+ if (reqtype == REQTYPE_DISCONNECT) { /* only received by servers */
+ wine_rpc_disconnect_header header;
+ IRpcStubBuffer *stub;
+ ULONG ret;
+
+ hres = _xread(xhPipe, &header, sizeof(header));
+ if (hres) {
+ ERR("could not read disconnect header\n");
+ goto end;
+ }
+
+ TRACE("read disconnect header\n");
+
+ hres = MARSHAL_Find_Stub_Buffer(&header.mid, &stub);
+ if (hres) {
+ ERR("could not locate stub to disconnect, mid.objectid=%p\n", (void*)header.mid.objectid);
+ goto end;
+ }
+
+
+ /* release reference added by MARSHAL_Find_Stub_Buffer call */
+ IRpcStubBuffer_Release(stub);
+ /* release it for real */
+ ret = IRpcStubBuffer_Release(stub);
+ /* FIXME: race */
+ if (ret == 0)
+ MARSHAL_Invalidate_Stub_From_MID(&header.mid);
+ goto end;
+ } else if (reqtype == REQTYPE_REQUEST) {
wine_rpc_request *xreq;
RPC_GetRequest(&xreq);
xreq->hPipe = xhPipe;
@@ -641,8 +695,7 @@
if (hres) goto end;
xreq->state = REQSTATE_REQ_GOT;
goto end;
- }
- if (reqtype == REQTYPE_RESPONSE) {
+ } else if (reqtype == REQTYPE_RESPONSE) {
wine_rpc_response_header resph;
int i;
More information about the wine-patches
mailing list