Hello,
I'm using mico-2.3.12RC1 released on 17 Sep. on fedora core3.
MICO aborted with following message when I called POA::destroy(true,
true):
poa_impl.cc:2672: void MICOPOA::POA_impl::remove_object(const
PortableServer::ObjectId&): Assertion 'ActiveObjectMap.exists.(id)'
failed.
It occured when calling POA::destroy(true, true) before an operation
of the servant completed, which was activated by the poa.
What I want to do are to etherealize objects and to destory the poa
safely.
My source code are attached below.
Would you like to tell me any suggestion?
Thanks for help!
// michio
-- hello.idl --
// -*- c++ -*-
interface HelloWorld {
void hello ();
};
interface HelloFactory {
HelloWorld createHello(in short i);
void poa_destroy();
};
-- server.cc --
/*
* A simple "Hello World" example that uses the POA
*/
#include "hello.h"
#ifdef HAVE_ANSI_CPLUSPLUS_HEADERS
#include <fstream>
#else
#include <fstream.h>
#endif
#include <time.h>
#include <iostream>
using namespace std;
/*
* Hello World implementation inherits the POA skeleton class
*/
class HelloWorld_impl : public virtual POA_HelloWorld,
public virtual PortableServer::RefCountServantBase
{
public:
HelloWorld_impl(PortableServer::POA_var poa, CORBA::Short i)
: _poa(poa), id(i)
{
};
void hello ();
private:
PortableServer::POA_var _poa;
CORBA::Short id;
};
void
HelloWorld_impl::hello ()
{
const struct timespec ts = {0, 10*1000*1000};
nanosleep(&ts, 0);
cout << "ID : " << id << ", Hello World" << endl;
}
/*
* Hello World implementation inherits the POA skeleton class
*/
class HelloFactory_impl : public virtual POA_HelloFactory,
public virtual PortableServer::RefCountServantBase
{
public:
HelloFactory_impl(CORBA::ORB_ptr orb, PortableServer::POA_ptr poa);
~HelloFactory_impl(){};
HelloWorld_ptr createHello(CORBA::Short i);
void poa_destroy();
void cleanupHellos();
private:
CORBA::ORB_var _orb;
PortableServer::POA_var _root_poa;
PortableServer::POA_var _poa;
bool _do_destroy_root, _do_destroy_child, _do_shutdown_orb,
_is_terminate;
vector<HelloWorld_impl*> _hellos;
MICOMT::Mutex _m;
MICOMT::CondVar _cond;
};
HelloFactory_impl::HelloFactory_impl(CORBA::ORB_ptr orb,
PortableServer::POA_ptr poa)
: _orb(CORBA::ORB::_duplicate(orb)),
_root_poa(PortableServer::POA::_duplicate(poa)),
_do_destroy_root(true), _do_destroy_child(false),
_do_shutdown_orb(false), _is_terminate(false),
_m(false, MICOMT::Mutex::Recursive), _cond(&_m)
{
PortableServer::POAManager_var mgr = poa->the_POAManager();
_poa = poa->create_POA("child", mgr, 0);
}
HelloWorld_ptr
HelloFactory_impl::createHello(CORBA::Short i)
{
HelloWorld_impl * hello = new HelloWorld_impl(_poa, i);
_hellos.push_back(hello);
PortableServer::ObjectId_var oid = _poa->activate_object(hello);
return HelloWorld::_narrow(_poa->id_to_reference(oid));
}
void
HelloFactory_impl::poa_destroy()
{
MICOMT::AutoLock l(_m);
cout << __FUNCTION__ << endl;
_poa->destroy(true, true);
_do_destroy_root = true;
cleanupHellos();
}
void
HelloFactory_impl::cleanupHellos ()
{
cout << __FUNCTION__ << endl;
while(!_hellos.empty()) {
HelloWorld_impl * hello = _hellos.front();
_hellos.erase(_hellos.begin());
hello->_remove_ref();
cout << "hello remove" << endl;
}
_hellos.clear();
}
/*
* Main
*/
int
main (int argc, char *argv[])
{
/*
* Initialize the ORB
*/
CORBA::ORB_var orb = CORBA::ORB_init (argc, argv);
/*
* Obtain a reference to the RootPOA and its Manager
*/
CORBA::Object_var poaobj = orb->resolve_initial_references
("RootPOA");
PortableServer::POA_var poa = PortableServer::POA::_narrow (poaobj);
PortableServer::POAManager_var mgr = poa->the_POAManager();
/*
* Create a Hello World Factory object
*/
HelloFactory_impl * helloFactory = new
HelloFactory_impl(orb.in(), poa.in());
/*
* Activate the Servant
*/
PortableServer::ObjectId_var oid = poa->activate_object
(helloFactory);
/*
* Write reference to file
*/
ofstream of ("hello.ref");
CORBA::Object_var ref = poa->id_to_reference (oid.in());
CORBA::String_var str = orb->object_to_string (ref.in());
of << str.in() << endl;
of.close ();
/*
* Activate the POA and start serving requests
*/
cout << "Running." << endl;
mgr->activate ();
orb->run();
/*
* Shutdown (never reached)
*/
cout << "ORB shutdowned" << endl;
orb->destroy();
helloFactory->_remove_ref();
return 0;
}
-- client.cc --
#include "hello.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef _WIN32
#include <direct.h>
#endif
#include "mico/util.h"
using namespace std;
bool poa_destroyed = false;
/*
* Worker Thread
*/
class MyThread : public virtual MICOMT::Thread
{
public:
MyThread(HelloWorld_var obj, int nmsg)
:_obj(obj) , _nmsg(nmsg) {};
void _run(void *arg = NULL);
private:
HelloWorld_var _obj;
int _nmsg;
};
void
MyThread::_run(void* args)
{
for (int i=0; i<_nmsg; i++) {
try {
_obj->hello();
} catch (CORBA::OBJECT_NOT_EXIST &e) {
cerr << "Object Not Exit, already poa has been destroyed" << endl;
} catch (CORBA::SystemException &e) {
cerr << "client : " << e << endl;
}
}
}
/*
* Test Client
*/
class TestClient
{
public:
TestClient(int argc, char *argv[]);
private:
HelloFactory_var helloFactory;
/*
* Default Value
* Thread : 10
* Message Passing Times : 10
*/
int nr_threads, nr_msgs, sleep_time;
void prepare(CORBA::ORB_var orb);
void run_test();
void terminate(MICOMT::Thread* thrd[]);
};
TestClient::TestClient(int argc, char *argv[])
: helloFactory(HelloFactory::_nil()),
nr_threads(10), nr_msgs(10), sleep_time(10)
{
CORBA::ORB_var orb = CORBA::ORB_init (argc, argv);
prepare(orb);
run_test();
}
void
TestClient::prepare(CORBA::ORB_var orb)
{
char pwd[256], uri[300];
sprintf (uri, "file://%s/hello.ref", getcwd(pwd, 256));
CORBA::Object_var obj = orb->string_to_object (uri);
helloFactory = HelloFactory::_narrow (obj);
if (CORBA::is_nil (helloFactory)) {
cout << "oops: could not locate HelloWorld server" << endl;
exit (1);
}
}
void
TestClient::run_test()
{
MICOMT::Thread* thrd[nr_threads];
for(int i=0; i<nr_threads; i++) {
HelloWorld_var hello = helloFactory->createHello(i);
thrd[i] = new MyThread(hello, nr_msgs);
thrd[i]->start();
}
struct timespec ts = {0, sleep_time*1000*1000}; /* 10 ms */
nanosleep(&ts, 0);
helloFactory->poa_destroy();
poa_destroyed = true;
terminate(thrd);
}
void
TestClient::terminate(MICOMT::Thread* thrd[])
{
for(int i=0; i<nr_threads; i++) {
thrd[i]->wait();
delete thrd[i];
}
}
/*
* Main
*/
int
main (int argc, char *argv[])
{
TestClient client(argc, argv);
return 0;
}
_______________________________________________
Mico-devel mailing list
[email protected]
http://www.mico.org/mailman/listinfo/mico-devel