The problem is that timeout should not reference the object anymore.
You mean the call variable? Yes, you have to zero it yourself; remove_call_out doesn't do that for you.
As you've noticed, the result from call_out is an array containing the function. When you put it in a variable in the same object, you'll get a classic reference cycle from the object via the array to itself. Thus, when the object runs out of external references it will still be around for a while, but it's not really a leak since the gc will get it eventually.
If you can't rely on the gc then you have to make sure that you break up all reference cycles, just like when you assign zero to the call variable. A robust way to do that is to destruct the object explicitly (but that can bring its own problems if there are multiple threads that access it etc). Roxen destructs the RequestID objects explicitly for this reason.
/ Martin Stjernholm, Roxen IS
Previous text:
2003-06-04 13:08: Subject: Re: Debugging memory problems
On Tue, 3 Jun 2003, David Gourdelier wrote:
. Is it possible to know which things reference which variables ?
There's one tool: If you compile with rtl-debug, there's a function _locate_references that walks through all things and prints the ones that reference the argument (in debug style). It's really useful, especially in 7.4 and later where it has been improved to report on the more odd sorts of references.
Ok I will try that.
After some debugging it looks like there is a problem with call_out. For example taking this code:
class C { mixed call;
void timeout() { }
void create() { call = call_out(timeout, 1); }
void close() { write("call=%O\n", call); remove_call_out(timeout); write("call=%O\n", call); } };
int main() { object o = C(); o->close(); write("call_out_info=%O\n", call_out_info()); write("refs=%d\n", _refs(o)); _locate_references(o); return -1; }
I get the following results:
call=({ /* 1 element */ memory()->C()->timeout }) call=({ /* 1 element */ memory()->C()->timeout }) call_out_info=({ }) refs=3 **Looking for references to 0x83a1ea0: ***One ref found in an array. -> from array 0x83a98c0 offset 28 **Location: 0x83a98c0 Type: array Refs: 1 **Describing array: Location=0x83a98c0 Refs=1, next=0x83f4100, prev=0x822d1e0, flags=0x0, size=1, malloced_size=1 Type field = array mapping multiset object function program string type int float <10> <11> <12> <13> <14> ({ timeout })
----------end------------ ***One ref found on current interpreter stack. -> at location 0x283370f8 ----------end------------ **Done looking for references to 0x83a1ea0.
The problem is that timeout should not reference the object anymore.
However it works if I set call = 0 in close() : call=({ /* 1 element */ memory()->C()->timeout }) call=0 call_out_info=({ }) refs=2 **Looking for references to 0x83a1ea0: ***One ref found on current interpreter stack. -> at location 0x283370f8 ----------end------------ **Done looking for references to 0x83a1ea0.
Any ideas ?
-- David Gourdelier
/ Brevbäraren