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

Reply via email to