Forums | developer.brewmp.com Forums | developer.brewmp.com

Developer

Forums

In the circle actor example, the circle model release function does a release on an IVfsNode. It gets this node ultimately from its HandleNodeEvent() function.

Why should this node be released? I could see how maybe when your code is handed a node, the caller would do an addref on it, so we should release it when done. That's not documented, but if true this is a memory leak because presumably the caller would addref the node each time it calls our HandleNodeEvent(). Should the node be released for each call to HandleNodeEvent()?

Any thoughts appreciated, thanks.
Brad Dre

Well, it should really be the root actor node that's being released. In this case, the node that's sent to the handle event function is the root node.

Well, it should really be the root actor node that's being released. In this case, the node that's sent to the handle event function is the root node.

Here's the info more clearly presented in case you want to know what I'm talking about.
CirlceActorModel.cpp has this code in the CircleModel_Release() function:
if ( self->m_actorNode ) {
IVFSNODE_Release( self->m_actorNode );

m_actorNode gets set in CircleModel_Rotate(), which is called each time the actor's HandleNodeEvent() function gets an EVT_TRIGMLEVENT with the eventName == "rotate".
The "node" parameter of HandleNodeEvent() is which node? Is it necessarily the root node? I don't know -- I thought it was possible to throw an event from a child node from within a trig.
Regardless, if we're assuming that the caller has done an addref on that node, shouldn't it be released each time before returning from HandleNodeEvent()?
If this is the assumption, then the circle actor code is storing the "node" in m_actorNode to use for some reason. However, the only thing it uses it for is releasing is when the model is released.
Finally, with the assumptions I've made, isn't this a memory leak? Remember, our actor is called each time the user presses the 5 key over in the trig.
Max, thanks for your response. I'm not sure if it answered the (unclear) question. Object management seems very confusing in actors.
Brad Dre

Here's the info more clearly presented in case you want to know what I'm talking about.
CirlceActorModel.cpp has this code in the CircleModel_Release() function:
if ( self->m_actorNode ) {
IVFSNODE_Release( self->m_actorNode );

m_actorNode gets set in CircleModel_Rotate(), which is called each time the actor's HandleNodeEvent() function gets an EVT_TRIGMLEVENT with the eventName == "rotate".
The "node" parameter of HandleNodeEvent() is which node? Is it necessarily the root node? I don't know -- I thought it was possible to throw an event from a child node from within a trig.
Regardless, if we're assuming that the caller has done an addref on that node, shouldn't it be released each time before returning from HandleNodeEvent()?
If this is the assumption, then the circle actor code is storing the "node" in m_actorNode to use for some reason. However, the only thing it uses it for is releasing is when the model is released.
Finally, with the assumptions I've made, isn't this a memory leak? Remember, our actor is called each time the user presses the 5 key over in the trig.
Max, thanks for your response. I'm not sure if it answered the (unclear) question. Object management seems very confusing in actors.
Brad Dre

May be you can try running the same process multiple time and try exiting brew in simulator. (By pressing Change applet directory and press ok). Now check in simulator logs.
*AEEShell.c:1213 - #*gEX
*AEEShell.c:8942 - #*gCL=625445222
*OEMDebug.c:183 - DBGEvent=0x1 cls=0x25478966 pl=0x0
*OEMOS.c:578 - BPOINT Type 1, Node 0x026C13D0 mybrewapp
*AEEHeap.c:1265 - ------ App Heap Info ------
*AEEHeap.c:1167 - 20 - mybrewapp #3539 .\src\mybrewapp.c:150 (L)
*OEMOS.c:578 - BPOINT Type 1, Node 0x026C3C80 mybrewapp
*AEEHeap.c:1167 - 40 - mybrewapp #3551 .\src\testing.c:125 (L)
*OEMOS.c:578 - BPOINT Type 1, Node 0x026C4910 mybrewapp
*AEEHeap.c:1167 - 80 - mybrewapp #3558 .\src\testing.c:127 (L)
*OEMOS.c:578 - BPOINT Type 1, Node 0x026C4990 mybrewapp
*AEEHeap.c:1167 - 40 - mybrewapp #3560 .\src\testing.c:125 (L)
*OEMOS.c:578 - BPOINT Type 1, Node 0x026C49E8 mybrewapp
*AEEHeap.c:1167 - 80 - mybrewapp #3561 .\src\testing.c:127 (L)
*OEMOS.c:578 - BPOINT Type 1, Node 0x026C4A68 mybrewapp
*AEEHeap.c:1167 - 40 - mybrewapp #3563 .\src\testing.c:125 (L)
*OEMOS.c:578 - BPOINT Type 1, Node 0x026D6978 mybrewapp
*AEEHeap.c:1167 - 80 - mybrewapp #3564 .\src\testing.c:127 (L)
*OEMOS.c:578 - BPOINT Type 1, Node 0x02A92288 mybrewapp
*AEEHeap.c:1167 - 40 - mybrewapp #3557 .\src\testing.c:125 (L)
*OEMOS.c:578 - BPOINT Type 1, Node 0x02A922F0 mybrewapp
*AEEHeap.c:1167 - 80 - mybrewapp #3552 .\src\testing.c:127 (L)
*OEMOS.c:578 - BPOINT Type 1, Node 0x02A92370 mybrewapp
*AEEHeap.c:1167 - 40 - mybrewapp #3554 .\src\testing.c:125 (L)
*OEMOS.c:578 - BPOINT Type 1, Node 0x02A923C8 mybrewapp
*AEEHeap.c:1167 - 80 - mybrewapp #3555 .\src\testing.c:127 (L)
*AEEHeap.c:1279 - -------------------------
*AEEHeap.c:1280 - 201384 Alloc - Total
*AEEHeap.c:1281 - 0 OEM
*AEEHeap.c:1282 - 57851 BREW
*AEEHeap.c:1283 - 143533 Apps
*AEEHeap.c:1284 - 33064 Wasted
*AEEHeap.c:1285 - 3860928 Free - Total
*AEEHeap.c:1286 - 3853408 Largest
*AEEHeap.c:1287 - 3853408 Largest Non Seq.
*AEEHeap.c:1288 - 3860928 Total Non Seq.
*AEEHeap.c:1289 - -------------------------
*AEEShell.c:8942 - #*gCL=16855468
*OEMDebug.c:183 - DBGEvent=0x1 cls=0x10131AC pl=0x0
*AEEShell.c:8942 - #*gCL=16809984
If there is some memory leak, it will show up in this msg.

May be you can try running the same process multiple time and try exiting brew in simulator. (By pressing Change applet directory and press ok). Now check in simulator logs.
*AEEShell.c:1213 - #*gEX
*AEEShell.c:8942 - #*gCL=625445222
*OEMDebug.c:183 - DBGEvent=0x1 cls=0x25478966 pl=0x0
*OEMOS.c:578 - BPOINT Type 1, Node 0x026C13D0 mybrewapp
*AEEHeap.c:1265 - ------ App Heap Info ------
*AEEHeap.c:1167 - 20 - mybrewapp #3539 .\src\mybrewapp.c:150 (L)
*OEMOS.c:578 - BPOINT Type 1, Node 0x026C3C80 mybrewapp
*AEEHeap.c:1167 - 40 - mybrewapp #3551 .\src\testing.c:125 (L)
*OEMOS.c:578 - BPOINT Type 1, Node 0x026C4910 mybrewapp
*AEEHeap.c:1167 - 80 - mybrewapp #3558 .\src\testing.c:127 (L)
*OEMOS.c:578 - BPOINT Type 1, Node 0x026C4990 mybrewapp
*AEEHeap.c:1167 - 40 - mybrewapp #3560 .\src\testing.c:125 (L)
*OEMOS.c:578 - BPOINT Type 1, Node 0x026C49E8 mybrewapp
*AEEHeap.c:1167 - 80 - mybrewapp #3561 .\src\testing.c:127 (L)
*OEMOS.c:578 - BPOINT Type 1, Node 0x026C4A68 mybrewapp
*AEEHeap.c:1167 - 40 - mybrewapp #3563 .\src\testing.c:125 (L)
*OEMOS.c:578 - BPOINT Type 1, Node 0x026D6978 mybrewapp
*AEEHeap.c:1167 - 80 - mybrewapp #3564 .\src\testing.c:127 (L)
*OEMOS.c:578 - BPOINT Type 1, Node 0x02A92288 mybrewapp
*AEEHeap.c:1167 - 40 - mybrewapp #3557 .\src\testing.c:125 (L)
*OEMOS.c:578 - BPOINT Type 1, Node 0x02A922F0 mybrewapp
*AEEHeap.c:1167 - 80 - mybrewapp #3552 .\src\testing.c:127 (L)
*OEMOS.c:578 - BPOINT Type 1, Node 0x02A92370 mybrewapp
*AEEHeap.c:1167 - 40 - mybrewapp #3554 .\src\testing.c:125 (L)
*OEMOS.c:578 - BPOINT Type 1, Node 0x02A923C8 mybrewapp
*AEEHeap.c:1167 - 80 - mybrewapp #3555 .\src\testing.c:127 (L)
*AEEHeap.c:1279 - -------------------------
*AEEHeap.c:1280 - 201384 Alloc - Total
*AEEHeap.c:1281 - 0 OEM
*AEEHeap.c:1282 - 57851 BREW
*AEEHeap.c:1283 - 143533 Apps
*AEEHeap.c:1284 - 33064 Wasted
*AEEHeap.c:1285 - 3860928 Free - Total
*AEEHeap.c:1286 - 3853408 Largest
*AEEHeap.c:1287 - 3853408 Largest Non Seq.
*AEEHeap.c:1288 - 3860928 Total Non Seq.
*AEEHeap.c:1289 - -------------------------
*AEEShell.c:8942 - #*gCL=16855468
*OEMDebug.c:183 - DBGEvent=0x1 cls=0x10131AC pl=0x0
*AEEShell.c:8942 - #*gCL=16809984
If there is some memory leak, it will show up in this msg.

DrDre wrote:Here's the info more clearly presented in case you want to know what I'm talking about.
CirlceActorModel.cpp has this code in the CircleModel_Release() function:
if ( self->m_actorNode ) {
IVFSNODE_Release( self->m_actorNode );

m_actorNode gets set in CircleModel_Rotate(), which is called each time the actor's HandleNodeEvent() function gets an EVT_TRIGMLEVENT with the eventName == "rotate".
The "node" parameter of HandleNodeEvent() is which node? Is it necessarily the root node? I don't know -- I thought it was possible to throw an event from a child node from within a trig.
Regardless, if we're assuming that the caller has done an addref on that node, shouldn't it be released each time before returning from HandleNodeEvent()?
If this is the assumption, then the circle actor code is storing the "node" in m_actorNode to use for some reason. However, the only thing it uses it for is releasing is when the model is released.
Finally, with the assumptions I've made, isn't this a memory leak? Remember, our actor is called each time the user presses the 5 key over in the trig.
Max, thanks for your response. I'm not sure if it answered the (unclear) question. Object management seems very confusing in actors.
Brad Dre
You're absolutely right in the general case. In the case of the circle actor, it only accepts events thrown at the root node. So, the node pointer in the NodeEvent handler will always be the root node. That's why there isn't any mucking around with addRef in the code. I would consider it to be somewhat sloppy programming -- it's by no means robust enough for a complicated actor. If you look at the code in CircleModel_Rotate(), you can see there's a commented-out block that acknowledges this fact, and shows how you would need to get the root node if this were a more complex actor (something that supported events thrown at child nodes).

DrDre wrote:Here's the info more clearly presented in case you want to know what I'm talking about.
CirlceActorModel.cpp has this code in the CircleModel_Release() function:
if ( self->m_actorNode ) {
IVFSNODE_Release( self->m_actorNode );

m_actorNode gets set in CircleModel_Rotate(), which is called each time the actor's HandleNodeEvent() function gets an EVT_TRIGMLEVENT with the eventName == "rotate".
The "node" parameter of HandleNodeEvent() is which node? Is it necessarily the root node? I don't know -- I thought it was possible to throw an event from a child node from within a trig.
Regardless, if we're assuming that the caller has done an addref on that node, shouldn't it be released each time before returning from HandleNodeEvent()?
If this is the assumption, then the circle actor code is storing the "node" in m_actorNode to use for some reason. However, the only thing it uses it for is releasing is when the model is released.
Finally, with the assumptions I've made, isn't this a memory leak? Remember, our actor is called each time the user presses the 5 key over in the trig.
Max, thanks for your response. I'm not sure if it answered the (unclear) question. Object management seems very confusing in actors.
Brad Dre
You're absolutely right in the general case. In the case of the circle actor, it only accepts events thrown at the root node. So, the node pointer in the NodeEvent handler will always be the root node. That's why there isn't any mucking around with addRef in the code. I would consider it to be somewhat sloppy programming -- it's by no means robust enough for a complicated actor. If you look at the code in CircleModel_Rotate(), you can see there's a commented-out block that acknowledges this fact, and shows how you would need to get the root node if this were a more complex actor (something that supported events thrown at child nodes).