Results 1 to 8 of 8

Thread: IceInternal::Handle

  1. #1
    RyanFogarty is offline Registered User
    Join Date
    Aug 2003
    Location
    Newport, RI
    Posts
    23

    Question IceInternal::Handle

    I have a question about the IceInteral::Handle. First off should we be using it? For instance if I have created some interface IA and then derived from it and want to keep a pointer to the more derived object that has some internal interface, so:

    Code:
    class A : IA
    {
       // some more internal interface
    };
    
    typedef IceInternal::Handle<A> APtr;
    If this is considered valid. Why is Handle in the IceInternal namespace. Or should I be using the one in IceUtil and if so, are the two compatible?

    Lastly, one comment about Handle. Why are the constructors not "explicit" so that, for instance, the add(...) operation in the ObjectAdapter cannot implicitly take a pointer to an Ice::Object type without complaining (which I think could be dangerous, no...)?

    Regards,
    Ryan

  2. #2
    marc's Avatar
    marc is offline ZeroC Staff
    Name: Marc Laukien
    Organization: ZeroC, Inc.
    Project: The Internet Communications Engine
    Join Date
    Feb 2003
    Location
    Florida
    Posts
    1,860
    You should use IceUtil::Handle. It is compatible with IceInternal::Handle.

    The difference between these two is that the latter can be used even if the underlying type is only declared but not defined. However, to make this work, IceInternal::Handle requires additional code for each template instance, and is therefore better suited for generated code than for hand-written code.

    The constructor is not explicit because passing a pointer where a handle is expected is permissible. For example, you can call some_adapter.add(new SomeObjectI) without any problems.

  3. #3
    RyanFogarty is offline Registered User
    Join Date
    Aug 2003
    Location
    Newport, RI
    Posts
    23
    Great. Thanks Marc!

    On the bit about the Handle constructor. From a dummy users perspective we tracked down a bug today which was determined to be the adapter trying to double delete an object when being destroyed. Our confusion was caused primarily by us being stupid and trying to have the object add itself into its adapter in its constructor. Something like:

    Code:
     class A
    {
       A()
       {
          AdapterForA::instance()->add(this); // !!!
       }
    };
    I guess this is ok to do but then we also tried to keep a smart pointer reference of A around as well (which was obviously baaaaad since there is no way to link them I think?). So,

    Code:
        AHandle theA(new A);
    Anyway, our dummy-hood may have been a little less certain if we were forced to write class A like

    Code:
          AdapterForA::instance()->add(AHandle(this));
    And it really doesn't add that much effort I think?

    V/R,
    Ryan

  4. #4
    marc's Avatar
    marc is offline ZeroC Staff
    Name: Marc Laukien
    Organization: ZeroC, Inc.
    Project: The Internet Communications Engine
    Join Date
    Feb 2003
    Location
    Florida
    Posts
    1,860
    I'm not sure I understand. You can of course also keep a smart pointer instance. Do you have a complete example that demonstrates the problem? I can't see anything wrong in the code segments.

    AdapterForA::instance()->add(AHandle(this));

    Is equivalent to:

    AdapterForA::instance()->add(this);

    The only difference is that in the first case, you are creating a smart pointer explicitly, while in the second case the compiler creates a smart pointer as a temporary. But with respect to reference counts and memory management, both statements are equivalent.

  5. #5
    michi's Avatar
    michi is offline Registered User
    Name: Michi Henning
    Organization: Triodia Technologies
    Project: I have a passing interest in Ice :-)
    Join Date
    Feb 2003
    Location
    Brisbane, Australia
    Posts
    1,055
    I agree -- this should work because the reference count is kept in the object, not in the handle. If you can reproduce this in a small example, I'd be interested in having a look at it.

    Cheers,

    Michi.

  6. #6
    marc's Avatar
    marc is offline ZeroC Staff
    Name: Marc Laukien
    Organization: ZeroC, Inc.
    Project: The Internet Communications Engine
    Join Date
    Feb 2003
    Location
    Florida
    Posts
    1,860
    As an aside, if you have used CORBA and its _var types before, then this is most likely the source of confusion. The _var types do very weird things, namely to "assume ownership" if you assign a pointer of the underlying type. Ice handles don't do this, they behave like "normal" reference-counted smart pointers. No "ownership" is assigned when you assign a plain C++ pointer to an Ice smart pointer. Here is an example:

    The following is illegal in CORBA:

    T* p = ...;
    T_var hande1(p);
    T_var hande2(p);
    T_var hande3(p);

    That's because of this brain-dead concept in the CORBA C++ mapping of "assigning ownership". However, the following is perfectly legal in Ice:

    T* p = ...;
    TPtr hande1(p);
    TPtr hande2(p);
    TPtr hande3(p);

    I can only guess what the authors of the _var type were trying to achieve. Perhaps they started out with something similar to std::auto_ptr, and then added reference counting, ending up with a solution that is neither here nor there...

  7. #7
    RyanFogarty is offline Registered User
    Join Date
    Aug 2003
    Location
    Newport, RI
    Posts
    23

    Ah, reference count is in Object!!

    Hi guys,

    Ok. I see what you are doing. Every Object type holds the reference count. I assumed you were implementing something close to the boost/shared_ptr. Which reminds me. That was where our error was (I didn't accurately write up our error above). We had mistakenly done something like this:

    Code:
    class A
    {
       A() : IA
       {
          AdapterForA::instance()->add(A); 
       }
    }
    
    // In code later on:
    
    typedef boost::shared_ptr<A> APtr;
    APtr theA(new A);
    I think early on. before we discovered the IceUtil::Handle, we had assumed that we were not supposed to be typedef-ing our own IceInternal::Handle types so that's when I decided to use the boost shared_ptr (not realizing under the covers another smart pointer type was being used). Hindsight is 20-20 of course. Definitely looks like a Nubian error now!

    Thanks for your help,
    Ryan
    Last edited by RyanFogarty; 12-17-2004 at 11:05 AM.

  8. #8
    michi's Avatar
    michi is offline Registered User
    Name: Michi Henning
    Organization: Triodia Technologies
    Project: I have a passing interest in Ice :-)
    Join Date
    Feb 2003
    Location
    Brisbane, Australia
    Posts
    1,055
    Originally posted by marc
    I can only guess what the authors of the _var type were trying to achieve. Perhaps they started out with something similar to std::auto_ptr, and then added reference counting, ending up with a solution that is neither here nor there...
    The historical reason is that some submitters (notably IBM) insisted on having a C++ mapping that was binary compatible with a C mapping. So, putting reference counts inside something like a class or a struct wasn't an option, which is why the _var type work the way they do. (Of course, that's no consolation when you are stuck with them.)

    The irony is that, despite all of IBM's insistence, the C++ mapping has never existed in a form that could be made binary compatible with the C mapping. The net effect, of course, is that users ended up with a severely compromised C++ mapping because of this insistency on compatibility with C but, at the same time, got a mapping that never provided that compatibility. Talk about getting the worst of both worlds...

    Originally posted by RyanFogarty
    I think early on. before we discovered the IceUtil::Handle, we had assumed that we were not supposed to be typedef-ing our own IceInternal::Handle types so that's when I decided to use the boost shared_ptr (not realizing under the covers another smart pointer type was being used).
    No, it's perfectly OK to use IceUtil::Handle to make your own typedefs (and the doc shows how to do that in a number of places). The whole point of IceUtil::Handle is that you get a smart pointer that is useful not only for Ice-generated classes, but is useful in general. However, you should not use anything in the IceInternal namespace in your application code. As the name suggests, that's stuff that is internal to Ice, and we need to be free to change that as we see fit without notice.

    Cheers,

    Michi.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. Replies: 7
    Last Post: 12-31-2010, 03:58 AM
  2. bug in IceInternal.Outgoing in Ice 3.2.1
    By dhogan in forum Bug Reports
    Replies: 5
    Last Post: 02-17-2009, 03:03 PM
  3. Replies: 5
    Last Post: 11-05-2007, 11:35 AM
  4. IceInternal::incRef segmentation fault
    By xdm in forum Help Center
    Replies: 2
    Last Post: 06-02-2006, 02:44 PM
  5. IceInternal.BasicStream seems to hold on to objects
    By Venkat Seeth in forum Help Center
    Replies: 12
    Last Post: 05-04-2005, 09:01 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •