Implement disconnect for proxies so that stubs are properly

destroyed.
oldstable
Mike Hearn 2004-07-29 23:58:12 +00:00 committed by Alexandre Julliard
parent fd233e2235
commit 5169f3c5d2
3 changed files with 70 additions and 4 deletions

View File

@ -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);
void MARSHAL_Invalidate_Stub_From_MID(wine_marshal_id *mid);
HRESULT MARSHAL_GetStandardMarshalCF(LPVOID *ppv);

View File

@ -91,6 +91,21 @@ static int nrofstubs = 0;
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;

View File

@ -65,6 +65,14 @@ typedef struct _wine_rpc_response_header {
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
@ -285,10 +293,25 @@ PipeBuf_AddRef(LPRPCCHANNELBUFFER iface) {
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;
}
@ -631,7 +654,35 @@ _read_one(wine_pipe *xpipe) {
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;
@ -643,8 +694,7 @@ _read_one(wine_pipe *xpipe) {
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;