Discussion:
[omniORB] Boost shared_ptr
Vázquez Landa, David
2008-11-14 20:31:29 UTC
Permalink
Hi,

I guess many of you are using shared_ptr's in your codes... So I wanted to ask how does it work with CORBA...

Say I have an interface:

Interface User
{
void setName(in string name);
string getName();
};

Normally, I would use CORBA's User_var in my code to perform operations... Now my obvious question is if I can use a shared pointer for that purpose...

Thanks :)
Michael
2008-11-14 20:45:52 UTC
Permalink
Client side:
There is very little reason to do this, don't try to use
boost::shared_ptr<User_ptr>, it won't really work and cause headaches.
You could of course use boost::shared_ptr<User_var>, but this is not
smart either.
If anybody knows a reasonable way of doing this I would like to be
enlightened as well :)

Server side:
Depending of the type of POA you're using it can make sense to have
shared_ptrs here. I use the following template:

template<class T>
class CorbaDeleter
{
PortableServer::POA_var _poa;

public:
CorbaDeleter(PortableServer::POA_ptr poa):
_poa(PortableServer::POA::_duplicate(poa))
{}

void operator()(T* p)
{
try
{
if (!_poa->_non_existent())
{
PortableServer::ObjectId_var oid = _poa->servant_to_id(p);
_poa->deactivate_object(oid);
}
}
catch(...)
{
std::cerr << "Exception while deactivating object (maybe not
activated in the first place)" << std::endl;
}
p->_remove_ref();
}
};

I use this for hierarchical objects where I also need to keep a list of
child objects in a parent object. This way all children will get
destroyed correctly if the parent goes away.

Usage looks like:
typedef boost::shared_ptr<User_impl> UserRef;
typedef std::vector<UserRef> UserList;

UserRef user(new User_impl(...), CorbaDeleter<User_impl>(myPoa));
PortableServer::ObjectId_var oid = PortableServer::string_to_ObjectId(...);
myPoa->activate_object_with_id(oid, user.get());

UserList ul;
ul.push_back(user);
Post by Vázquez Landa, David
Hi,
I guess many of you are using shared_ptr's in your codes... So I wanted to ask how does it work with CORBA...
Interface User
{
void setName(in string name);
string getName();
};
Normally, I would use CORBA's User_var in my code to perform operations... Now my obvious question is if I can use a shared pointer for that purpose...
Thanks :)
_______________________________________________
omniORB-list mailing list
http://www.omniorb-support.com/mailman/listinfo/omniorb-list
Vázquez Landa, David
2008-11-14 20:54:53 UTC
Permalink
Thanks for the answer... Pity that it won't work on the client side, I was hoping for a way of automatically calling "destroy()" when an interface isn't used anymore...

See, On the server side I use Java, but I still have a destroy() method for my interfaces, such that I can deactivate them (remove them from the AOM.)

Thus, user would see like:

Interface user
{
void setName(in string name);
string getName();
void destroy();
};

And by using shared_ptr on the client side, I was hoping to be able to call my own implementation of the interface's destructor, hence, calling user->destroy(); automatically...

So now I'm at a loss... :S If I wrote a wrapper for the interface user, I suppose I could use a shared_ptr to that wrapper and call the wrapper's destructor and, well, you get it, I suppose.

It's perhaps very onion-like, but I still HAVE TO use wrappers (not my decission really), so I may as well try it like that...

What do you think? Would it be viable?

-----Urspr?ngliche Nachricht-----
Von: Michael [mailto:***@bindone.de]
Gesendet: Freitag, 14. November 2008 15:46
An: V?zquez Landa, David
Cc: omniorb-***@omniorb-support.com
Betreff: Re: [omniORB] Boost shared_ptr

Client side:
There is very little reason to do this, don't try to use boost::shared_ptr<User_ptr>, it won't really work and cause headaches.
You could of course use boost::shared_ptr<User_var>, but this is not smart either.
If anybody knows a reasonable way of doing this I would like to be enlightened as well :)

Server side:
Depending of the type of POA you're using it can make sense to have shared_ptrs here. I use the following template:

template<class T>
class CorbaDeleter
{
PortableServer::POA_var _poa;

public:
CorbaDeleter(PortableServer::POA_ptr poa):
_poa(PortableServer::POA::_duplicate(poa))
{}

void operator()(T* p)
{
try
{
if (!_poa->_non_existent())
{
PortableServer::ObjectId_var oid = _poa->servant_to_id(p);
_poa->deactivate_object(oid);
}
}
catch(...)
{
std::cerr << "Exception while deactivating object (maybe not activated in the first place)" << std::endl;
}
p->_remove_ref();
}
};

I use this for hierarchical objects where I also need to keep a list of child objects in a parent object. This way all children will get destroyed correctly if the parent goes away.

Usage looks like:
typedef boost::shared_ptr<User_impl> UserRef; typedef std::vector<UserRef> UserList;

UserRef user(new User_impl(...), CorbaDeleter<User_impl>(myPoa)); PortableServer::ObjectId_var oid = PortableServer::string_to_ObjectId(...);
myPoa->activate_object_with_id(oid, user.get());

UserList ul;
ul.push_back(user);
Post by Vázquez Landa, David
Hi,
I guess many of you are using shared_ptr's in your codes... So I wanted to ask how does it work with CORBA...
Interface User
{
void setName(in string name);
string getName();
};
Normally, I would use CORBA's User_var in my code to perform operations... Now my obvious question is if I can use a shared pointer for that purpose...
Thanks :)
_______________________________________________
omniORB-list mailing list
http://www.omniorb-support.com/mailman/listinfo/omniorb-list
Michael
2008-11-14 21:24:58 UTC
Permalink
That's possible, even so I'm not certain if shared_ptr is the best
wrapper for this. In this case you should create a shared_ptr. If you
not certain how to do it exactly I might check on this later (tell me if
you're lost).

Another question of course is if you really need a destroy method. Are
you dealing with persistent objects (e.g. database backed) or are those
objects volatile? If they're persistent you might consider either using
a default servant or a servant locator (+eviction cache) on the server
side. This is much easier from a client perspective and ensures your
server is not leaking resources.
Post by Vázquez Landa, David
Thanks for the answer... Pity that it won't work on the client side, I was hoping for a way of automatically calling "destroy()" when an interface isn't used anymore...
See, On the server side I use Java, but I still have a destroy() method for my interfaces, such that I can deactivate them (remove them from the AOM.)
Interface user
{
void setName(in string name);
string getName();
void destroy();
};
And by using shared_ptr on the client side, I was hoping to be able to call my own implementation of the interface's destructor, hence, calling user->destroy(); automatically...
So now I'm at a loss... :S If I wrote a wrapper for the interface user, I suppose I could use a shared_ptr to that wrapper and call the wrapper's destructor and, well, you get it, I suppose.
It's perhaps very onion-like, but I still HAVE TO use wrappers (not my decission really), so I may as well try it like that...
What do you think? Would it be viable?
-----Urspr?ngliche Nachricht-----
Gesendet: Freitag, 14. November 2008 15:46
An: V?zquez Landa, David
Betreff: Re: [omniORB] Boost shared_ptr
There is very little reason to do this, don't try to use boost::shared_ptr<User_ptr>, it won't really work and cause headaches.
You could of course use boost::shared_ptr<User_var>, but this is not smart either.
If anybody knows a reasonable way of doing this I would like to be enlightened as well :)
template<class T>
class CorbaDeleter
{
PortableServer::POA_var _poa;
_poa(PortableServer::POA::_duplicate(poa))
{}
void operator()(T* p)
{
try
{
if (!_poa->_non_existent())
{
PortableServer::ObjectId_var oid = _poa->servant_to_id(p);
_poa->deactivate_object(oid);
}
}
catch(...)
{
std::cerr << "Exception while deactivating object (maybe not activated in the first place)" << std::endl;
}
p->_remove_ref();
}
};
I use this for hierarchical objects where I also need to keep a list of child objects in a parent object. This way all children will get destroyed correctly if the parent goes away.
typedef boost::shared_ptr<User_impl> UserRef; typedef std::vector<UserRef> UserList;
UserRef user(new User_impl(...), CorbaDeleter<User_impl>(myPoa)); PortableServer::ObjectId_var oid = PortableServer::string_to_ObjectId(...);
myPoa->activate_object_with_id(oid, user.get());
UserList ul;
ul.push_back(user);
Post by Vázquez Landa, David
Hi,
I guess many of you are using shared_ptr's in your codes... So I wanted to ask how does it work with CORBA...
Interface User
{
void setName(in string name);
string getName();
};
Normally, I would use CORBA's User_var in my code to perform operations... Now my obvious question is if I can use a shared pointer for that purpose...
Thanks :)
_______________________________________________
omniORB-list mailing list
http://www.omniorb-support.com/mailman/listinfo/omniorb-list
Vázquez Landa, David
2008-11-17 16:00:17 UTC
Permalink
Ok, sorry, my bad... I meant a POA per class. And I asked because I have many many classes... But that shouldn't be a problem anyway.

Right now I'm using unique ID's and I'm not sure whether to use "SYSTEM_ID" or "USER_ID" --I'm more inclined to use "SYSTEM_ID" though.

And about persistence... Well, as I understand it, my persistence objects are the ones stored in the database, CORBA servants and clients are no more than interfaces to those objects --damn! I hope I'm not doing something really wrong here. Anyway, I have one Factory class, which I use to get instances of any object I may need (that's pure Java), and in the CORBA implementation I defined an interface for this factory which implements ist methods. In other words it's a "CorbaFactory", it uses the normal pure Java Factory to create the db Objects and delivers servants for each one of them. (haha, I think I just explained something utterly obvious)

Mist! Hahaha, oh well... It's never too late to change something.

Oh yeah, and about concurrency... I thought that I should manage that at the database level. Meaning, two clients shouldn't be able to modify the same object at the same time... But I don't know if you're talking about that or about servants.. I don't know if two clients can use the same servant the way I have it implemented.

I'm very thankful for all these details you're making me think of :)... Thanks, seriously.

-----Urspr?ngliche Nachricht-----
Von: Michael [mailto:***@bindone.de]
Gesendet: Montag, 17. November 2008 10:37
An: V?zquez Landa, David
Betreff: Re: AW: AW: [omniORB] Boost shared_ptr

hi,

I'm not a Java expert, but this should be possible and I think it's better than having to rely on the client to do everything correctly.

The eviction pattern is basically a cache, that keeps N persistent objects in memory and everytime the object is used (a method on it is
called) it is put back to the front of the cache. When loading new objects, it will evict out object N+1. Relatively simple if you're using a servant locator.

You will not need to use one POA per object, but you need to roll your own object ids (e.g. make them match the id in the database or another identifier you're using to create the pre-existing object). Normally you will use one POA per class of objects, even so a different algorithm (like prefixing object ids with different strings per type) is possible as well. Just remember to use unique object ids per instance and that you need to create at least one POA, because you cannot change the policyset on the root POA (or at least should not).

How do you actually look up persistent objects in your current implementation, since it seems like you're using the AOM without self defined object ids (how do you prevent different clients from talking to different instances of the same object - do you run your own mapping in-mem?!?).

br
michael
I tried using both, a servant locator and just the normal AOM (yes,
It's a db app). Anyway, the persistent objects exist already (this is
an evolution on an existing program) and I had to wrap them on my
servants. The problem with this is that java apparently doesn't
finalize some objects, therefore causing me headaches and memory heap
exceptions... The only way I was able to control that was with a
destroy method, where I'd deactivate the corba objects and erase
references to the persistent ones. Then again, it may also be poor
programming on my part, since it's my first real CORBA app. ^^
Q. If I were to use a default servant or servant locator, wouldn't I need one poa&(default-)servant(-locator) for each object?
Humm... Eviction cache?
-----Urspr?ngliche Nachricht-----
Gesendet: Freitag, 14. November 2008 16:25
An: V?zquez Landa, David
Betreff: Re: AW: [omniORB] Boost shared_ptr
That's possible, even so I'm not certain if shared_ptr is the best wrapper for this. In this case you should create a shared_ptr. If you not certain how to do it exactly I might check on this later (tell me if you're lost).
Another question of course is if you really need a destroy method. Are you dealing with persistent objects (e.g. database backed) or are those objects volatile? If they're persistent you might consider either using a default servant or a servant locator (+eviction cache) on the server side. This is much easier from a client perspective and ensures your server is not leaking resources.
Post by Vázquez Landa, David
Thanks for the answer... Pity that it won't work on the client side, I was hoping for a way of automatically calling "destroy()" when an interface isn't used anymore...
See, On the server side I use Java, but I still have a destroy()
method for my interfaces, such that I can deactivate them (remove
them from the AOM.)
Interface user
{
void setName(in string name);
string getName();
void destroy();
};
And by using shared_ptr on the client side, I was hoping to be able to call my own implementation of the interface's destructor, hence, calling user->destroy(); automatically...
So now I'm at a loss... :S If I wrote a wrapper for the interface user, I suppose I could use a shared_ptr to that wrapper and call the wrapper's destructor and, well, you get it, I suppose.
It's perhaps very onion-like, but I still HAVE TO use wrappers (not my decission really), so I may as well try it like that...
What do you think? Would it be viable?
-----Urspr?ngliche Nachricht-----
Gesendet: Freitag, 14. November 2008 15:46
An: V?zquez Landa, David
Betreff: Re: [omniORB] Boost shared_ptr
There is very little reason to do this, don't try to use boost::shared_ptr<User_ptr>, it won't really work and cause headaches.
You could of course use boost::shared_ptr<User_var>, but this is not smart either.
If anybody knows a reasonable way of doing this I would like to be enlightened as well :)
template<class T>
class CorbaDeleter
{
PortableServer::POA_var _poa;
_poa(PortableServer::POA::_duplicate(poa))
{}
void operator()(T* p)
{
try
{
if (!_poa->_non_existent())
{
PortableServer::ObjectId_var oid = _poa->servant_to_id(p);
_poa->deactivate_object(oid);
}
}
catch(...)
{
std::cerr << "Exception while deactivating object (maybe not activated in the first place)" << std::endl;
}
p->_remove_ref();
}
};
I use this for hierarchical objects where I also need to keep a list of child objects in a parent object. This way all children will get destroyed correctly if the parent goes away.
typedef boost::shared_ptr<User_impl> UserRef; typedef
std::vector<UserRef> UserList;
UserRef user(new User_impl(...), CorbaDeleter<User_impl>(myPoa));
PortableServer::ObjectId_var oid =
PortableServer::string_to_ObjectId(...);
myPoa->activate_object_with_id(oid, user.get());
UserList ul;
ul.push_back(user);
Post by Vázquez Landa, David
Hi,
I guess many of you are using shared_ptr's in your codes... So I wanted to ask how does it work with CORBA...
Interface User
{
void setName(in string name);
string getName();
};
Normally, I would use CORBA's User_var in my code to perform operations... Now my obvious question is if I can use a shared pointer for that purpose...
Thanks :)
_______________________________________________
omniORB-list mailing list
http://www.omniorb-support.com/mailman/listinfo/omniorb-list
Kevin Bailey
2008-11-17 22:20:09 UTC
Permalink
Post by Vázquez Landa, David
Right now I'm using unique ID's and I'm not sure whether to use
"SYSTEM_ID" or "USER_ID" --I'm more inclined to use "SYSTEM_ID" though.
And about persistence... Well, as I understand it, my persistence objects
are the ones stored in the database, CORBA servants and clients are no
more than interfaces to those objects --damn! I hope I'm not doing
something really wrong here. Anyway, I have one Factory class, which I use
to get instances of any object I may need (that's pure Java), and in the
CORBA implementation I defined an interface for this factory which
implements ist methods. In other words it's a "CorbaFactory", it uses the
normal pure Java Factory to create the db Objects and delivers servants
for each one of them. (haha, I think I just explained something utterly
obvious)
Take a look at Henning&Vinoski. It sounds like the USER_ID,
NON_RETAIN and SERVANT_MANAGER might be appropriate to what
you're doing and they describe it well.
Brian Neal
2008-11-19 04:16:20 UTC
Permalink
As previously stated, there isn't really a compelling reason to use
shared_ptr when dealing with CORBA types. Recall that the default
action of shared_ptr is to perform a delete on the pointer. You don't
want that. You can pass a custom deleter to shared_ptr, and here you
could instruct it to do a release() operation instead, or something
else. Since object references have their own reference count,
intrusive_ptr would seem a better choice than shared_ptr. But, this
also assumes that the ORB implements _ptr types as C++ pointers. ORBs
don't have to do that and you would be making your code less portable
by assuming that is the case.

So, on the client side, my advice is to continue to use the _var types
to manage object references.

On the server side you can use Servant_var. Servant_var was added to
the C++ mapping in version 1.1. Recent versions of omniORB support
Servant_var.

Loading...