1. delete_routine() - malfunction or misunderstanding?

Perhaps I'm missing something on how delete_routine() is supposed to work.

manual said...

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

new topic     » topic index » view message » categorize

2. Re: delete_routine() - malfunction or misunderstanding?

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.

new topic     » goto parent     » topic index » view message » categorize

3. Re: delete_routine() - malfunction or misunderstanding?

ghaberek said...

Perhaps I'm missing something on how delete_routine() is supposed to work.

manual said...

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.

ghaberek said...

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

new topic     » goto parent     » topic index » view message » categorize

4. Re: delete_routine() - malfunction or misunderstanding?

mattlewis said...

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. blink

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

new topic     » goto parent     » topic index » view message » categorize

5. Re: delete_routine() - malfunction or misunderstanding?

ghaberek said...
mattlewis said...

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. blink

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

new topic     » goto parent     » topic index » view message » categorize

6. Re: delete_routine() - malfunction or misunderstanding?

mattlewis said...

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

new topic     » goto parent     » topic index » view message » categorize

7. Re: delete_routine() - malfunction or misunderstanding?

ghaberek said...
mattlewis said...

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

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu