1. delete_routine() - malfunction or misunderstanding?
- Posted by ghaberek (admin) Mar 12, 2013
- 1497 views
Perhaps I'm missing something on how delete_routine() is supposed to work.
The second way for the delete routine to be called is when its reference count is reduced to 0. Before its memory is freed, the delete routine is called. A default delete will be used if the cleanup parameter to one of the allocate routines is true.
I'm confused here: does this mean I can only associate a delete routine with a memory address? It would seem from the above mention of sequences and atoms, that it can be any object. I also found the gem below hidden away in std/machine.e (line 320), which doesn't seem to make it into the manual (see: Type Sorted Function List) because of the extra - on the first line.
---**** -- ==== Using non-Memory Objects -- -- Use call the ##new## routine belonging to the module and you normally don't need to -- free it. You may use [[:delete]] to call its destructors explicitly. It will be freeed -- automatically when the variable becomes unused. For creating new objects -- you can associate a destructor with [[:delete_routine]]. --
And so, after reading all this, I have the code below. It does not work as I would expect. My delete_obj() routine is being called immediately when I call delete_routine(), and I would expect it to be called later when the object's reference count is reduced to 0 and/or when the application exits and performs its cleanup.
-- test.e namespace test include "std/map.e" include "std/pretty.e" integer delete_rid = routine_id( "delete_obj" ) map objects = map:new() public function new() -- generate some random value atom obj = rand( 10000 ) * rand( 10000 ) printf( 1, "new(), obj = #%08x\n", {obj} ) map:put( objects, obj, "" ) dump() delete_routine( obj, delete_rid ) return obj end function procedure delete_obj( atom obj ) printf( 1, "delete_obj( obj=#%08x )\n", {obj} ) if map:has( objects, obj ) then map:remove( objects, obj ) puts( 1, "object removed!\n" ) end if end procedure public procedure action( atom obj ) printf( 1, "action( obj=#%08x )\n", {obj} ) dump() if map:has( objects, obj ) then map:put( objects, obj, "action" ) else puts( 2, "object not found!\n" ) end if end procedure procedure dump() sequence pairs = map:pairs( objects ) puts( 1, "pairs = " ) pretty_print( 1, pairs, {2} ) puts( 1, "\n" ) end procedure
-- example.ex include test.e atom obj = test:new() test:action( obj )
-Greg
2. Re: delete_routine() - malfunction or misunderstanding?
- Posted by EUWX Mar 12, 2013
- 1414 views
Whether it is "malfunction or misunderstanding", memory leaks are the biggest problems with C and C plus plus. Tthe situation should be rectified and be made completely solid.
3. Re: delete_routine() - malfunction or misunderstanding?
- Posted by mattlewis (admin) Mar 12, 2013
- 1450 views
Perhaps I'm missing something on how delete_routine() is supposed to work.
The second way for the delete routine to be called is when its reference count is reduced to 0. Before its memory is freed, the delete routine is called. A default delete will be used if the cleanup parameter to one of the allocate routines is true.
I'm confused here: does this mean I can only associate a delete routine with a memory address? It would seem from the above mention of sequences and atoms, that it can be any object.
That's just some poor writing. It's attempting to point out that the allocate routines have an option to have the underlying memory be deleted when the value returned from the allocation routine's reference count drops to zero.
I also found the gem below hidden away in std/machine.e (line 320), which doesn't seem to make it into the manual (see: Type Sorted Function List) because of the extra - on the first line.
---**** -- ==== Using non-Memory Objects -- -- Use call the ##new## routine belonging to the module and you normally don't need to -- free it. You may use [[:delete]] to call its destructors explicitly. It will be freeed -- automatically when the variable becomes unused. For creating new objects -- you can associate a destructor with [[:delete_routine]]. --
And so, after reading all this, I have the code below. It does not work as I would expect. My delete_obj() routine is being called immediately when I call delete_routine(), and I would expect it to be called later when the object's reference count is reduced to 0 and/or when the application exits and performs its cleanup.
You are not assigning the value returned from delete_routine(). So what happens is that its reference count is immediately decremented. Your code should look like:
obj = delete_routine( obj, delete_rid ) -- or: return delete_routine( obj, delete_rid )
Matt
4. Re: delete_routine() - malfunction or misunderstanding?
- Posted by ghaberek (admin) Mar 12, 2013
- 1399 views
You are not assigning the value returned from delete_routine(). So what happens is that its reference count is immediately decremented. Your code should look like:
obj = delete_routine( obj, delete_rid ) -- or: return delete_routine( obj, delete_rid )
Ah-ha! I knew there was a simple trick I was missing. That detail, of all things, should probably be added to the documentation.
And so, while doing as you suggest corrects the first issue, my cleanup routine is not still being called when the program exits, only when I call delete() manually at the end. Any suggestions? Or am I expecting the wrong behavior?
-Greg
5. Re: delete_routine() - malfunction or misunderstanding?
- Posted by mattlewis (admin) Mar 12, 2013
- 1436 views
You are not assigning the value returned from delete_routine(). So what happens is that its reference count is immediately decremented. Your code should look like:
obj = delete_routine( obj, delete_rid ) -- or: return delete_routine( obj, delete_rid )
Ah-ha! I knew there was a simple trick I was missing. That detail, of all things, should probably be added to the documentation.
And so, while doing as you suggest corrects the first issue, my cleanup routine is not still being called when the program exits, only when I call delete() manually at the end. Any suggestions? Or am I expecting the wrong behavior?
Back when I was developing this, I was planning on having the normal cleanup go through and dereference everything and invoke those cleanup routines. This often broke things, as certain resources would be gone when cleanup routines would try to use them (especially things like maps stored in eumem).
So far, I haven't found a good way to make all of that work, so the routines won't be called at exit. Of course, allocated memory goes away. I suppose that's another documentation update that needs doing.
Matt
6. Re: delete_routine() - malfunction or misunderstanding?
- Posted by ghaberek (admin) Mar 12, 2013
- 1438 views
Back when I was developing this, I was planning on having the normal cleanup go through and dereference everything and invoke those cleanup routines. This often broke things, as certain resources would be gone when cleanup routines would try to use them (especially things like maps stored in eumem).
So far, I haven't found a good way to make all of that work, so the routines won't be called at exit. Of course, allocated memory goes away. I suppose that's another documentation update that needs doing.
That makes sense. Would it be possible instead to have a cleanup routine that only looks for objects that still exist and have a delete routine attached?
-Greg
7. Re: delete_routine() - malfunction or misunderstanding?
- Posted by mattlewis (admin) Mar 13, 2013
- 1346 views
Back when I was developing this, I was planning on having the normal cleanup go through and dereference everything and invoke those cleanup routines. This often broke things, as certain resources would be gone when cleanup routines would try to use them (especially things like maps stored in eumem).
So far, I haven't found a good way to make all of that work, so the routines won't be called at exit. Of course, allocated memory goes away. I suppose that's another documentation update that needs doing.
That makes sense. Would it be possible instead to have a cleanup routine that only looks for objects that still exist and have a delete routine attached?
You still run into problems with side effects of those delete routines. Perhaps if we had some sort of cleanup that you could run at the end. Obviously, we have a crash handler, but not something for when things go right.
Matt