<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=US-ASCII">
<META NAME="Generator" CONTENT="MS Exchange Server version 5.5.2654.45">
<TITLE>RE: Reference count as a solution to the problem of an object life time</TITLE>
</HEAD>
<BODY>

<P><FONT SIZE=2>Hi Fab,</FONT>
</P>

<P><FONT SIZE=2>Perhaps I'm wrong about this, but there is one difference between the two models. </FONT>
<BR><FONT SIZE=2>I believe that this difference is what forces one to wait for the destroy completion. This difference is when the number of call backs is not known to the user. In my approach the library can play with the reference count and make sure that it is increased even when there are more than one callback, while on your model (one removes the reference in the callback) one can not know when to remove the reference. A good example for this is the CM API's. If I understand correctly, one call CM_REQ and doesn't know how many call backs there will be. For example I have received a REP, and if I was too busy to answer I have received a DREQ. As I understood it, the only way to know that the last callback was sent is to wait for the completion of the destroy of the QP.</FONT></P>

<P><FONT SIZE=2>A similar example is a timer object that works automatically, that is you set it once and every second, you get a call back. A new callback, is started even if the previous wasn't. In this model, when I want to stop things, I just can't know when the last call back will happen. The only way to solve this is to call stop on timer, wait (event, callback or whatever) for the timer to stop and than remove my reference (I want to make this clear there might still be others using this object!!!). </FONT></P>

<P><FONT SIZE=2>On the model that I propose, the timer will increase the reference count before each callback and will decrease the reference after the callback.</FONT></P>

<P><FONT SIZE=2>As a result, after I call stop on the timer, I can safely remove me reference, and I DON'T HAVE TO WAIT. </FONT>
</P>

<P><FONT SIZE=2>Is there someway to solve this problem in your model?</FONT>
</P>

<P><FONT SIZE=2>Thanks</FONT>
<BR><FONT SIZE=2>Tzachi</FONT>
</P>

<P><FONT SIZE=2>>-----Original Message-----</FONT>
<BR><FONT SIZE=2>>From: Fab Tillier [<A HREF="mailto:ftillier@silverstorm.com">mailto:ftillier@silverstorm.com</A>]</FONT>
<BR><FONT SIZE=2>>Sent: Monday, September 19, 2005 7:35 AM</FONT>
<BR><FONT SIZE=2>>To: 'Tzachi Dar'; openib-windows@openib.org</FONT>
<BR><FONT SIZE=2>>Subject: RE: Reference count as a solution to the problem of an object life</FONT>
<BR><FONT SIZE=2>>time</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>> From: Tzachi Dar [<A HREF="mailto:tzachid@mellanox.co.il">mailto:tzachid@mellanox.co.il</A>]</FONT>
<BR><FONT SIZE=2>>> Sent: Sunday, September 18, 2005 12:38 PM</FONT>
<BR><FONT SIZE=2>>></FONT>
<BR><FONT SIZE=2>>> Hi Fab,</FONT>
<BR><FONT SIZE=2>>></FONT>
<BR><FONT SIZE=2>>> It seems that the only place in which I'm missing you is why there is a</FONT>
<BR><FONT SIZE=2>>need</FONT>
<BR><FONT SIZE=2>>> for a "destroy complete" call-back. According to the method that I</FONT>
<BR><FONT SIZE=2>>mention,</FONT>
<BR><FONT SIZE=2>>> there is no need for that I just call destroy and forget about the</FONT>
<BR><FONT SIZE=2>>object. I</FONT>
<BR><FONT SIZE=2>>> haven't yet figured why the destroy call back is needed on your approach.</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>In your model, you define a standard interface for taking and releasing</FONT>
<BR><FONT SIZE=2>>references on objects.  When creating an object that invokes callbacks (B</FONT>
<BR><FONT SIZE=2>>in</FONT>
<BR><FONT SIZE=2>>this example), the client passes in such an interface representing its</FONT>
<BR><FONT SIZE=2>>context</FONT>
<BR><FONT SIZE=2>>object (A in this example).  B is returned with a reference held on behalf</FONT>
<BR><FONT SIZE=2>>of</FONT>
<BR><FONT SIZE=2>>the caller.  Before being returned, B takes a reference on A and holds it</FONT>
<BR><FONT SIZE=2>>as</FONT>
<BR><FONT SIZE=2>>long as it can have callbacks outstanding.  Once A destroys B, A can't go</FONT>
<BR><FONT SIZE=2>>away</FONT>
<BR><FONT SIZE=2>>until B releases the reference on it, which it can only do once all</FONT>
<BR><FONT SIZE=2>>callbacks</FONT>
<BR><FONT SIZE=2>>are delivered.  In this case, you don't need to specify a destroy callback</FONT>
<BR><FONT SIZE=2>>at</FONT>
<BR><FONT SIZE=2>>destruction time since the dereference handler for A is equivalent.  You've</FONT>
<BR><FONT SIZE=2>>just</FONT>
<BR><FONT SIZE=2>>specified the equivalent of the destroy callback at creation time.</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>In the current model, B doesn't take an interface to A, it takes an opaque</FONT>
<BR><FONT SIZE=2>>pointer as context, but has no knowledge of how to do anything with that</FONT>
<BR><FONT SIZE=2>>context.  When A decides to destroy B, it provides a destroy callback so</FONT>
<BR><FONT SIZE=2>>that B</FONT>
<BR><FONT SIZE=2>>can properly synchronize callback delivery with destruction.  What A does</FONT>
<BR><FONT SIZE=2>>in the</FONT>
<BR><FONT SIZE=2>>destroy callback is irrelevant to B - it just needs to do whatever is</FONT>
<BR><FONT SIZE=2>>appropriate.  When B is done being destroyed, it invokes A's destroy</FONT>
<BR><FONT SIZE=2>>callback.</FONT>
<BR><FONT SIZE=2>>At creation time, A would take a reference on itself on behalf of B - this</FONT>
<BR><FONT SIZE=2>>eliminates the need to provide a call to take a reference on A internally</FONT>
<BR><FONT SIZE=2>>to B.</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>The destroy callback serves as a final notification, from which the user</FONT>
<BR><FONT SIZE=2>>typically releases a reference on its internal context and performs any</FONT>
<BR><FONT SIZE=2>>necessary cleanup.  Think of the destroy callback as a deref for the</FONT>
<BR><FONT SIZE=2>>context</FONT>
<BR><FONT SIZE=2>>provided when the object was created.</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>There's a reason the destroy callback and deref_al_obj have similar</FONT>
<BR><FONT SIZE=2>>prototypes -</FONT>
<BR><FONT SIZE=2>>it is to allow a user to use an al_obj_t pointer as their context, and use</FONT>
<BR><FONT SIZE=2>>deref_al_obj as their destroy callback.  This is very similar to your</FONT>
<BR><FONT SIZE=2>>proposed</FONT>
<BR><FONT SIZE=2>>model, except that in the IBAL model the deref() handler is provided when</FONT>
<BR><FONT SIZE=2>>the</FONT>
<BR><FONT SIZE=2>>object is being destroyed rather than when it is being created.</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>Does that make any more sense?</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>I don't know if it's necessary/valuable to have the addref() function</FONT>
<BR><FONT SIZE=2>>passed</FONT>
<BR><FONT SIZE=2>>into an object.  So I think the difference between the models comes down to</FONT>
<BR><FONT SIZE=2>>passing the deref handler at creation time or destruction time, which seems</FONT>
<BR><FONT SIZE=2>>like</FONT>
<BR><FONT SIZE=2>>a pretty minor difference.</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>Whether a user waits for the deref/destroy callback or not is</FONT>
<BR><FONT SIZE=2>>implementation</FONT>
<BR><FONT SIZE=2>>specific - neither of our methods forces any kind of synchronous or</FONT>
<BR><FONT SIZE=2>>asynchronous</FONT>
<BR><FONT SIZE=2>>policy on our clients.</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>I don't know if forcing an object model into the API makes sense - that is,</FONT>
<BR><FONT SIZE=2>>the</FONT>
<BR><FONT SIZE=2>>notion that all clients that expect callbacks must provide an interface to</FONT>
<BR><FONT SIZE=2>>their</FONT>
<BR><FONT SIZE=2>>context that we define, as well as forcing all objects created by various</FONT>
<BR><FONT SIZE=2>>parts</FONT>
<BR><FONT SIZE=2>>of the stack to expose the same general interface.  I would say I'm on the</FONT>
<BR><FONT SIZE=2>>fence</FONT>
<BR><FONT SIZE=2>>about this, leaning towards simplicity (the current model) over flexibility</FONT>
<BR><FONT SIZE=2>>(the</FONT>
<BR><FONT SIZE=2>>unified object model).</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>- Fab</FONT>
</P>

</BODY>
</HTML>