How to call release from COM server

2019-05-28 21:09发布

I am writing a Com server and I have wrote code that detect situation when COM client was closed unexpectedly, in this case I should close COM server inside COM server code.

How can I do this?

UPD: I have situations when COM server is hanged or more correctly I can't attach to COM server from COM client, but application that contains COM server is alive, so I think that COM server can detect that all old COM clients was disconnected/closed/crashed and application will restart because no new clients attached.

I have write the following code in COM client in separate thread

while(not we are closing)
{
   unknown->QueryInterface(IComServer, &server);

   if (server)
     return;
}

so the COM client can wait until server will really ready to work

UPD2: Just tested: after 12 minutes my COM server was closed

标签: windows com
3条回答
贪生不怕死
2楼-- · 2019-05-28 21:36

COM will release the server-side object in an out-proc server some time after the client dies but only if there's no call executing in that object. This is the key - COM can't possibly stop a call in progress. So the solution is to make methods short-running and guaranteed to finish in some short reasonable time like several seconds. This way once the client dies no new calls arrive from it and after some time the call in progress end naturally and then after a timeout COM releases the objects in the server and the server can stop naturally.

查看更多
Melony?
3楼-- · 2019-05-28 21:45

COM periodically pings clients to see if they are still alive and runs down interfaces from dead clients. So your server will find out eventually.

查看更多
女痞
4楼-- · 2019-05-28 21:50

That's a vulnerability that exists whenever you have two or processes interop with each other. One of them dies and the other one keeps running, unaware that there will never be another request again from the dead process. In the case of an out-of-process COM server, nobody is going to call IUnknown::Release() to get the object destroyed. COM does not otherwise have a built-in fix for that problem. An in-process server doesn't have this problem, the crashed process takes the server out as well. Which is a problem too, no nice cleanup, but easier to deal with.

Getting the server to recover from this is something you'll have to add yourself. You could, say, have the client pass its process ID so that the server can obtain the process handle and detect when the client falls over with WaitForMultipleHandles(). Assuming they both live on the machine, that's certainly not a COM requirement and not something the server can find out.

查看更多
登录 后发表回答