[omniORB] Some changes to bidir sample with (Problems=Unknowledge=1)

Fernando A. de Araujo Filho maverick@elogica.com.br
Thu Oct 31 05:39:01 2002


Hi everybody ...

I have made some changes to Bidir sample (omniORB-4.0.0\src\examples\bidir).
Let me try to explain with my, no coments,  english ... :-)

The problem :
BD_SERVER is started
BD_CLIENT is started  with IOR of BD_SERVER
BD_CLIENT finish OK
BD_CLIENT is restarted  with the same IOR of the same BD_SERVER
BD_CLIENT fail. I presume something about callback reference retained on
BD_SERVER cause
a COMM::FAILURE exception, I really dont know ...

In short, works only once ...

Sorry for long dump (traceLevel 10), Duncan, if I am breaking any rule,
please advise me.
I like the ideas about PortableServer::PERSISTENT and
BiDirPolicy::BIDIRECTIONAL_POLICY_TYPE.
In this way, I created for both, bd_server and bd_client,
BiDirPolicy::BIDIRECTIONAL_POLICY_TYPE,
PortableServer::PERSISTENT  and PortableServer::USER_ID policies.
In case of  both had to work as "client and servant". Well, why do not
complicate if we can do easyest ... ~:-]

I changed IDL
added "void register(in Server srv);"  to interface CallBack
added "void call_Back(in string mesg);"  to interface Server

I have added many initialization parameters .
I have registered a callback object on BD_SERVER
The rest is basically the same of original sample.

thanks for any reply,

Fernando
maverick@elogica.com.br

Dumps and sources below

****************************************************
FIRST DUMP OF BD_CLIENT
****************************************************
C:\libs\omniORB-4.0.0\src\examples\bidir>bd_client
IOR:010000001200000049444c3a6
3622f5365727665723a312e300000000100000000000000ba000000010102001000000031363
92e3
235342e3137342e31373700800d00001e000000ff62696469722e70657273697374656e74005
3455
2564552434c49454e5400000400000000000000080000000100000000545441010000001c000
0000
1000000010001000100000001000105090101000100000009010100030000001a00000001000
0000
f0000003230302e3136342e3235352e34390000800d00000300000016000000010000000c000
0003
139322e3136382e302e3100800d 1 2
omniORB: Distribution date: Sun Sep 22 22:06:56 BST 2002 dgrisby
omniORB: Initialising omniDynamic library.
omniORB: Initialising incoming endpoints.
omniORB: Starting serving incoming endpoints.
omniORB: Adding root/bidir.persistent<CLIENTSERVER> (activating) to object
table
.
omniORB: Creating ref to local: root/bidir.persistent<CLIENTSERVER>
 target id      : IDL:cb/CallBack:1.0
 most derived id: IDL:cb/CallBack:1.0
omniORB: Creating ref to remote: root/bidir.persistent<SERVERCLIENT>
 target id      : IDL:omg.org/CORBA/Object:1.0
 most derived id: IDL:cb/Server:1.0

CLIENT: REGISTER ITSELF ON SERVER
omniORB: LocateRequest to remote: root/bidir.persistent<SERVERCLIENT>
omniORB: AsyncInvoker: thread id = 1 has started. Total threads = 2
omniORB: AsyncInvoker: thread id = 2 has started. Total threads = 2
omniORB: AsyncInvoker: thread id = 3 has started. Total threads = 4
omniORB: AsyncInvoker: thread id = 4 has started. Total threads = 4
omniORB: AsyncInvoker: thread id = 5 has started. Total threads = 5
omniORB: Accepted connection from giop:tcp:169.254.174.177:4267 because of
this
rule: "* unix,tcp,bidir"
omniORB: Handling a GIOP LOCATE_REQUEST.
omniORB: Accepted request from giop:tcp:169.254.174.177:4267 to switch to
bidire
ctional because of this rule: "* unix,tcp,bidir"
omniORB: Creating ref to remote: root/bidir.persistent<SERVERCLIENT>
 target id      : IDL:cb/Server:1.0
 most derived id: IDL:cb/Server:1.0

CLIENT _cxx_register: CALLBACK FROM SERVER. LETS TRY TO DUPLICATE

CLIENT RECEIVE CALLBACK FROM SERVER MSG=**** HELLO FROM CLIENT ****
omniORB: LocateRequest to remote: root/bidir.persistent<SERVERCLIENT>
omniORB: AsyncInvoker: thread id = 6 has started. Total threads = 6

CLIENT: FINISHED.
omniORB: Preparing to shutdown ORB.
omniORB: Destroying POA(RootPOA).
omniORB: Destroying POA(bidir.persistent).
omniORB: Deactivating all POA(bidir.persistent)'s objects.
omniORB: Waiting for requests to complete on POA(bidir.persistent).
omniORB: Requests on POA(bidir.persistent) completed.
omniORB: Etherealising POA(bidir.persistent)'s objects.
omniORB: Removing root/bidir.persistent<CLIENTSERVER> (etherealising) from
objec
t table
omniORB: Destruction of POA(bidir.persistent) complete.
omniORB: Deactivating all POA(RootPOA)'s objects.
omniORB: Waiting for requests to complete on POA(RootPOA).
omniORB: Requests on POA(RootPOA) completed.
omniORB: Etherealising POA(RootPOA)'s objects.
omniORB: Stopping serving incoming endpoints.
omniORB: throw giopStream::CommFailure from
giopStream.cc:812(0,NO,COMM_FAILURE_
UnMarshalArguments)
omniORB: throw giopStream::CommFailure from
giopStream.cc:812(0,NO,COMM_FAILURE_
UnMarshalArguments)
omniORB: throw giopStream::CommFailure from
giopStream.cc:812(0,NO,COMM_FAILURE_
UnMarshalArguments)
omniORB: Destruction of POA(RootPOA) complete.
omniORB: Shutting-down all incoming endpoints.
omniORB: ORB shutdown is complete.
omniORB: Deinitialising omniDynamic library.
omniORB: AsyncInvoker: thread id = 5 has exited. Total threads = 6
omniORB: AsyncInvoker: thread id = 6 has exited. Total threads = 6
omniORB: AsyncInvoker: thread id = 3 has exited. Total threads = 6
omniORB: AsyncInvoker: thread id = 2 has exited. Total threads = 3
omniORB: AsyncInvoker: thread id = 4 has exited. Total threads = 3
omniORB: AsyncInvoker: thread id = 1 has exited. Total threads = 3
omniORB: AsyncInvoker: deleted.
omniORB: Final clean-up completed.

C:\libs\omniORB-4.0.0\src\examples\bidir>

****************************************************
SECOND DUMP OF BD_CLIENT
****************************************************
C:\libs\omniORB-4.0.0\src\examples\bidir>bd_client
IOR:010000001200000049444c3a6
3622f5365727665723a312e300000000100000000000000ba000000010102001000000031363
92e3
235342e3137342e31373700800d00001e000000ff62696469722e70657273697374656e74005
3455
2564552434c49454e5400000400000000000000080000000100000000545441010000001c000
0000
1000000010001000100000001000105090101000100000009010100030000001a00000001000
0000
f0000003230302e3136342e3235352e34390000800d00000300000016000000010000000c000
0003
139322e3136382e302e3100800d 1 2
omniORB: Distribution date: Sun Sep 22 22:06:56 BST 2002 dgrisby
omniORB: Initialising omniDynamic library.
omniORB: Initialising incoming endpoints.
omniORB: Starting serving incoming endpoints.
omniORB: Adding root/bidir.persistent<CLIENTSERVER> (activating) to object
table
.
omniORB: Creating ref to local: root/bidir.persistent<CLIENTSERVER>
 target id      : IDL:cb/CallBack:1.0
 most derived id: IDL:cb/CallBack:1.0
omniORB: Creating ref to remote: root/bidir.persistent<SERVERCLIENT>
 target id      : IDL:omg.org/CORBA/Object:1.0
 most derived id: IDL:cb/Server:1.0

CLIENT: REGISTER ITSELF ON SERVER
omniORB: AsyncInvoker: thread id = 1 has started. Total threads = 1
omniORB: LocateRequest to remote: root/bidir.persistent<SERVERCLIENT>
omniORB: AsyncInvoker: thread id = 2 has started. Total threads = 4
omniORB: AsyncInvoker: thread id = 3 has started. Total threads = 4
omniORB: AsyncInvoker: thread id = 4 has started. Total threads = 4

CLIENT: FINISHED.
omniORB: Preparing to shutdown ORB.
omniORB: Destroying POA(RootPOA).
omniORB: Destroying POA(bidir.persistent).
omniORB: Deactivating all POA(bidir.persistent)'s objects.
omniORB: Waiting for requests to complete on POA(bidir.persistent).
omniORB: Requests on POA(bidir.persistent) completed.
omniORB: Etherealising POA(bidir.persistent)'s objects.
omniORB: Removing root/bidir.persistent<CLIENTSERVER> (etherealising) from
objec
t table
omniORB: Destruction of POA(bidir.persistent) complete.
omniORB: Deactivating all POA(RootPOA)'s objects.
omniORB: Waiting for requests to complete on POA(RootPOA).
omniORB: Requests on POA(RootPOA) completed.
omniORB: Etherealising POA(RootPOA)'s objects.
omniORB: Stopping serving incoming endpoints.
omniORB: throw giopStream::CommFailure from
giopStream.cc:812(0,NO,COMM_FAILURE_
UnMarshalArguments)
omniORB: Destruction of POA(RootPOA) complete.
omniORB: Shutting-down all incoming endpoints.
omniORB: ORB shutdown is complete.
omniORB: Deinitialising omniDynamic library.
omniORB: AsyncInvoker: thread id = 2 has exited. Total threads = 4
omniORB: AsyncInvoker: thread id = 1 has exited. Total threads = 3
omniORB: AsyncInvoker: thread id = 3 has exited. Total threads = 2
omniORB: AsyncInvoker: thread id = 4 has exited. Total threads = 1
omniORB: AsyncInvoker: deleted.
omniORB: Final clean-up completed.

C:\libs\omniORB-4.0.0\src\examples\bidir>


****************************************************
DUMP OF BD_SERVER
****************************************************
C:\libs\omniORB-4.0.0\src\examples\bidir>bd_server
omniORB: Distribution date: Sun Sep 22 22:06:56 BST 2002 dgrisby
omniORB: Initialising omniDynamic library.
omniORB: Initialising incoming endpoints.
omniORB: Starting serving incoming endpoints.
omniORB: Adding root/bidir.persistent<SERVERCLIENT> (activating) to object
table
.
omniORB: Creating ref to local: root/bidir.persistent<SERVERCLIENT>
 target id      : IDL:cb/Server:1.0
 most derived id: IDL:cb/Server:1.0

IOR:010000001200000049444c3a63622f5365727665723a312e300000000100000000000000
ba00
000001010200100000003136392e3235342e3137342e31373700800d00001e000000ff626964
6972
2e70657273697374656e7400534552564552434c49454e540000040000000000000008000000
0100
000000545441010000001c000000010000000100010001000000010001050901010001000000
0901
0100030000001a000000010000000f0000003230302e3136342e3235352e34390000800d0000
0300
000016000000010000000c0000003139322e3136382e302e3100800d
omniORB: AsyncInvoker: thread id = 1 has started. Total threads = 1
omniORB: AsyncInvoker: thread id = 2 has started. Total threads = 3
omniORB: AsyncInvoker: thread id = 3 has started. Total threads = 3
omniORB: Accepted connection from giop:tcp:169.254.174.177:4266 because of
this
rule: "* unix,tcp,bidir"
omniORB: Handling a GIOP LOCATE_REQUEST.
omniORB: Accepted request from giop:tcp:169.254.174.177:4266 to switch to
bidire
ctional because of this rule: "* unix,tcp,bidir"
omniORB: Creating ref to remote: root/bidir.persistent<CLIENTSERVER>
 target id      : IDL:cb/CallBack:1.0
 most derived id: IDL:cb/CallBack:1.0

DUPLICATE CLIENT REF OK

SERVER TRY TO REGISTER IT AS A CALLBACK ON CLIENT, DESPITE THE CLIENT HAVE
"NARR
OWED" IT
omniORB: LocateRequest to remote: root/bidir.persistent<CLIENTSERVER>
omniORB: AsyncInvoker: thread id = 5 has started. Total threads = 5
omniORB: AsyncInvoker: thread id = 6 has started. Total threads = 5

SERVER REPLY MESSAGE FROM CLIENT
omniORB: AsyncInvoker: thread id = 7 has started. Total threads = 6
omniORB: Accepted connection from giop:tcp:169.254.174.177:4268 because of
this
rule: "* unix,tcp,bidir"
omniORB: Handling a GIOP LOCATE_REQUEST.
omniORB: Accepted request from giop:tcp:169.254.174.177:4268 to switch to
bidire
ctional because of this rule: "* unix,tcp,bidir"

CALL BACK FROM CLIENT: CLIENT REPLY CALLBACK TO SERVER
omniORB: throw giopStream::CommFailure from
giopImpl12.cc:1218(0,NO,COMM_FAILURE
_UnMarshalArguments)
omniORB: throw giopStream::CommFailure from
giopImpl12.cc:1218(0,NO,COMM_FAILURE
_UnMarshalArguments)
omniORB: throw giopStream::CommFailure from
giopImpl12.cc:1218(0,NO,COMM_FAILURE
_UnMarshalArguments)

SERVER REPLY MESSAGE FROM CLIENT
omniORB: throw TRANSIENT from giopRope.cc:321 (NO,TRANSIENT_CallTimedout)
omniORB: throw TRANSIENT from omniObjRef.cc:745 (NO,TRANSIENT_CallTimedout)

CB_SERVER: LOST CLIENT!

CB_SERVER: THREAD EXITING
omniORB: AsyncInvoker: thread id = 3 has exited. Total threads = 6
omniORB: AsyncInvoker: thread id = 7 has exited. Total threads = 6
omniORB: AsyncInvoker: thread id = 5 has exited. Total threads = 4
omniORB: AsyncInvoker: thread id = 8 has started. Total threads = 4
omniORB: Accepted connection from giop:tcp:169.254.174.177:4276 because of
this
rule: "* unix,tcp,bidir"
omniORB: Handling a GIOP LOCATE_REQUEST.
omniORB: Accepted request from giop:tcp:169.254.174.177:4276 to switch to
bidire
ctional because of this rule: "* unix,tcp,bidir"
omniORB: Creating ref to remote: root/bidir.persistent<CLIENTSERVER>
 target id      : IDL:cb/CallBack:1.0
 most derived id: IDL:cb/CallBack:1.0

DUPLICATE CLIENT REF OK

SERVER TRY TO REGISTER IT AS A CALLBACK ON CLIENT, DESPITE THE CLIENT HAVE
"NARR
OWED" IT
omniORB: LocateRequest to remote: root/bidir.persistent<CLIENTSERVER>
omniORB: throw giopStream::CommFailure from
giopImpl12.cc:1218(0,NO,COMM_FAILURE
_UnMarshalArguments)
omniORB: throw TRANSIENT from giopRope.cc:321 (NO,TRANSIENT_CallTimedout)

CB_SERVER: LOST CLIENT!

CB_SERVER: THREAD EXITING
omniORB: AsyncInvoker: thread id = 8 has exited. Total threads = 4



************************************************
THE SOURCES:
************************************************
BD_CLIENT.CC
************************************************
#include <iostream.h>
#include <stdlib.h>
#include <echo_callback.hh>
#include <malloc.h>
#include <stdio.h>
// Implementation of cb::CallBack.
class cb_i : public virtual POA_cb::CallBack,
      public virtual PortableServer::RefCountServantBase {
public:
  inline cb_i() {}
  virtual ~cb_i() {}
  virtual void call_back(const char* mesg)
  {
 cerr << endl << "CLIENT RECEIVE CALLBACK FROM SERVER MSG=" << mesg << endl;
 srv->call_Back("CLIENT REPLY CALLBACK TO SERVER");
  }
  // RECEIVE A REF FROM THE SERVER ... "
  virtual void _cxx_register(cb::Server_ptr srv)
  {
     cerr << endl << "CLIENT _cxx_register: CALLBACK FROM SERVER. LETS TRY
TO DUPLICATE" << endl;
  try {
  this->srv = cb::Server::_duplicate(srv);
  }
  catch (...) {
  cerr << endl << "_cxx_register: CALLBACK FROM SERVER. DUPLICATE ERROR" <<
endl;
  }

  }
private:
  CORBA::String_var pd_mesg;
public:
  cb::CallBack_var callback;
  cb::Server_var srv;
  cb::Server_var server;
};
//////////////////////////////////////////////////////////////////////
static void do_single(cb_i* mycallback)
{
  if( CORBA::is_nil(mycallback->server) ) {
    cerr << endl << "CLIENT: SERVER REFERENCE IS NIL 0!" << endl;
    return;
  }
  mycallback->server->one_time(mycallback->callback, "HELLO ONE TIME!");
}

static void do_register(cb_i* mycallback, int period, int time_to_shutdown)
{
  if( CORBA::is_nil(mycallback->server) ) {
    cerr << endl << "CLIENT: CLIENT: SERVER REFERENCE IS NIL 1!" << endl;
    return;
  }
  cerr << endl << "CLIENT: REGISTER ITSELF ON SERVER" << endl;
  mycallback->server->_cxx_register(mycallback->callback, "**** HELLO FROM
CLIENT ****", period);
  omni_thread::sleep(time_to_shutdown);
  cerr << endl << "CLIENT: FINISHED." << endl;
}

void insertArgs(int& argc, char**& argv, int idx, int nargs)
{
 char** newArgv = new char*[argc+nargs];
 int i;
 for (i = 0; i < idx; i++) {
  newArgv[i] = argv[i];
 }
 for (i = idx; i < argc; i++) {
  newArgv[i+nargs] = argv[i];
 }
 argv = newArgv;
 argc += nargs;
}


//////////////////////////////////////////////////////////////////////
int main(int argc, char** argv)
{
 try {
       if( argc != 2 && argc != 4 )
    {
   cerr << endl << "usage:  bd_client <object reference> [<call-back
period>"
      " <time to shutdown>]" << endl;
     return 1;
    }

  int argc1=0;
  char ** argv1;
  insertArgs(argc1, argv1, 0, 20);
  argv1[0] = strdup("-ORBendPoint");
  argv1[1] = (char*) malloc(32);
  sprintf(argv1[1], "giop:tcp::3459");
  argv1[2] = strdup("-ORBclientTransportRule");
  argv1[3] = strdup("* unix,tcp,bidir");
  argv1[4] = strdup("-ORBserverTransportRule");
  argv1[5] = strdup("* unix,tcp,bidir");
  argv1[6] = strdup("-ORBofferBiDirectionalGIOP");
  argv1[7] = strdup("1");
  argv1[8] = strdup("-ORBacceptBiDirectionalGIOP");
  argv1[9] = strdup("1");
  argv1[10] = strdup("-ORBendPointPublishAllIFs");
  argv1[11] = strdup("1");
  argv1[12] = strdup("-ORBtraceLevel");
  argv1[13] = strdup("10");
  argv1[14] = strdup("-ORBoneCallPerConnection");
  argv1[15] = strdup("0");
  argv1[16] = strdup("-ORBclientCallTimeOutPeriod");
  argv1[17] = strdup("5000");
  argv1[18] = strdup("-ORBserverCallTimeOutPeriod");
  argv1[19] = strdup("5000" );
        CORBA::ORB_var orb = CORBA::ORB_init(argc1, argv1);
  CORBA::Object_var obj;

  obj = orb->resolve_initial_references("RootPOA");
  PortableServer::POA_var rootpoa = PortableServer::POA::_narrow(obj);
  PortableServer::POAManager_var pman = rootpoa->the_POAManager();
  pman->activate();

  // Create a POA with the Bidirectional policy
  CORBA::PolicyList pl;
  pl.length(3);
  CORBA::Any a;
  a <<= BiDirPolicy::BOTH;
  pl[0] = orb->create_policy(BiDirPolicy::BIDIRECTIONAL_POLICY_TYPE, a);
  pl[1] = rootpoa->create_lifespan_policy(PortableServer::PERSISTENT);
  pl[2] = rootpoa->create_id_assignment_policy(PortableServer::USER_ID);

  // create a child poa derived from rootpoa
  PortableServer::POA_var poa = rootpoa->create_POA("bidir.persistent",
pman, pl);

  cb_i* mycallback = new cb_i();
  PortableServer::ObjectId_var oid =
PortableServer::string_to_ObjectId("CLIENTSERVER");
  poa->activate_object_with_id(oid, mycallback);
  mycallback->callback = mycallback->_this();
  mycallback->_remove_ref();

  obj = orb->string_to_object(argv[1]);
  mycallback->server = cb::Server::_narrow(obj);

  if( argc == 2 )  do_single(mycallback);
  else             do_register(mycallback, atoi(argv[2]), atoi(argv[3]));
  orb->destroy();
 }
 catch(CORBA::COMM_FAILURE& ex) {
  cerr << endl << "Caught system exception COMM_FAILURE -- unable to contact
the "
    << "object." << endl;
 }
 catch(CORBA::SystemException&) {
  cerr << endl << "Caught a CORBA::SystemException." << endl;
 }
 catch(CORBA::Exception&) {
  cerr << endl << "Caught CORBA::Exception." << endl;
 }
 catch(omniORB::fatalException& fe) {
  cerr << endl << "Caught omniORB::fatalException:" << endl;
  cerr << endl << "  file: " << fe.file() << endl;
  cerr << endl << "  line: " << fe.line() << endl;
  cerr << endl << "  mesg: " << fe.errmsg() << endl;
 }
 catch(...) {
  cerr << endl << "Caught unknown exception." << endl;
 }
 return 0;
}


************************************************
THE SOURCES:
************************************************
BD_SERVER
************************************************
#include <iostream.h>
#include <echo_callback.hh>
#include <malloc.h>
#include <stdio.h>

static CORBA::ORB_ptr orb;
static int            dying = 0;
static int            num_active_servers = 0;
static omni_mutex     mu;
static omni_condition sigobj(&mu);

//////////////////////////////////////////////////////////////////////
// Implementation of cb::Server.
class server_i : public POA_cb::Server,
   public PortableServer::RefCountServantBase
{
public:
  inline server_i() {}
  virtual ~server_i();
  virtual void one_time(cb::CallBack_ptr cb, const char* mesg);
  virtual void _cxx_register(cb::CallBack_ptr cb, const char* mesg,
        CORBA::UShort period_secs);
  virtual void call_Back(const char* mesg);
  virtual void shutdown();
  cb::Server_var srv;
  cb::CallBack_var cbVar;
};

class server_thread : public omni_thread {
public:
  inline server_thread(server_i* srvI, cb::CallBack_ptr client, const char*
mesg, int period)
    {
     pd_mesg = mesg;
  pd_period = period;
  this->srvI = srvI;
  try {
   this->srvI->cbVar = cb::CallBack::_duplicate(client);
   cerr << endl << "DUPLICATE CLIENT REF OK" << endl;
  }
  catch (...) {
   cerr << endl << "DUPLICATE CLIENT REF ERROR" << endl;
  }

  }
  virtual void run(void* arg);
private:
  CORBA::String_var pd_mesg;
  int              pd_period;
  int              count;
  server_i* srvI;
};


void server_thread::run(void* arg)
{
  try {
     cerr << endl << "SERVER TRY TO REGISTER IT AS A CALLBACK ON CLIENT,
DESPITE THE CLIENT HAVE \"NARROWED\" IT" << endl;
  srvI->cbVar->_cxx_register(srvI->srv);
     while( !dying ) {
        omni_thread::sleep(pd_period);
  try {
   cerr << endl << "SERVER REPLY MESSAGE FROM CLIENT" << endl;
   srvI->cbVar->call_back(pd_mesg);
  }
  catch (...) {
   cerr << endl << "CB_SERVER: LOST CLIENT!" << endl;
            break;
  }

  }
  }
  catch(...) {
    cerr << endl << "CB_SERVER: LOST CLIENT!" << endl;
  }
  cerr << endl << "CB_SERVER: THREAD EXITING" << endl;
  mu.lock();
  int do_signal = --num_active_servers == 0;
  mu.unlock();
  if( do_signal )  sigobj.signal();
}

//***************************************************
void insertArgs(int& argc, char**& argv, int idx, int nargs)
//**************************************************
{
 char** newArgv = new char*[argc+nargs];
 int i;
 for (i = 0; i < idx; i++) {
 newArgv[i] = argv[i];
 }
 for (i = idx; i < argc; i++) {
 newArgv[i+nargs] = argv[i];
 }
 argv = newArgv;
 argc += nargs;
}
//////////////////////////////////////////////////////////////////////
void server_i::call_Back(const char* mesg)
{
 cerr << endl << "CALL BACK FROM CLIENT: " << mesg << endl;
}

server_i::~server_i() {}

void
server_i::one_time(cb::CallBack_ptr cb, const char* mesg)
{
  if( CORBA::is_nil(cb) ) {
    cerr << endl << "RECEIVED A NIL CALLBACK REF" << endl;
    return;
  }
  cbVar =  cb::CallBack::_duplicate(cb);
  cerr << endl << "SERVER: REGISTER ITSELF ON CLIENT"  << endl;
  cbVar->_cxx_register(srv);
  cerr << endl << "SERVER : DOING A SINGLE CALLBACK: " << mesg << endl;
  cbVar->call_back("\nSERVER REGISTERED\n");
}

void
server_i::_cxx_register(cb::CallBack_ptr cb, const char* mesg,
        CORBA::UShort period_secs)
{
  if( CORBA::is_nil(cb) ) {
    cerr << endl << "RECEIVED A NIL CALLBACK REF" << endl;
    return;
  }
  mu.lock();
  num_active_servers++;
  mu.unlock();
  server_thread* server = new server_thread(this, cb, mesg, period_secs);
  server->start();
}

void
server_i::shutdown()
{
  omni_mutex_lock sync(mu);
  if( !dying ) {
    cerr << endl << "bd_server: I am being shutdown!" << endl;
    dying = 1;
    while( num_active_servers > 0 )  sigobj.wait();
    orb->shutdown(0);
  }
}
//////////////////////////////////////////////////////////////////////
int main(int argc, char** argv)
{
 try {
  int argc1=0;
  char ** argv1;
  insertArgs(argc1, argv1, 0, 20);
  argv1[0] = strdup("-ORBendPoint");
  argv1[1] = strdup("giop:tcp::3456");
  argv1[2] = strdup("-ORBclientTransportRule");
  argv1[3] = strdup("* unix,tcp,bidir");
  argv1[4] = strdup("-ORBserverTransportRule");
  argv1[5] = strdup("* unix,tcp,bidir");
  argv1[6] = strdup("-ORBofferBiDirectionalGIOP");
  argv1[7] = strdup("1");
  argv1[8] = strdup("-ORBacceptBiDirectionalGIOP");
  argv1[9] = strdup("1");
  argv1[10] = strdup("-ORBendPointPublishAllIFs");
  argv1[11] = strdup("1");
  argv1[12] = strdup("-ORBtraceLevel");
  argv1[13] = strdup("10");
  argv1[14] = strdup("-ORBoneCallPerConnection");
  argv1[15] = strdup("0");
  argv1[16] = strdup("-ORBclientCallTimeOutPeriod");
  argv1[17] = strdup("5000");
  argv1[18] = strdup("-ORBserverCallTimeOutPeriod");
  argv1[19] = strdup("5000" );

      orb = CORBA::ORB_init(argc1, argv1);

      CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
      PortableServer::POA_var rootpoa = PortableServer::POA::_narrow(obj);
      PortableServer::POAManager_var pman = rootpoa->the_POAManager();
      pman->activate();

      // Create a POA with the Bidirectional policy
      CORBA::PolicyList pl;
      pl.length(3);
      CORBA::Any a;
      a <<= BiDirPolicy::BOTH;
      pl[0] = orb->create_policy(BiDirPolicy::BIDIRECTIONAL_POLICY_TYPE, a);
      pl[1] = rootpoa->create_lifespan_policy(PortableServer::PERSISTENT);
      pl[2] = rootpoa->create_id_assignment_policy(PortableServer::USER_ID);

      PortableServer::POA_var poa = rootpoa->create_POA("bidir.persistent",
pman, pl);

      server_i* myserver = new server_i();
      PortableServer::ObjectId_var oid =
PortableServer::string_to_ObjectId("SERVERCLIENT");
   poa->activate_object_with_id(oid, myserver );
   myserver->srv = myserver->_this();
   myserver->_remove_ref();

   obj = myserver->_this();
      CORBA::String_var sior(orb->object_to_string(obj));
      cerr << endl <<  (char*) sior  << endl;
      orb->run();
      cerr << endl << "SERVER: RETURNED FROM orb->run()." << endl;
      orb->destroy();
  }
  catch(CORBA::SystemException&) {
    cerr << endl << "Caught CORBA::SystemException." << endl;
  }
  catch(CORBA::Exception&) {
    cerr << endl << "Caught CORBA::Exception." << endl;
  }
  catch(omniORB::fatalException& fe) {
    cerr << endl << "Caught omniORB::fatalException:" << endl;
    cerr << endl << "  file: " << fe.file() << endl;
    cerr << endl << "  line: " << fe.line() << endl;
    cerr << endl << "  mesg: " << fe.errmsg() << endl;
  }
  catch(...) {
    cerr << endl << "Caught unknown exception." << endl;
  }
  return 0;
}