<!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: [Openib-windows] RE: Reference count as a solution to the problem of an object lif e time</TITLE>
</HEAD>
<BODY>
<P><FONT SIZE=2>Hi Fab, </FONT>
<BR><FONT SIZE=2>It seems that I still don't get your model (sorry for that)</FONT>
<BR><FONT SIZE=2>Just a small question that might help me understand it. Why do you call your model a reference counting model. If I understand correctly you only take the reference once, and when you get the callback you remove it.</FONT></P>
<P><FONT SIZE=2>Is their any chance that the reference will ever reach 5 for example? (or 10 or 20). It still seems to me as an exist don't exist one.</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: Fabian Tillier [<A HREF="mailto:ftillier@silverstorm.com">mailto:ftillier@silverstorm.com</A>]</FONT>
<BR><FONT SIZE=2>>Sent: Wednesday, September 21, 2005 9:11 PM</FONT>
<BR><FONT SIZE=2>>To: Tzachi Dar</FONT>
<BR><FONT SIZE=2>>Cc: openib-windows@openib.org</FONT>
<BR><FONT SIZE=2>>Subject: Re: [Openib-windows] RE: Reference count as a solution to the</FONT>
<BR><FONT SIZE=2>>problem of an object lif e time</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>On 9/21/05, Tzachi Dar <tzachid@mellanox.co.il> wrote:</FONT>
<BR><FONT SIZE=2>>></FONT>
<BR><FONT SIZE=2>>></FONT>
<BR><FONT SIZE=2>>> See also my answer to Sean.</FONT>
<BR><FONT SIZE=2>>></FONT>
<BR><FONT SIZE=2>>> One more thing to notice is that I see a difference between "destroying"</FONT>
<BR><FONT SIZE=2>>the</FONT>
<BR><FONT SIZE=2>>> object and freeing the memory that it is using.</FONT>
<BR><FONT SIZE=2>>></FONT>
<BR><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: Tuesday, September 20, 2005 12:51 AM</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: Monday, September 19, 2005 1:45 PM</FONT>
<BR><FONT SIZE=2>>> >></FONT>
<BR><FONT SIZE=2>>> >> Hi Fab,</FONT>
<BR><FONT SIZE=2>>> >></FONT>
<BR><FONT SIZE=2>>> >> Perhaps I'm wrong about this, but there is one difference between the</FONT>
<BR><FONT SIZE=2>>two</FONT>
<BR><FONT SIZE=2>>> >> models.</FONT>
<BR><FONT SIZE=2>>> >></FONT>
<BR><FONT SIZE=2>>> >> I believe that this difference is what forces one to wait for the</FONT>
<BR><FONT SIZE=2>>destroy</FONT>
<BR><FONT SIZE=2>>> >> completion. This difference is when the number of call backs is not</FONT>
<BR><FONT SIZE=2>>known</FONT>
<BR><FONT SIZE=2>>> >> to</FONT>
<BR><FONT SIZE=2>>> >> the user. In my approach the library can play with the reference count</FONT>
<BR><FONT SIZE=2>>> >> and</FONT>
<BR><FONT SIZE=2>>> >> make sure that it is increased even when there are more than one</FONT>
<BR><FONT SIZE=2>>> >> callback,</FONT>
<BR><FONT SIZE=2>>> >> while on your model (one removes the reference in the callback) one</FONT>
<BR><FONT SIZE=2>>can</FONT>
<BR><FONT SIZE=2>>> >> not</FONT>
<BR><FONT SIZE=2>>> >> know when to remove the reference.</FONT>
<BR><FONT SIZE=2>>> ></FONT>
<BR><FONT SIZE=2>>> >You do know when to remove the reference - in the destroy callback.</FONT>
<BR><FONT SIZE=2>>Once</FONT>
<BR><FONT SIZE=2>>> >the</FONT>
<BR><FONT SIZE=2>>> >deref call is invoked, no further callbacks will ever occur for that</FONT>
<BR><FONT SIZE=2>>> >object.</FONT>
<BR><FONT SIZE=2>>> ></FONT>
<BR><FONT SIZE=2>>> >It's a slight change in logic. Your model takes a reference when it</FONT>
<BR><FONT SIZE=2>>needs</FONT>
<BR><FONT SIZE=2>>> >to</FONT>
<BR><FONT SIZE=2>>> >invoke a callback, and releases it after the callback returns. The IBAL</FONT>
<BR><FONT SIZE=2>>> >object</FONT>
<BR><FONT SIZE=2>>> >model holds a reference for the lifetime of the object, and releases it</FONT>
<BR><FONT SIZE=2>>> >when</FONT>
<BR><FONT SIZE=2>>> >that object is destroyed. Obviously, this doesn't support sharing</FONT>
<BR><FONT SIZE=2>>objects</FONT>
<BR><FONT SIZE=2>>> >between multiple users well, but this hasn't been a problem yet.</FONT>
<BR><FONT SIZE=2>>> ></FONT>
<BR><FONT SIZE=2>>> >If you're sharing an object, waiting until that object is destroyed does</FONT>
<BR><FONT SIZE=2>>> >keep a</FONT>
<BR><FONT SIZE=2>>> >user's context around longer than might be necessary. But objects</FONT>
<BR><FONT SIZE=2>>aren't</FONT>
<BR><FONT SIZE=2>>> >shared</FONT>
<BR><FONT SIZE=2>>> >in any of the public APIs, so this isn't a problem as far as I know.</FONT>
<BR><FONT SIZE=2>>></FONT>
<BR><FONT SIZE=2>>> This is probably not a problem now, but I want to allow a more general</FONT>
<BR><FONT SIZE=2>>model</FONT>
<BR><FONT SIZE=2>>> in which our internal and external API's are consistent and can be used</FONT>
<BR><FONT SIZE=2>>> better.</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>I don't see the value in this, as IB resources are not designed to be</FONT>
<BR><FONT SIZE=2>>shared, and sharing them will require a lot more work to properly</FONT>
<BR><FONT SIZE=2>>synchronize things - what if a shared QP is driven into two states by</FONT>
<BR><FONT SIZE=2>>two different clients simulatenously?</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>As I've said before, your model forces a policy on the clients - the</FONT>
<BR><FONT SIZE=2>>API forces users to implement reference counting and use a destroy</FONT>
<BR><FONT SIZE=2>>method in which the last deref cleans the object up. This may or may</FONT>
<BR><FONT SIZE=2>>not fit into their model. The current model allows a client to use</FONT>
<BR><FONT SIZE=2>>reference counting to control the lifetime of an object, but does not</FONT>
<BR><FONT SIZE=2>>force an API on the client for how to do so.</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>Beyond the thoretical, I don't see any client needing this. Until</FONT>
<BR><FONT SIZE=2>>then, I would delay any implementation changes to do this as it will</FONT>
<BR><FONT SIZE=2>>just slow other more important things down.</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>> Please note that we had a problem in which objects were destroyed</FONT>
<BR><FONT SIZE=2>>> while they were busy. In my approach there is no problem in destroying an</FONT>
<BR><FONT SIZE=2>>> object while it is busy.</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>Was this problem in the access layer? In either case, it sounds like</FONT>
<BR><FONT SIZE=2>>a bug to me and needs to be fixed. I don't think fixing the bug</FONT>
<BR><FONT SIZE=2>>requires changing the object model - the buggy implementation is</FONT>
<BR><FONT SIZE=2>>clearly not using the destroy callback properly.</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>> >> A good example for this is the CM API's. If</FONT>
<BR><FONT SIZE=2>>> >> I understand correctly, one call CM_REQ and doesn't know how many call</FONT>
<BR><FONT SIZE=2>>> >> backs</FONT>
<BR><FONT SIZE=2>>> >> there will be. For example I have received a REP, and if I was too</FONT>
<BR><FONT SIZE=2>>busy</FONT>
<BR><FONT SIZE=2>>> >> to</FONT>
<BR><FONT SIZE=2>>> >> answer I have received a DREQ. As I understood it, the only way to</FONT>
<BR><FONT SIZE=2>>know</FONT>
<BR><FONT SIZE=2>>> >> that</FONT>
<BR><FONT SIZE=2>>> >> the last callback was sent is to wait for the completion of the</FONT>
<BR><FONT SIZE=2>>destroy</FONT>
<BR><FONT SIZE=2>>> >> of the</FONT>
<BR><FONT SIZE=2>>> >> QP.</FONT>
<BR><FONT SIZE=2>>> ></FONT>
<BR><FONT SIZE=2>>> >The current CM design invokes the CM callbacks on a QP, and you can't</FONT>
<BR><FONT SIZE=2>>> >destroy</FONT>
<BR><FONT SIZE=2>>> >the QP until all its associated callbacks have been either delivered or</FONT>
<BR><FONT SIZE=2>>> >cancelled. I don't see how your model would change that. The user's QP</FONT>
<BR><FONT SIZE=2>>> >context</FONT>
<BR><FONT SIZE=2>>> >can't be freed until the access layer notifies the user that it is safe</FONT>
<BR><FONT SIZE=2>>to</FONT>
<BR><FONT SIZE=2>>> >do</FONT>
<BR><FONT SIZE=2>>> >so. I don't see how your model helps this.</FONT>
<BR><FONT SIZE=2>>></FONT>
<BR><FONT SIZE=2>>> In my model, the QP can be destroyed whenever you want. If there are CM</FONT>
<BR><FONT SIZE=2>>> callbacks, than the QP is destroyed, but memory isn't freed. Once the CM</FONT>
<BR><FONT SIZE=2>>has</FONT>
<BR><FONT SIZE=2>>> finished doing his callbacks, (either doing them or not) he will release</FONT>
<BR><FONT SIZE=2>>the</FONT>
<BR><FONT SIZE=2>>> (last) reference and the memory will be freed. This is why I belive that</FONT>
<BR><FONT SIZE=2>>> this method is so good.</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>What if your CM callbacks try to perform state changes on the QP? Now</FONT>
<BR><FONT SIZE=2>>you need to add logic in the CM callbacks to make sure that you</FONT>
<BR><FONT SIZE=2>>haven't destroyed the QP already. Further, you need to add logic in</FONT>
<BR><FONT SIZE=2>>the access layer to check that you're not trying to use a destroyed</FONT>
<BR><FONT SIZE=2>>object, since the client's check in their CM callback could race with</FONT>
<BR><FONT SIZE=2>>the destruction.</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>What is the harm in keeping the QP around until all callbacks have</FONT>
<BR><FONT SIZE=2>>completed? I don't see the value in destroying the QP sooner - what</FONT>
<BR><FONT SIZE=2>>are you accomplishing with this, aside from complicating the logic at</FONT>
<BR><FONT SIZE=2>>all levels in the stack?</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>> >I believe that in the current code, all pending (not in flight) events</FONT>
<BR><FONT SIZE=2>>are</FONT>
<BR><FONT SIZE=2>>> >flushed as soon as you initiate destruction of the QP. If you initiate</FONT>
<BR><FONT SIZE=2>>QP</FONT>
<BR><FONT SIZE=2>>> >destruction from the REP callback, the REJ gets flushed, and when the</FONT>
<BR><FONT SIZE=2>>REP</FONT>
<BR><FONT SIZE=2>>> >callback unwinds, reference counts get released and the queue pair's</FONT>
<BR><FONT SIZE=2>>> >reference</FONT>
<BR><FONT SIZE=2>>> >count goes to zero and your destroy callback gets invoked.</FONT>
<BR><FONT SIZE=2>>> ></FONT>
<BR><FONT SIZE=2>>> Please note that when I start the destroy of the QP I don't know it's</FONT>
<BR><FONT SIZE=2>>state.</FONT>
<BR><FONT SIZE=2>>> (It's state might be changing a micro second ago) so I don't know what</FONT>
<BR><FONT SIZE=2>>> callbacks should happen. As a result I have to wait and it complicates</FONT>
<BR><FONT SIZE=2>>the</FONT>
<BR><FONT SIZE=2>>> code.</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>You should have a reference on your context because the QP exists.</FONT>
<BR><FONT SIZE=2>>When that QP is destroyed, the reference will be released. This is</FONT>
<BR><FONT SIZE=2>>independent of what callbacks are pending, the QP state, etc. If the</FONT>
<BR><FONT SIZE=2>>CM was in the process of invoking a callback, you would have to wait</FONT>
<BR><FONT SIZE=2>>in your object model too. Your solution doesn't avoid the need to</FONT>
<BR><FONT SIZE=2>>wait.</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>> >> A similar example is a timer object that works automatically, that is</FONT>
<BR><FONT SIZE=2>>you</FONT>
<BR><FONT SIZE=2>>> >> set</FONT>
<BR><FONT SIZE=2>>> >> it once and every second, you get a call back. A new callback, is</FONT>
<BR><FONT SIZE=2>>started</FONT>
<BR><FONT SIZE=2>>> >> even</FONT>
<BR><FONT SIZE=2>>> >> if the previous wasn't. In this model, when I want to stop things, I</FONT>
<BR><FONT SIZE=2>>just</FONT>
<BR><FONT SIZE=2>>> >> can't know when the last call back will happen. The only way to solve</FONT>
<BR><FONT SIZE=2>>> >> this is</FONT>
<BR><FONT SIZE=2>>> >> to call stop on timer, wait (event, callback or whatever) for the</FONT>
<BR><FONT SIZE=2>>timer</FONT>
<BR><FONT SIZE=2>>> >> to</FONT>
<BR><FONT SIZE=2>>> >> stop and than remove my reference (I want to make this clear there</FONT>
<BR><FONT SIZE=2>>might</FONT>
<BR><FONT SIZE=2>>> >> still</FONT>
<BR><FONT SIZE=2>>> >> be others using this object!!!).</FONT>
<BR><FONT SIZE=2>>> ></FONT>
<BR><FONT SIZE=2>>> >So you want to have a timer that can invoke multiple user's callbacks?</FONT>
<BR><FONT SIZE=2>>> >This</FONT>
<BR><FONT SIZE=2>>> >introduces a new object model - currently, there is only one recipient</FONT>
<BR><FONT SIZE=2>>of</FONT>
<BR><FONT SIZE=2>>> >callbacks. For a multi-client object, having the ability to take</FONT>
<BR><FONT SIZE=2>>> >references</FONT>
<BR><FONT SIZE=2>>> >would help let clients deregister without having to wait until all</FONT>
<BR><FONT SIZE=2>>clients</FONT>
<BR><FONT SIZE=2>>> >have</FONT>
<BR><FONT SIZE=2>>> >deregistered. Shutdown/destroy/whatever wouldn't really destroy the</FONT>
<BR><FONT SIZE=2>>timer,</FONT>
<BR><FONT SIZE=2>>> >it</FONT>
<BR><FONT SIZE=2>>> >would just deregister the callback, and when there are no references</FONT>
<BR><FONT SIZE=2>>left,</FONT>
<BR><FONT SIZE=2>>> >would</FONT>
<BR><FONT SIZE=2>>> >implicitly destroy the timer. This isn't a timer object anymore, as it</FONT>
<BR><FONT SIZE=2>>> >introduces the notion of event dispatching to allow multiplexing to</FONT>
<BR><FONT SIZE=2>>> >multiple</FONT>
<BR><FONT SIZE=2>>> >clients. For this, I agree that allowing the dispatcher to take</FONT>
<BR><FONT SIZE=2>>references</FONT>
<BR><FONT SIZE=2>>> >on</FONT>
<BR><FONT SIZE=2>>> >each client can be helpful.</FONT>
<BR><FONT SIZE=2>>> ></FONT>
<BR><FONT SIZE=2>>> >This is only an issue for multi-client objects - single user objects</FONT>
<BR><FONT SIZE=2>>don't</FONT>
<BR><FONT SIZE=2>>> >need</FONT>
<BR><FONT SIZE=2>>> >the ability to take extra references. I don't see any need for multi-</FONT>
<BR><FONT SIZE=2>>> >client</FONT>
<BR><FONT SIZE=2>>> >objects being exposed in the API - maybe if you could explain what</FONT>
<BR><FONT SIZE=2>>you're</FONT>
<BR><FONT SIZE=2>>> >trying</FONT>
<BR><FONT SIZE=2>>> >to do it might make more sense to me.</FONT>
<BR><FONT SIZE=2>>></FONT>
<BR><FONT SIZE=2>>> The problem is not multi-client objects but rather one object that has</FONT>
<BR><FONT SIZE=2>>more</FONT>
<BR><FONT SIZE=2>>> than one call back. If you look at the CM state diagram page 687 in the</FONT>
<BR><FONT SIZE=2>>IB</FONT>
<BR><FONT SIZE=2>>> spec you will see that the numbers of callback possible at any state is</FONT>
<BR><FONT SIZE=2>>> large. As a result I don't know when I have received the last one and I</FONT>
<BR><FONT SIZE=2>>have</FONT>
<BR><FONT SIZE=2>>> to wait. (see also bellow)</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>You have to wait as long as your object has a reference on it. This</FONT>
<BR><FONT SIZE=2>>is true of any reference counting model. It is only safe to release</FONT>
<BR><FONT SIZE=2>>the reference in the destroy callback, no matter what CM callbacks are</FONT>
<BR><FONT SIZE=2>>pending.</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>Also, while the number of events that can be generated from any state</FONT>
<BR><FONT SIZE=2>>in the CM state diagram is large, multiple events cannot be generated</FONT>
<BR><FONT SIZE=2>>from any state - events are associated with a state change. Further</FONT>
<BR><FONT SIZE=2>>events could happen from the new state, and a new event notification</FONT>
<BR><FONT SIZE=2>>be queued, but there's nothing that would prevent that - it's just a</FONT>
<BR><FONT SIZE=2>>fact of the state machine.</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>> >> On the model that I propose, the timer will increase the reference</FONT>
<BR><FONT SIZE=2>>count</FONT>
<BR><FONT SIZE=2>>> >> before each callback and will decrease the reference after the</FONT>
<BR><FONT SIZE=2>>callback.</FONT>
<BR><FONT SIZE=2>>> >> As a result, after I call stop on the timer, I can safely remove me</FONT>
<BR><FONT SIZE=2>>> >reference,</FONT>
<BR><FONT SIZE=2>>> >> and I DON'T HAVE TO WAIT.</FONT>
<BR><FONT SIZE=2>>> ></FONT>
<BR><FONT SIZE=2>>> >When you say you don't have to wait, do you mean wait in the</FONT>
<BR><FONT SIZE=2>>> >WaitForSingleObject</FONT>
<BR><FONT SIZE=2>>> >sense, or do you wait for the reference count to reach zero (i.e. your</FONT>
<BR><FONT SIZE=2>>> >object</FONT>
<BR><FONT SIZE=2>>> >can immediately be freed)? I think at a minimum, you must wait for the</FONT>
<BR><FONT SIZE=2>>> >reference count to reach zero, whether through a call to</FONT>
<BR><FONT SIZE=2>>> >WaitForSingleObject or</FONT>
<BR><FONT SIZE=2>>> >letting the dereference handler work asynchronously. If you are going</FONT>
<BR><FONT SIZE=2>>to</FONT>
<BR><FONT SIZE=2>>> >wait</FONT>
<BR><FONT SIZE=2>>> >for the reference count to reach zero, this isn't any different than</FONT>
<BR><FONT SIZE=2>>> >waiting for</FONT>
<BR><FONT SIZE=2>>> >the destroy callback.</FONT>
<BR><FONT SIZE=2>>></FONT>
<BR><FONT SIZE=2>>> I mean wait in both meaning. In my model I don't have to wait for</FONT>
<BR><FONT SIZE=2>>anything -</FONT>
<BR><FONT SIZE=2>>> the object will destroy itself once it's reference has reached zero.</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>No, in your model you have to wait for the reference count to reach</FONT>
<BR><FONT SIZE=2>>zero. In the existing model you have to wait for the reference count</FONT>
<BR><FONT SIZE=2>>to reach zero. In the existing model, you decrement your reference</FONT>
<BR><FONT SIZE=2>>count from the destroy callback. There is no more or less waiting</FONT>
<BR><FONT SIZE=2>>required than in your model than the existing one.</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>THE DESTROY CALLBACK IS EQUIVALENT TO A DEREF CALLBACK!!!</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>> >> Is there someway to solve this problem in your model?</FONT>
<BR><FONT SIZE=2>>> ></FONT>
<BR><FONT SIZE=2>>> >I don't see what the problem is. Can you be more specific about what it</FONT>
<BR><FONT SIZE=2>>is</FONT>
<BR><FONT SIZE=2>>> >you</FONT>
<BR><FONT SIZE=2>>> >want to change in the code - like APIs etc? Your object model can work</FONT>
<BR><FONT SIZE=2>>> >fine, I</FONT>
<BR><FONT SIZE=2>>> >just don't see why we should change the model throughout the API when</FONT>
<BR><FONT SIZE=2>>there</FONT>
<BR><FONT SIZE=2>>> >are</FONT>
<BR><FONT SIZE=2>>> >more important problems to solve.</FONT>
<BR><FONT SIZE=2>>></FONT>
<BR><FONT SIZE=2>>> As was descried above and in my answer to Sean Hefty my model makes life</FONT>
<BR><FONT SIZE=2>>> simpler (especially I don't like the fact that I have to wait on a QP</FONT>
<BR><FONT SIZE=2>>> destroy (more than this the problem is probably that I don't know what to</FONT>
<BR><FONT SIZE=2>>> wait for, If I new exactly how many call backs there will be it would be</FONT>
<BR><FONT SIZE=2>>> probably fine)).</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>You don't care how many callbacks it will be - the only callback from</FONT>
<BR><FONT SIZE=2>>which it is safe to release your reference is the destroy callback.</FONT>
<BR><FONT SIZE=2>>Period, end of story. Anything else is a bug.</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>As to destruction being async, this is a requirement to allow clients</FONT>
<BR><FONT SIZE=2>>to initiate destruction from DISPATCH. This will not go away, just</FONT>
<BR><FONT SIZE=2>>the opposite.</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>> I believe that if we are doing a revolution in our API (and our</FONT>
<BR><FONT SIZE=2>>> implementation) than we should consider doing this change as well.</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>I think it's clear that I've considered the suggestion from the length</FONT>
<BR><FONT SIZE=2>>of this exchange. I still don't see the value in changing the APIs to</FONT>
<BR><FONT SIZE=2>>do this, and I think your desire to do so comes from a</FONT>
<BR><FONT SIZE=2>>misunderstanding of how to use the current API to achieve exactly the</FONT>
<BR><FONT SIZE=2>>same results as what you are looking for.</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>The current object model is pretty simple - take a reference on your</FONT>
<BR><FONT SIZE=2>>context when you create a QP, and release that reference from the QP's</FONT>
<BR><FONT SIZE=2>>destroy callback. It's irrelevant how many CM callbacks are invoked</FONT>
<BR><FONT SIZE=2>>in between these two events, a reference on your context should exist</FONT>
<BR><FONT SIZE=2>>as long as the QP is alive. If you do this, taking an extra reference</FONT>
<BR><FONT SIZE=2>>for each CM callback accomplishes nothing.</FONT>
<BR><FONT SIZE=2>></FONT>
<BR><FONT SIZE=2>>- Fab</FONT>
</P>
</BODY>
</HTML>