Commit 5169f3c5 authored by Mike Hearn's avatar Mike Hearn Committed by Alexandre Julliard

Implement disconnect for proxies so that stubs are properly

destroyed.
parent fd233e22
...@@ -147,6 +147,7 @@ MARSHAL_Compare_Mids_NoInterface(wine_marshal_id *mid1, wine_marshal_id *mid2) { ...@@ -147,6 +147,7 @@ MARSHAL_Compare_Mids_NoInterface(wine_marshal_id *mid1, wine_marshal_id *mid2) {
} }
HRESULT MARSHAL_Find_Stub_Buffer(wine_marshal_id *mid,IRpcStubBuffer **stub); 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); HRESULT MARSHAL_GetStandardMarshalCF(LPVOID *ppv);
......
...@@ -91,6 +91,21 @@ static int nrofstubs = 0; ...@@ -91,6 +91,21 @@ static int nrofstubs = 0;
static mid2unknown *proxies = NULL; static mid2unknown *proxies = NULL;
static int nrofproxies = 0; 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 HRESULT
MARSHAL_Find_Stub_Server(wine_marshal_id *mid,LPUNKNOWN *punk) { MARSHAL_Find_Stub_Server(wine_marshal_id *mid,LPUNKNOWN *punk) {
int i; int i;
......
...@@ -65,6 +65,14 @@ typedef struct _wine_rpc_response_header { ...@@ -65,6 +65,14 @@ typedef struct _wine_rpc_response_header {
DWORD retval; DWORD retval;
} wine_rpc_response_header; } 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_START 0
#define REQSTATE_REQ_QUEUED 1 #define REQSTATE_REQ_QUEUED 1
#define REQSTATE_REQ_WAITING_FOR_REPLY 2 #define REQSTATE_REQ_WAITING_FOR_REPLY 2
...@@ -285,10 +293,25 @@ PipeBuf_AddRef(LPRPCCHANNELBUFFER iface) { ...@@ -285,10 +293,25 @@ PipeBuf_AddRef(LPRPCCHANNELBUFFER iface) {
static ULONG WINAPI static ULONG WINAPI
PipeBuf_Release(LPRPCCHANNELBUFFER iface) { PipeBuf_Release(LPRPCCHANNELBUFFER iface) {
ICOM_THIS(PipeBuf,iface); ICOM_THIS(PipeBuf,iface);
wine_rpc_disconnect_header header;
HANDLE pipe;
DWORD reqtype = REQTYPE_DISCONNECT;
This->ref--; This->ref--;
if (This->ref) if (This->ref)
return 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); HeapFree(GetProcessHeap(),0,This);
return 0; return 0;
} }
...@@ -631,7 +654,35 @@ _read_one(wine_pipe *xpipe) { ...@@ -631,7 +654,35 @@ _read_one(wine_pipe *xpipe) {
EnterCriticalSection(&(xpipe->crit)); EnterCriticalSection(&(xpipe->crit));
/*FIXME("%lx got reqtype %ld\n",GetCurrentProcessId(),reqtype);*/ /*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; wine_rpc_request *xreq;
RPC_GetRequest(&xreq); RPC_GetRequest(&xreq);
xreq->hPipe = xhPipe; xreq->hPipe = xhPipe;
...@@ -643,8 +694,7 @@ _read_one(wine_pipe *xpipe) { ...@@ -643,8 +694,7 @@ _read_one(wine_pipe *xpipe) {
if (hres) goto end; if (hres) goto end;
xreq->state = REQSTATE_REQ_GOT; xreq->state = REQSTATE_REQ_GOT;
goto end; goto end;
} } else if (reqtype == REQTYPE_RESPONSE) {
if (reqtype == REQTYPE_RESPONSE) {
wine_rpc_response_header resph; wine_rpc_response_header resph;
int i; int i;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment