Archived

This forum has been archived. Please start a new discussion on GitHub.

Release "callback class" in AMI

Hello, guys:
i am developing a service requiring AMI. However i'v got a problem. The following is a example slice definition.

module Demo
{
interface Server
{
["ami"] int Process(int iReqLen)
};
};

//The following is from the client side
try
{
char ProxyString[100];
sprintf(ProxyString, "Server:tcp -h %s -p %d", g_ServerIp, g_ServerPort);

Ice::ObjectPrx pBase = g_IcePtr->stringToProxy(ProxyString);
ServerPrx Transer = ServerPrx::checkedCast(pBase);
if (!Transer)
{...}

Transer->Process_async(new AMI_Server_ProcessI, iReqLen);//PROBLEM HERE
}
My problem is:
will this code lead to a memory leakage? the new AMI_Server_ProcessI is never destroyed? i see AMI_Server_ProcessI is derived from "class shared" which has a member "__ref". So i assume that when "new AMI_Server_ProcessI" is called the __ref will be increased.
i tried to call "_decRef()" in the AMI_KMCServer_ProcessI::ice_response(), however i got a fatal error in run-time.
if i use the following codes:
AMI_KMCServer_ProcessPtr p = new AMI_KMCServer_ProcessI;
Transer->Process_async(p, iReqLen);
when p's life ends, it will release the "AMI_KMCServer_ProcessI", right? because p is an auto variable, this will lead to problems that "AMI_KMCServer_ProcessI" is released before "ice_response" get called. how can i fix this?
thank u.

Comments

  • matthew
    matthew NL, Canada
    The code samples as presented above will not leak. I recommend you read section 6.14.6 "Smart Pointers for Classes" in the Ice manual for a detailed explanation. If you have more questions after reviewing this please let me know!
  • Thank you, Matthew:
    After reading section 6.14.6 in the manual, and after a careful debug, i think i have figure out what is actually going on in the code.

    Transer->Process_async(new AMI_Server_ProcessI, iReqLen);

    first, after a AMI_Server_ProcessI instance is created and passed to function "Process_async", the constructor of IceUtil::Handle<AMI_Server_ProcessI> is called. And __incRef is called in this constructor.
    Second, which is the point i didnot think through earlier, is that function "Process_async" will also call __incRef. So when the stack variable IceUtil::Handle<AMI_Server_ProcessI> goes out od scope, __ref in AMI_Server_ProcessI is still not zero.
    Third, i assume that after ice_response() is called ice-runtime will also call __decRef(). This also explain why i get a fatal error when i add __defRef() explicitly in my ice_response().
    Am i right? I wish i have time to study the ice source thoroughly. Thank you very much.
  • matthew
    matthew NL, Canada
    Yes, your analysis is correct!