Preston, Ralph A.
2008-10-08 03:28:55 UTC
Hello,
I've created a simple client/server app to transfer large files and am
having trouble with it locking up. It will run for a while then
abruptly stop. The problem occurs when running in Cygwin/Windows XP
often between 40 and 200 iterations. I've tested various combinations
of Linux vs. Cygwin and local vs. remote server. The problem occurs
only when the client is running in Cygwin, I've let it run up to 170K
iterations in Linux without a problem. The location of the server
(local/remote/Linux/Cygwin) doesn't seem to matter. I'm using the
latest version of Cygwin, XP and gcc version 3.4.4 (cygming special,
gdc 0.12, using dmd 0.125)
The lockup always occurs during the call to ::recv in
src/lib/omniORB/orbcore/tcp/tcpConnection::Recv(...). It seems as if
the ::recv blocks and is never unblocked, judging by print statements
inserted before and after the ::recv call.
Any suggestions for debugging are very welcome. Following is more
detailed information about the threads and source code.
I've examined the running threads before and after a lockup. When I
set a breakpoint on tcpConnection.cc:422 (the ::recv call) and view the
threads, there are 5 threads. However there are six when I ^C after
they client blocks. Comparing the stack trace between the threads
before and after the lockup shows two differences, thread 1 and thread
6 (which didn't exist at my breakpoint.) Following are the stack traces
for thread 1 and 6.
Thread 1 during breakpoint:
(gdb) bt
#0 omni::tcpConnection::Recv (this=0x106d9ed4, buf=0x7fc05384,
sz=1875076,
deadline_secs=0, deadline_nanosecs=0) at ./tcp/tcpConnection.cc:422
#1 0x10070685 in omni::giopStream::inputCopyChunk (this=0x106d7dfc,
dest=0x7fbd1fe8, size=1875076) at giopStream.cc:1089
#2 0x10089c0c in omni::giopImpl12::copyInputData (g=0x106d7dfc,
b=0x7fbd1fe8, sz=2084896, align=ALIGN_4) at giopImpl12.cc:1313
#3 0x1006ef76 in omni::giopStream::get_octet_array (this=0x106d7dfc,
b=0x7fbd0008 "\001", size=2093056, align=ALIGN_4) at
giopStream.cc:586
#4 0x004194db in _CORBA_Unbounded_Sequence_w_FixSizeElement<unsigned
long, 4, 4
at /usr/local/include/omniORB4/seqTemplatedefns.h:189
#5 0x00402dcd in
_0RL_cd_18b75a56e194476b_00000000::unmarshalReturnedValues (
this=0x22ca70, _n=@0x106d7dfc) at BigTestSK.cpp:167
#6 0x10056ad8 in omniRemoteIdentity::dispatch (this=0x106d7ca8,
call_desc=@0x22ca70) at remoteIdentity.cc:187
#7 0x100355ea in omniObjRef::_invoke (this=0x106d7ac0,
call_desc=@0x22ca70,
do_assert=true) at omniObjRef.cc:779
#8 0x00402eff in BT::_objref_Bigtest::Read (this=0x106d7ab0,
size=523264,
outdata=0x22cbf0) at BigTestSK.cpp:187
#9 0x004019e3 in main (argc=1, argv=0x106cf778) at BigRx.cpp:87
Thread 1 after lockup:
#0 0x7c90e4f4 in ntdll!LdrAccessResource ()
from /cygdrive/c/WINDOWS/system32/ntdll.dll
#1 0x7c90df2c in ntdll!ZwWaitForMultipleObjects ()
from /cygdrive/c/WINDOWS/system32/ntdll.dll
#2 0x7c809574 in KERNEL32!CreateFileMappingA ()
from /cygdrive/c/WINDOWS/system32/kernel32.dll
#3 0x6103d770 in fhandler_socket::wait () from /usr/bin/cygwin1.dll
#4 0x00000002 in ?? ()
#5 0x0022c368 in ?? ()
#6 0x00000000 in ?? ()
Thread 6 after lockup:
#0 0x7c87635d in KERNEL32!GetConsoleCharType ()
from /cygdrive/c/WINDOWS/system32/kernel32.dll
#1 0x0154ce64 in ?? ()
#2 0x00000000 in ?? ()
Following is the source code, sorry there is so much but I wanted to
include everything necessary to reproduce the error, should anyone wish
to help (but you must supply your own name service.) Hopefully it's
something ridiculously simple that I've overlooked. BigRx.cpp is the
client application, BigTest.cpp is the server. Any help is
appreciated, thanks!
<BigTest.idl>
#ifndef _BIGTEST_IDL_
#define _BIGTEST_IDL_
#pragma prefix "blah.com"
module BT {
interface Bigtest {
typedef sequence<unsigned long> Data;
long Read ( in long size, out Data outdata );
};
};
#endif
</BigTest.idl>
<BigRx.cpp>
#include <BigTest.hh>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <fstream>
#include <vector>
using namespace std;
const int READ_SIZE = (1024*512)-1024;
int
main ( int argc, char* argv[] )
{
unsigned long _incoming_length;
int len = 0;
unsigned long cnt = 0;
CosNaming::NamingContext_var rootContext;
CosNaming::Name service_name;
service_name.length(3);
service_name[0].id = CORBA::string_dup("Test");
service_name[0].kind = CORBA::string_dup("");
service_name[1].id = CORBA::string_dup("BigTest");
service_name[1].kind = CORBA::string_dup("");
service_name[2].id = CORBA::string_dup("BigTest");
service_name[2].kind = CORBA::string_dup("");
CORBA::ORB_var _orb = CORBA::ORB_init(argc, argv);
bool res = true;
try {
// Obtain a reference to the root context of the Name service:
CORBA::Object_var obj;
obj = _orb->resolve_initial_references("NameService");
// Narrow the reference returned.
rootContext = CosNaming::NamingContext::_narrow(obj);
if( CORBA::is_nil(rootContext) ) {
cerr << "Failed to narrow the root naming context." << endl;
res = false;
}
}
catch (CORBA::NO_RESOURCES&) {
cerr << "NameServiceClient Caught NO_RESOURCES exception." << endl;
res = false;
}
catch (CORBA::ORB::InvalidName&) {
// This should not happen!
cerr << "NameService is required [does not exist]." << endl;
res = false;
}
CORBA::Object_var obj;
obj = rootContext->resolve(service_name);
BT::Bigtest_var controller = BT::Bigtest::_narrow(obj);
if( CORBA::is_nil(controller) ) {
cerr << "ERROR Bigtest failed to narrow Controller." << endl;
return -1;
}
if(CORBA::is_nil(controller)) {
cerr << "ERROR Bigtest failed to find controller" << endl;
return -1;
}
for(unsigned int loopcnt=0; loopcnt < 1000000; loopcnt++) {
cout << "\nIteration " << loopcnt << endl;
try {
len = 0;
cnt = 0;
do {
BT::Bigtest::Data* tmpdata;
CORBA::Long s = READ_SIZE;
cout << "++ Calling controller->Read() for index " << cnt
<< ", size of " << s << endl;
int retry = 0;
do {
try {
len = controller->Read(READ_SIZE, tmpdata);
}
catch (CORBA::COMM_FAILURE& e) {
cout << "EXCEPTION CORBA::COMM_FAILURE" << endl;
retry++;
len = 0;
}
catch (CORBA::UserException& e) {
cout << "EXCEPTION CORBA::UserException" << endl;
throw;
}
catch (CORBA::SystemException& e) {
cout << "EXCEPTION CORBA::SystemException" << endl;
throw;
}
} while(retry == 1);
cout << "++ Read " << len << " bytes" << endl;
if(len == 0) {
if(cnt < _incoming_length) {
cout << "ERROR BigTest read "
<< cnt << " bytes, expected " << _incoming_length
<< " bytes." << endl;
}
break; // out of do {} while() loop
}
vector<char>* que = new vector<char>(len);
if(que == NULL) {
cerr << "ERROR BigRx vector allocation failed" << endl;
throw CORBA::NO_MEMORY();
}
std::copy(tmpdata->get_buffer(), tmpdata->get_buffer()+len,
que->begin());
delete tmpdata;
cout << "que now has " << que->size() << " bytes" << endl;
delete que;
if(cnt == 0) {
cout << "Resetting incoming length to " << READ_SIZE << endl;
_incoming_length = READ_SIZE;
}
cnt += len;
} while(cnt < _incoming_length);
}
catch (...) {
cout << "\nEXCEPTION Bigtest \n" << endl;
throw;
}
}
sleep(10);
return 0;
}
</BigRx.cpp>
<BigTest_i.cpp>
//
// Example code for implementing IDL interfaces in file BigTest.idl
//
#include <iostream>
#include <BigTest.hh>
#include <NameServiceClient.hh>
using namespace std;
const string BIG_TEST_STR = "BigTest";
//
// Example class implementing IDL interface BT::Bigtest
//
class BT_Bigtest_i:
public NameServiceClient,
public POA_BT::Bigtest {
private:
// Make sure all instances are built on the heap by making the
// destructor non-public
//virtual ~BT_Bigtest_i();
public:
// standard constructor
BT_Bigtest_i(CORBA::ORB_ptr orb,
string registered_name = string(""));
virtual ~BT_Bigtest_i();
string GetServiceName ( void );
// methods corresponding to defined IDL attributes and operations
::CORBA::Long Read(::CORBA::Long size, BT::Bigtest::Data_out
outdata);
};
//
// Example implementational code for IDL interface BT::Bigtest
//
BT_Bigtest_i::BT_Bigtest_i(CORBA::ORB_ptr orb,
string registered_name)
: NameServiceClient( orb, BIG_TEST_STR )
{
cout << "BigTest Constructed" << endl;
// add extra constructor code here
}
BT_Bigtest_i::~BT_Bigtest_i(){
// add extra destructor code here
}
string
BT_Bigtest_i::GetServiceName ( void )
{
return BIG_TEST_STR;
}
// Methods corresponding to IDL attributes and operations
::CORBA::Long
BT_Bigtest_i::Read(::CORBA::Long size, BT::Bigtest::Data_out outdata)
{
unsigned int i = 0;
cout << "Read called for size " << size << endl;
outdata = new BT::Bigtest::Data();
outdata->length(size);
cout << " outdata->length set to " << outdata->length() << endl;
for(i=0; i<(unsigned int)size; i++) {
(*outdata)[i] = i+1;
}
cout << " Returning " << i << endl;
return i;
}
// End of example implementational code
int main(int argc, char** argv)
{
try {
// Initialise the ORB.
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
// Obtain a reference to the root POA.
CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
PortableServer::POA_var poa = PortableServer::POA::_narrow(obj);
// We allocate the objects on the heap. Since these are reference
// counted objects, they will be deleted by the POA when they are
no
// longer needed.
BT_Bigtest_i* myBT_Bigtest_i = new BT_Bigtest_i(orb);
// Activate the objects. This tells the POA that the objects are
// ready to accept requests.
PortableServer::ObjectId_var myBT_Bigtest_iid =
poa->activate_object(myBT_Bigtest_i);
if(!myBT_Bigtest_i->UpdateNameService(myBT_Bigtest_i->_this())) {
return -1;
}
myBT_Bigtest_i->_remove_ref();
// Obtain a POAManager, and tell the POA to start accepting
// requests on its objects.
PortableServer::POAManager_var pman = poa->the_POAManager();
pman->activate();
cout << "ORB running." << endl;
orb->run();
orb->destroy();
}
catch(CORBA::TRANSIENT&) {
cerr << "Caught system exception TRANSIENT -- unable to contact the
"
<< "server." << endl;
}
catch(CORBA::SystemException& ex) {
cerr << "Caught a CORBA::" << ex._name() << endl;
}
catch(CORBA::Exception& ex) {
cerr << "Caught CORBA::Exception: " << ex._name() << endl;
}
catch(omniORB::fatalException& fe) {
cerr << "Caught omniORB::fatalException:" << endl;
cerr << " file: " << fe.file() << endl;
cerr << " line: " << fe.line() << endl;
cerr << " mesg: " << fe.errmsg() << endl;
}
return 0;
}
</BigTest_i.cpp>
<Makefile>
IDL2CC = omniidl
IDLFLAGS = -bcxx -Wbh=.hh -Wbs=SK.cpp -Wbexample
OBJECTS = BigTestSK.cpp BigTest_i.cpp NameServiceClient.cpp
OSVER = $(shell uname)
.PHONY: all source obj bin clean install
all: idl BT RX
source: $(OBJECTS)
idl : BigTest.idl
$(IDL2CC) $(IDLFLAGS) BigTest.idl
ifeq (Linux, $(OSVER))
LDFLAGS +=
LIBLDFLAGS =
DEFINES += -D__OSVERSION__=2 -D__linux__
LIBS +=
else
LDFLAGS += -Wl,--enable-auto-import
LIBLDFLAGS = -Wl,--export-all-symbols -Wl,--out-implib=$(LIBRARY).dll.a
-Wl,--whole-archive
DEFINES += -D__OSVERSION__=1 -D__cygwin__
LIBS +=
endif
BT :
g++ -c -Wall -g -fexceptions -D__OMNIORB4__ -D_REENTRANT
$(DEFINES) -DUSE_LOCAL_TCHAR -I. -I.. NameServiceClient.cpp -o
NameServiceClient.o
g++ -c -Wall -g -fexceptions -D__OMNIORB4__ -D_REENTRANT
$(DEFINES) -DUSE_LOCAL_TCHAR -I. -I.. BigTestSK.cpp -o BigTestSK.o
g++ -c -Wall -g -fexceptions -D__OMNIORB4__ -D_REENTRANT
$(DEFINES) -DUSE_LOCAL_TCHAR -I. -I.. BigTest_i.cpp -o BigTest_i.o
g++ -Wall -Wno-unused -fexceptions $(LDFLAGS) -L.
-L/usr/local/lib BigTest_i.o BigTestSK.o NameServiceClient.o -o
BigTest.exe -lomniORB4 -lomnithread -lpthread -lomniDynamic4 $(LIBS)
RX :
g++ -c -Wall -g -fexceptions -D__OMNIORB4__ -D_REENTRANT
$(DEFINES) -DUSE_LOCAL_TCHAR -I. -I.. NameServiceClient.cpp -o
NameServiceClient.o
g++ -c -Wall -g -fexceptions -D__OMNIORB4__ -D_REENTRANT
$(DEFINES) -DUSE_LOCAL_TCHAR -I. -I.. BigTestSK.cpp -o BigTestSK.o
g++ -c -Wall -g -fexceptions -D__OMNIORB4__ -D_REENTRANT
$(DEFINES) -DUSE_LOCAL_TCHAR -I. -I.. BigRx.cpp -o BigRx.o
g++ -Wall -Wno-unused -fexceptions $(LDFLAGS) -L.
-L/usr/local/lib BigRx.o BigTestSK.o NameServiceClient.o -o BigRx.exe
-lomniORB4 -lomnithread -lpthread -lomniDynamic4 $(LIBS)
clean :
rm -f *~
</Makefile>
<NameServiceClient.hh>
#ifndef NAMESERVICECLIENT_H
#define NAMESERVICECLIENT_H 1
#include <string>
#include <omniORB4/CORBA.h>
#include <omniORB4/Naming.hh>
using namespace std;
const string NAME_ROOT_ID = "Test";
const string CONTEXT_STR = "";
const string OBJECT_STR = "";
class NameServiceClient {
public:
NameServiceClient( CORBA::ORB_ptr orb, string registered_name =
string("") );
virtual ~NameServiceClient() {};
CORBA::ORB_ptr _orb;
CosNaming::Name _name_root;
CosNaming::Name _bound_name;
string _hostname;
virtual string GetServiceName ( void ) = 0;
bool RemoveNameService ( void );
bool UpdateNameService ( CORBA::Object_var obj );
private:
void _Init ( );
bool _GetRootContext ( CosNaming::NamingContext_var& rc );
};
#endif // NAMESERVICECLIENT_H
</NameServiceClient.hh>
<NameServiceClient.cpp>
#include <NameServiceClient.hh>
#include <iostream>
#include <unistd.h>
#include <sys/param.h>
NameServiceClient::NameServiceClient( CORBA::ORB_ptr orb,
string registered_name )
: _orb(orb),
_hostname(registered_name)
{
_Init();
return;
}
void
NameServiceClient::_Init ( void )
{
char name[MAXHOSTNAMELEN];
if(_hostname == string("")) {
if(gethostname(name, sizeof(name)) != 0) {
cerr << "ERROR NameServiceClient can't get
hostname" << endl;
exit(-1);
}
_hostname = name;
}
string id, kind;
id = NAME_ROOT_ID;
kind = CONTEXT_STR;
_name_root.length(1);
_name_root[0].id = CORBA::string_dup(id.c_str());
_name_root[0].kind = CORBA::string_dup(kind.c_str());
}
bool
NameServiceClient::RemoveNameService ( void )
{
CosNaming::NamingContext_var rootContext;
try {
// Obtain a reference to the root context of the Name service:
CORBA::Object_var nsobj;
nsobj = _orb->resolve_initial_references("NameService");
// Narrow the reference returned.
rootContext = CosNaming::NamingContext::_narrow(nsobj);
if( CORBA::is_nil(rootContext) ) {
cerr << "Failed to narrow the root naming context." << endl;
return false;
}
}
catch (CORBA::NO_RESOURCES&) {
cerr << "NameServiceClient Caught NO_RESOURCES exception."
<< " You must configure omniORB"
<< " with the location"
<< " of the naming service." << endl;
return false;
}
catch (CORBA::ORB::InvalidName&) {
// This should not happen!
cerr << "NameService is required [does not exist]." << endl;
return false;
}
try {
// Get "Test.Context"
CosNaming::Name testContextName;
testContextName.length(1);
testContextName[0].id = CORBA::string_dup(_bound_name[0].id);
testContextName[0].kind = CORBA::string_dup(_bound_name[0].kind);
CORBA::Object_var root;
CosNaming::NamingContext_var testContext;
root = rootContext->resolve(testContextName);
testContext = CosNaming::NamingContext::_narrow(root);
if( CORBA::is_nil(testContext) ) {
cerr << "Failed to narrow naming context." << endl;
return false;
}
CosNaming::Name serviceContextName;
serviceContextName.length(1);
serviceContextName[0].id = CORBA::string_dup(_bound_name[1].id);
serviceContextName[0].kind =
CORBA::string_dup(_bound_name[1].kind);
CORBA::Object_var service;
CosNaming::NamingContext_var serviceContext;
service = testContext->resolve(serviceContextName);
serviceContext = CosNaming::NamingContext::_narrow(service);
if( CORBA::is_nil(serviceContext) ) {
cerr << "Failed to narrow naming context." << endl;
return false;
}
CosNaming::Name objectName;
objectName.length(1);
objectName[0].id = CORBA::string_dup(_bound_name[2].id);
objectName[0].kind = CORBA::string_dup(_bound_name[2].kind);
cout << "Removing " << _bound_name[0].id;
cout << "/" << _bound_name[1].id;
cout << "/" << _bound_name[2].id;
cout << " from NameServer" << endl;
// Unbind the objectName
try {
serviceContext->unbind(objectName);
}
catch(CosNaming::NamingContext::NotFound& ex) {
cerr << "NameServiceClient objectName not found" << endl;
return false;
}
catch(CosNaming::NamingContext::CannotProceed& ex) {
cerr << "NameServiceClient cannot proceed" << endl;
return false;
}
catch(CosNaming::NamingContext::InvalidName& ex) {
cerr << "NameServiceClient invalid name" << endl;
return false;
}
// Destroy the hostname.Object
try {
serviceContext->destroy();
}
catch(CosNaming::NamingContext::NotEmpty& ex) {
return true;
}
try {
testContext->unbind(serviceContextName);
}
catch(CosNaming::NamingContext::NotFound& ex) {
cerr << "NameServiceClient serviceContextName not found" << endl;
return false;
}
catch(CosNaming::NamingContext::CannotProceed& ex) {
cerr << "NameServiceClient cannot proceed" << endl;
return false;
}
catch(CosNaming::NamingContext::InvalidName& ex) {
cerr << "NameServiceClient invalid name" << endl;
return false;
}
try {
testContext->destroy();
}
catch(CosNaming::NamingContext::NotEmpty& ex) {
return true;
}
try {
rootContext->unbind(testContextName);
}
catch(CosNaming::NamingContext::NotFound& ex) {
cerr << "NameServiceClient testContextName not found" << endl;
return false;
}
catch(CosNaming::NamingContext::CannotProceed& ex) {
cerr << "NameServiceClient cannot proceed" << endl;
return false;
}
catch(CosNaming::NamingContext::InvalidName& ex) {
cerr << "NameServiceClient invalid name" << endl;
return false;
}
}
catch(CORBA::TRANSIENT& ex) {
cerr << "NameServiceClient Caught system exception TRANSIENT"
<< " -- unable to contact the naming service." << endl
<< "Make sure the naming server is running and that omniORB is
"
<< "configured correctly." << endl;
return false;
}
catch(CORBA::SystemException& ex) {
cerr << "NameServiceClient Caught a CORBA::" << ex._name()
<< " while using the naming service." << endl;
return false;
}
return true;
}
bool
NameServiceClient::UpdateNameService ( CORBA::Object_var obj )
{
CosNaming::NamingContext_var rootContext;
_bound_name.length(3);
_bound_name[0].id = CORBA::string_dup(_name_root[0].id);
_bound_name[0].kind = CORBA::string_dup(_name_root[0].kind);
_bound_name[1].id = CORBA::string_dup(GetServiceName().c_str());
_bound_name[1].kind = CORBA::string_dup(CONTEXT_STR.c_str());
_bound_name[2].id = CORBA::string_dup(_hostname.c_str());
_bound_name[2].kind = CORBA::string_dup(OBJECT_STR.c_str());
try {
// Obtain a reference to the root context of the Name service:
CORBA::Object_var nsobj;
nsobj = _orb->resolve_initial_references("NameService");
// Narrow the reference returned.
rootContext = CosNaming::NamingContext::_narrow(nsobj);
if( CORBA::is_nil(rootContext) ) {
cerr << "Failed to narrow the root naming context." << endl;
return false;
}
}
catch (CORBA::NO_RESOURCES&) {
cerr << "NameServiceClient Caught NO_RESOURCES exception."
<< " You must configure omniORB with the location"
<< " of the naming service." << endl;
return false;
}
catch (CORBA::ORB::InvalidName&) {
// This should not happen!
cerr << "NameService is required." << endl;
return false;
}
try {
// Bind a context called "Test" to the root context:
CosNaming::Name testContextName;
testContextName.length(1);
testContextName[0].id = CORBA::string_dup(_bound_name[0].id);
testContextName[0].kind = CORBA::string_dup(_bound_name[0].kind);
CosNaming::NamingContext_var testContext;
try {
// Bind the context to root.
testContext = rootContext->bind_new_context(testContextName);
}
catch(CosNaming::NamingContext::AlreadyBound& ex) {
// If the context already exists, this exception will be raised.
// In this case, just resolve the name and assign testContext
// to the object returned:
CORBA::Object_var obj;
obj = rootContext->resolve(testContextName);
testContext = CosNaming::NamingContext::_narrow(obj);
if( CORBA::is_nil(testContext) ) {
cerr << "Failed to narrow naming context." << endl;
return false;
}
}
CosNaming::Name serviceContextName;
serviceContextName.length(1);
serviceContextName[0].id = CORBA::string_dup(_bound_name[1].id);
serviceContextName[0].kind =
CORBA::string_dup(_bound_name[1].kind);
CosNaming::NamingContext_var serviceContext;
try {
serviceContext =
testContext->bind_new_context(serviceContextName);
}
catch(CosNaming::NamingContext::AlreadyBound& ex) {
// If the context already exists, this exception will be raised.
// In this case, just resolve the name and assign testContext
// to the object returned:
CORBA::Object_var serviceobj;
serviceobj = testContext->resolve(serviceContextName);
serviceContext = CosNaming::NamingContext::_narrow(serviceobj);
if( CORBA::is_nil(serviceContext) ) {
cerr << "Failed to narrow naming context." << endl;
return false;
}
}
CosNaming::Name objectName;
objectName.length(1);
objectName[0].id = CORBA::string_dup(_bound_name[2].id);
objectName[0].kind = CORBA::string_dup(_bound_name[2].kind);
try {
serviceContext->bind(objectName, obj);
}
catch(CosNaming::NamingContext::AlreadyBound& ex) {
serviceContext->rebind(objectName, obj);
}
// Note: Using rebind() will overwrite any Object previously bound
// to /test/Echo with obj.
// Alternatively, bind() can be used, which will raise a
// CosNaming::NamingContext::AlreadyBound exception if the
name
// supplied is already bound to an object.
// Amendment: When using OrbixNames, it is necessary to first try
bind
// and then rebind, as rebind on it's own will throw a
NotFoundexception if
// the Name has not already been bound. [This is incorrect
behaviour -
// it should just bind].
}
catch(CORBA::TRANSIENT& ex) {
cerr << "NameServiceClient Caught system exception TRANSIENT"
<< " -- unable to contact the "
<< "naming service." << endl
<< "Make sure the naming server is running and that omniORB is
"
<< "configured correctly." << endl;
return false;
}
catch(CORBA::SystemException& ex) {
cerr << "NameServiceClient Caught a CORBA::" << ex._name()
<< " while using the naming service." << endl;
return false;
}
return true;
}
bool
NameServiceClient::_GetRootContext ( CosNaming::NamingContext_var& rc )
{
bool res = true;
try {
// Obtain a reference to the root context of the Name service:
CORBA::Object_var obj;
obj = _orb->resolve_initial_references("NameService");
// Narrow the reference returned.
rc = CosNaming::NamingContext::_narrow(obj);
if( CORBA::is_nil(rc) ) {
cerr << "Failed to narrow the root naming context." << endl;
res = false;
}
}
catch (CORBA::NO_RESOURCES&) {
cerr << "NameServiceClient Caught NO_RESOURCES exception."
<< " You must configure omniORB"
<< " with the location"
<< " of the naming service." << endl;
res = false;
}
catch (CORBA::ORB::InvalidName&) {
// This should not happen!
cerr << "NameService is required [does not exist]." << endl;
res = false;
}
return res;
}
</NameServiceClient.cpp>
Ralph A. Preston
The MITRE Corporation
202 Burlington Road, MS E095
Bedford, MA 01730
Office: 781-271-7914 Fax: 781-271-8915
I've created a simple client/server app to transfer large files and am
having trouble with it locking up. It will run for a while then
abruptly stop. The problem occurs when running in Cygwin/Windows XP
often between 40 and 200 iterations. I've tested various combinations
of Linux vs. Cygwin and local vs. remote server. The problem occurs
only when the client is running in Cygwin, I've let it run up to 170K
iterations in Linux without a problem. The location of the server
(local/remote/Linux/Cygwin) doesn't seem to matter. I'm using the
latest version of Cygwin, XP and gcc version 3.4.4 (cygming special,
gdc 0.12, using dmd 0.125)
The lockup always occurs during the call to ::recv in
src/lib/omniORB/orbcore/tcp/tcpConnection::Recv(...). It seems as if
the ::recv blocks and is never unblocked, judging by print statements
inserted before and after the ::recv call.
Any suggestions for debugging are very welcome. Following is more
detailed information about the threads and source code.
I've examined the running threads before and after a lockup. When I
set a breakpoint on tcpConnection.cc:422 (the ::recv call) and view the
threads, there are 5 threads. However there are six when I ^C after
they client blocks. Comparing the stack trace between the threads
before and after the lockup shows two differences, thread 1 and thread
6 (which didn't exist at my breakpoint.) Following are the stack traces
for thread 1 and 6.
Thread 1 during breakpoint:
(gdb) bt
#0 omni::tcpConnection::Recv (this=0x106d9ed4, buf=0x7fc05384,
sz=1875076,
deadline_secs=0, deadline_nanosecs=0) at ./tcp/tcpConnection.cc:422
#1 0x10070685 in omni::giopStream::inputCopyChunk (this=0x106d7dfc,
dest=0x7fbd1fe8, size=1875076) at giopStream.cc:1089
#2 0x10089c0c in omni::giopImpl12::copyInputData (g=0x106d7dfc,
b=0x7fbd1fe8, sz=2084896, align=ALIGN_4) at giopImpl12.cc:1313
#3 0x1006ef76 in omni::giopStream::get_octet_array (this=0x106d7dfc,
b=0x7fbd0008 "\001", size=2093056, align=ALIGN_4) at
giopStream.cc:586
#4 0x004194db in _CORBA_Unbounded_Sequence_w_FixSizeElement<unsigned
long, 4, 4
at /usr/local/include/omniORB4/seqTemplatedefns.h:189
#5 0x00402dcd in
_0RL_cd_18b75a56e194476b_00000000::unmarshalReturnedValues (
this=0x22ca70, _n=@0x106d7dfc) at BigTestSK.cpp:167
#6 0x10056ad8 in omniRemoteIdentity::dispatch (this=0x106d7ca8,
call_desc=@0x22ca70) at remoteIdentity.cc:187
#7 0x100355ea in omniObjRef::_invoke (this=0x106d7ac0,
call_desc=@0x22ca70,
do_assert=true) at omniObjRef.cc:779
#8 0x00402eff in BT::_objref_Bigtest::Read (this=0x106d7ab0,
size=523264,
outdata=0x22cbf0) at BigTestSK.cpp:187
#9 0x004019e3 in main (argc=1, argv=0x106cf778) at BigRx.cpp:87
Thread 1 after lockup:
#0 0x7c90e4f4 in ntdll!LdrAccessResource ()
from /cygdrive/c/WINDOWS/system32/ntdll.dll
#1 0x7c90df2c in ntdll!ZwWaitForMultipleObjects ()
from /cygdrive/c/WINDOWS/system32/ntdll.dll
#2 0x7c809574 in KERNEL32!CreateFileMappingA ()
from /cygdrive/c/WINDOWS/system32/kernel32.dll
#3 0x6103d770 in fhandler_socket::wait () from /usr/bin/cygwin1.dll
#4 0x00000002 in ?? ()
#5 0x0022c368 in ?? ()
#6 0x00000000 in ?? ()
Thread 6 after lockup:
#0 0x7c87635d in KERNEL32!GetConsoleCharType ()
from /cygdrive/c/WINDOWS/system32/kernel32.dll
#1 0x0154ce64 in ?? ()
#2 0x00000000 in ?? ()
Following is the source code, sorry there is so much but I wanted to
include everything necessary to reproduce the error, should anyone wish
to help (but you must supply your own name service.) Hopefully it's
something ridiculously simple that I've overlooked. BigRx.cpp is the
client application, BigTest.cpp is the server. Any help is
appreciated, thanks!
<BigTest.idl>
#ifndef _BIGTEST_IDL_
#define _BIGTEST_IDL_
#pragma prefix "blah.com"
module BT {
interface Bigtest {
typedef sequence<unsigned long> Data;
long Read ( in long size, out Data outdata );
};
};
#endif
</BigTest.idl>
<BigRx.cpp>
#include <BigTest.hh>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <fstream>
#include <vector>
using namespace std;
const int READ_SIZE = (1024*512)-1024;
int
main ( int argc, char* argv[] )
{
unsigned long _incoming_length;
int len = 0;
unsigned long cnt = 0;
CosNaming::NamingContext_var rootContext;
CosNaming::Name service_name;
service_name.length(3);
service_name[0].id = CORBA::string_dup("Test");
service_name[0].kind = CORBA::string_dup("");
service_name[1].id = CORBA::string_dup("BigTest");
service_name[1].kind = CORBA::string_dup("");
service_name[2].id = CORBA::string_dup("BigTest");
service_name[2].kind = CORBA::string_dup("");
CORBA::ORB_var _orb = CORBA::ORB_init(argc, argv);
bool res = true;
try {
// Obtain a reference to the root context of the Name service:
CORBA::Object_var obj;
obj = _orb->resolve_initial_references("NameService");
// Narrow the reference returned.
rootContext = CosNaming::NamingContext::_narrow(obj);
if( CORBA::is_nil(rootContext) ) {
cerr << "Failed to narrow the root naming context." << endl;
res = false;
}
}
catch (CORBA::NO_RESOURCES&) {
cerr << "NameServiceClient Caught NO_RESOURCES exception." << endl;
res = false;
}
catch (CORBA::ORB::InvalidName&) {
// This should not happen!
cerr << "NameService is required [does not exist]." << endl;
res = false;
}
CORBA::Object_var obj;
obj = rootContext->resolve(service_name);
BT::Bigtest_var controller = BT::Bigtest::_narrow(obj);
if( CORBA::is_nil(controller) ) {
cerr << "ERROR Bigtest failed to narrow Controller." << endl;
return -1;
}
if(CORBA::is_nil(controller)) {
cerr << "ERROR Bigtest failed to find controller" << endl;
return -1;
}
for(unsigned int loopcnt=0; loopcnt < 1000000; loopcnt++) {
cout << "\nIteration " << loopcnt << endl;
try {
len = 0;
cnt = 0;
do {
BT::Bigtest::Data* tmpdata;
CORBA::Long s = READ_SIZE;
cout << "++ Calling controller->Read() for index " << cnt
<< ", size of " << s << endl;
int retry = 0;
do {
try {
len = controller->Read(READ_SIZE, tmpdata);
}
catch (CORBA::COMM_FAILURE& e) {
cout << "EXCEPTION CORBA::COMM_FAILURE" << endl;
retry++;
len = 0;
}
catch (CORBA::UserException& e) {
cout << "EXCEPTION CORBA::UserException" << endl;
throw;
}
catch (CORBA::SystemException& e) {
cout << "EXCEPTION CORBA::SystemException" << endl;
throw;
}
} while(retry == 1);
cout << "++ Read " << len << " bytes" << endl;
if(len == 0) {
if(cnt < _incoming_length) {
cout << "ERROR BigTest read "
<< cnt << " bytes, expected " << _incoming_length
<< " bytes." << endl;
}
break; // out of do {} while() loop
}
vector<char>* que = new vector<char>(len);
if(que == NULL) {
cerr << "ERROR BigRx vector allocation failed" << endl;
throw CORBA::NO_MEMORY();
}
std::copy(tmpdata->get_buffer(), tmpdata->get_buffer()+len,
que->begin());
delete tmpdata;
cout << "que now has " << que->size() << " bytes" << endl;
delete que;
if(cnt == 0) {
cout << "Resetting incoming length to " << READ_SIZE << endl;
_incoming_length = READ_SIZE;
}
cnt += len;
} while(cnt < _incoming_length);
}
catch (...) {
cout << "\nEXCEPTION Bigtest \n" << endl;
throw;
}
}
sleep(10);
return 0;
}
</BigRx.cpp>
<BigTest_i.cpp>
//
// Example code for implementing IDL interfaces in file BigTest.idl
//
#include <iostream>
#include <BigTest.hh>
#include <NameServiceClient.hh>
using namespace std;
const string BIG_TEST_STR = "BigTest";
//
// Example class implementing IDL interface BT::Bigtest
//
class BT_Bigtest_i:
public NameServiceClient,
public POA_BT::Bigtest {
private:
// Make sure all instances are built on the heap by making the
// destructor non-public
//virtual ~BT_Bigtest_i();
public:
// standard constructor
BT_Bigtest_i(CORBA::ORB_ptr orb,
string registered_name = string(""));
virtual ~BT_Bigtest_i();
string GetServiceName ( void );
// methods corresponding to defined IDL attributes and operations
::CORBA::Long Read(::CORBA::Long size, BT::Bigtest::Data_out
outdata);
};
//
// Example implementational code for IDL interface BT::Bigtest
//
BT_Bigtest_i::BT_Bigtest_i(CORBA::ORB_ptr orb,
string registered_name)
: NameServiceClient( orb, BIG_TEST_STR )
{
cout << "BigTest Constructed" << endl;
// add extra constructor code here
}
BT_Bigtest_i::~BT_Bigtest_i(){
// add extra destructor code here
}
string
BT_Bigtest_i::GetServiceName ( void )
{
return BIG_TEST_STR;
}
// Methods corresponding to IDL attributes and operations
::CORBA::Long
BT_Bigtest_i::Read(::CORBA::Long size, BT::Bigtest::Data_out outdata)
{
unsigned int i = 0;
cout << "Read called for size " << size << endl;
outdata = new BT::Bigtest::Data();
outdata->length(size);
cout << " outdata->length set to " << outdata->length() << endl;
for(i=0; i<(unsigned int)size; i++) {
(*outdata)[i] = i+1;
}
cout << " Returning " << i << endl;
return i;
}
// End of example implementational code
int main(int argc, char** argv)
{
try {
// Initialise the ORB.
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
// Obtain a reference to the root POA.
CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
PortableServer::POA_var poa = PortableServer::POA::_narrow(obj);
// We allocate the objects on the heap. Since these are reference
// counted objects, they will be deleted by the POA when they are
no
// longer needed.
BT_Bigtest_i* myBT_Bigtest_i = new BT_Bigtest_i(orb);
// Activate the objects. This tells the POA that the objects are
// ready to accept requests.
PortableServer::ObjectId_var myBT_Bigtest_iid =
poa->activate_object(myBT_Bigtest_i);
if(!myBT_Bigtest_i->UpdateNameService(myBT_Bigtest_i->_this())) {
return -1;
}
myBT_Bigtest_i->_remove_ref();
// Obtain a POAManager, and tell the POA to start accepting
// requests on its objects.
PortableServer::POAManager_var pman = poa->the_POAManager();
pman->activate();
cout << "ORB running." << endl;
orb->run();
orb->destroy();
}
catch(CORBA::TRANSIENT&) {
cerr << "Caught system exception TRANSIENT -- unable to contact the
"
<< "server." << endl;
}
catch(CORBA::SystemException& ex) {
cerr << "Caught a CORBA::" << ex._name() << endl;
}
catch(CORBA::Exception& ex) {
cerr << "Caught CORBA::Exception: " << ex._name() << endl;
}
catch(omniORB::fatalException& fe) {
cerr << "Caught omniORB::fatalException:" << endl;
cerr << " file: " << fe.file() << endl;
cerr << " line: " << fe.line() << endl;
cerr << " mesg: " << fe.errmsg() << endl;
}
return 0;
}
</BigTest_i.cpp>
<Makefile>
IDL2CC = omniidl
IDLFLAGS = -bcxx -Wbh=.hh -Wbs=SK.cpp -Wbexample
OBJECTS = BigTestSK.cpp BigTest_i.cpp NameServiceClient.cpp
OSVER = $(shell uname)
.PHONY: all source obj bin clean install
all: idl BT RX
source: $(OBJECTS)
idl : BigTest.idl
$(IDL2CC) $(IDLFLAGS) BigTest.idl
ifeq (Linux, $(OSVER))
LDFLAGS +=
LIBLDFLAGS =
DEFINES += -D__OSVERSION__=2 -D__linux__
LIBS +=
else
LDFLAGS += -Wl,--enable-auto-import
LIBLDFLAGS = -Wl,--export-all-symbols -Wl,--out-implib=$(LIBRARY).dll.a
-Wl,--whole-archive
DEFINES += -D__OSVERSION__=1 -D__cygwin__
LIBS +=
endif
BT :
g++ -c -Wall -g -fexceptions -D__OMNIORB4__ -D_REENTRANT
$(DEFINES) -DUSE_LOCAL_TCHAR -I. -I.. NameServiceClient.cpp -o
NameServiceClient.o
g++ -c -Wall -g -fexceptions -D__OMNIORB4__ -D_REENTRANT
$(DEFINES) -DUSE_LOCAL_TCHAR -I. -I.. BigTestSK.cpp -o BigTestSK.o
g++ -c -Wall -g -fexceptions -D__OMNIORB4__ -D_REENTRANT
$(DEFINES) -DUSE_LOCAL_TCHAR -I. -I.. BigTest_i.cpp -o BigTest_i.o
g++ -Wall -Wno-unused -fexceptions $(LDFLAGS) -L.
-L/usr/local/lib BigTest_i.o BigTestSK.o NameServiceClient.o -o
BigTest.exe -lomniORB4 -lomnithread -lpthread -lomniDynamic4 $(LIBS)
RX :
g++ -c -Wall -g -fexceptions -D__OMNIORB4__ -D_REENTRANT
$(DEFINES) -DUSE_LOCAL_TCHAR -I. -I.. NameServiceClient.cpp -o
NameServiceClient.o
g++ -c -Wall -g -fexceptions -D__OMNIORB4__ -D_REENTRANT
$(DEFINES) -DUSE_LOCAL_TCHAR -I. -I.. BigTestSK.cpp -o BigTestSK.o
g++ -c -Wall -g -fexceptions -D__OMNIORB4__ -D_REENTRANT
$(DEFINES) -DUSE_LOCAL_TCHAR -I. -I.. BigRx.cpp -o BigRx.o
g++ -Wall -Wno-unused -fexceptions $(LDFLAGS) -L.
-L/usr/local/lib BigRx.o BigTestSK.o NameServiceClient.o -o BigRx.exe
-lomniORB4 -lomnithread -lpthread -lomniDynamic4 $(LIBS)
clean :
rm -f *~
</Makefile>
<NameServiceClient.hh>
#ifndef NAMESERVICECLIENT_H
#define NAMESERVICECLIENT_H 1
#include <string>
#include <omniORB4/CORBA.h>
#include <omniORB4/Naming.hh>
using namespace std;
const string NAME_ROOT_ID = "Test";
const string CONTEXT_STR = "";
const string OBJECT_STR = "";
class NameServiceClient {
public:
NameServiceClient( CORBA::ORB_ptr orb, string registered_name =
string("") );
virtual ~NameServiceClient() {};
CORBA::ORB_ptr _orb;
CosNaming::Name _name_root;
CosNaming::Name _bound_name;
string _hostname;
virtual string GetServiceName ( void ) = 0;
bool RemoveNameService ( void );
bool UpdateNameService ( CORBA::Object_var obj );
private:
void _Init ( );
bool _GetRootContext ( CosNaming::NamingContext_var& rc );
};
#endif // NAMESERVICECLIENT_H
</NameServiceClient.hh>
<NameServiceClient.cpp>
#include <NameServiceClient.hh>
#include <iostream>
#include <unistd.h>
#include <sys/param.h>
NameServiceClient::NameServiceClient( CORBA::ORB_ptr orb,
string registered_name )
: _orb(orb),
_hostname(registered_name)
{
_Init();
return;
}
void
NameServiceClient::_Init ( void )
{
char name[MAXHOSTNAMELEN];
if(_hostname == string("")) {
if(gethostname(name, sizeof(name)) != 0) {
cerr << "ERROR NameServiceClient can't get
hostname" << endl;
exit(-1);
}
_hostname = name;
}
string id, kind;
id = NAME_ROOT_ID;
kind = CONTEXT_STR;
_name_root.length(1);
_name_root[0].id = CORBA::string_dup(id.c_str());
_name_root[0].kind = CORBA::string_dup(kind.c_str());
}
bool
NameServiceClient::RemoveNameService ( void )
{
CosNaming::NamingContext_var rootContext;
try {
// Obtain a reference to the root context of the Name service:
CORBA::Object_var nsobj;
nsobj = _orb->resolve_initial_references("NameService");
// Narrow the reference returned.
rootContext = CosNaming::NamingContext::_narrow(nsobj);
if( CORBA::is_nil(rootContext) ) {
cerr << "Failed to narrow the root naming context." << endl;
return false;
}
}
catch (CORBA::NO_RESOURCES&) {
cerr << "NameServiceClient Caught NO_RESOURCES exception."
<< " You must configure omniORB"
<< " with the location"
<< " of the naming service." << endl;
return false;
}
catch (CORBA::ORB::InvalidName&) {
// This should not happen!
cerr << "NameService is required [does not exist]." << endl;
return false;
}
try {
// Get "Test.Context"
CosNaming::Name testContextName;
testContextName.length(1);
testContextName[0].id = CORBA::string_dup(_bound_name[0].id);
testContextName[0].kind = CORBA::string_dup(_bound_name[0].kind);
CORBA::Object_var root;
CosNaming::NamingContext_var testContext;
root = rootContext->resolve(testContextName);
testContext = CosNaming::NamingContext::_narrow(root);
if( CORBA::is_nil(testContext) ) {
cerr << "Failed to narrow naming context." << endl;
return false;
}
CosNaming::Name serviceContextName;
serviceContextName.length(1);
serviceContextName[0].id = CORBA::string_dup(_bound_name[1].id);
serviceContextName[0].kind =
CORBA::string_dup(_bound_name[1].kind);
CORBA::Object_var service;
CosNaming::NamingContext_var serviceContext;
service = testContext->resolve(serviceContextName);
serviceContext = CosNaming::NamingContext::_narrow(service);
if( CORBA::is_nil(serviceContext) ) {
cerr << "Failed to narrow naming context." << endl;
return false;
}
CosNaming::Name objectName;
objectName.length(1);
objectName[0].id = CORBA::string_dup(_bound_name[2].id);
objectName[0].kind = CORBA::string_dup(_bound_name[2].kind);
cout << "Removing " << _bound_name[0].id;
cout << "/" << _bound_name[1].id;
cout << "/" << _bound_name[2].id;
cout << " from NameServer" << endl;
// Unbind the objectName
try {
serviceContext->unbind(objectName);
}
catch(CosNaming::NamingContext::NotFound& ex) {
cerr << "NameServiceClient objectName not found" << endl;
return false;
}
catch(CosNaming::NamingContext::CannotProceed& ex) {
cerr << "NameServiceClient cannot proceed" << endl;
return false;
}
catch(CosNaming::NamingContext::InvalidName& ex) {
cerr << "NameServiceClient invalid name" << endl;
return false;
}
// Destroy the hostname.Object
try {
serviceContext->destroy();
}
catch(CosNaming::NamingContext::NotEmpty& ex) {
return true;
}
try {
testContext->unbind(serviceContextName);
}
catch(CosNaming::NamingContext::NotFound& ex) {
cerr << "NameServiceClient serviceContextName not found" << endl;
return false;
}
catch(CosNaming::NamingContext::CannotProceed& ex) {
cerr << "NameServiceClient cannot proceed" << endl;
return false;
}
catch(CosNaming::NamingContext::InvalidName& ex) {
cerr << "NameServiceClient invalid name" << endl;
return false;
}
try {
testContext->destroy();
}
catch(CosNaming::NamingContext::NotEmpty& ex) {
return true;
}
try {
rootContext->unbind(testContextName);
}
catch(CosNaming::NamingContext::NotFound& ex) {
cerr << "NameServiceClient testContextName not found" << endl;
return false;
}
catch(CosNaming::NamingContext::CannotProceed& ex) {
cerr << "NameServiceClient cannot proceed" << endl;
return false;
}
catch(CosNaming::NamingContext::InvalidName& ex) {
cerr << "NameServiceClient invalid name" << endl;
return false;
}
}
catch(CORBA::TRANSIENT& ex) {
cerr << "NameServiceClient Caught system exception TRANSIENT"
<< " -- unable to contact the naming service." << endl
<< "Make sure the naming server is running and that omniORB is
"
<< "configured correctly." << endl;
return false;
}
catch(CORBA::SystemException& ex) {
cerr << "NameServiceClient Caught a CORBA::" << ex._name()
<< " while using the naming service." << endl;
return false;
}
return true;
}
bool
NameServiceClient::UpdateNameService ( CORBA::Object_var obj )
{
CosNaming::NamingContext_var rootContext;
_bound_name.length(3);
_bound_name[0].id = CORBA::string_dup(_name_root[0].id);
_bound_name[0].kind = CORBA::string_dup(_name_root[0].kind);
_bound_name[1].id = CORBA::string_dup(GetServiceName().c_str());
_bound_name[1].kind = CORBA::string_dup(CONTEXT_STR.c_str());
_bound_name[2].id = CORBA::string_dup(_hostname.c_str());
_bound_name[2].kind = CORBA::string_dup(OBJECT_STR.c_str());
try {
// Obtain a reference to the root context of the Name service:
CORBA::Object_var nsobj;
nsobj = _orb->resolve_initial_references("NameService");
// Narrow the reference returned.
rootContext = CosNaming::NamingContext::_narrow(nsobj);
if( CORBA::is_nil(rootContext) ) {
cerr << "Failed to narrow the root naming context." << endl;
return false;
}
}
catch (CORBA::NO_RESOURCES&) {
cerr << "NameServiceClient Caught NO_RESOURCES exception."
<< " You must configure omniORB with the location"
<< " of the naming service." << endl;
return false;
}
catch (CORBA::ORB::InvalidName&) {
// This should not happen!
cerr << "NameService is required." << endl;
return false;
}
try {
// Bind a context called "Test" to the root context:
CosNaming::Name testContextName;
testContextName.length(1);
testContextName[0].id = CORBA::string_dup(_bound_name[0].id);
testContextName[0].kind = CORBA::string_dup(_bound_name[0].kind);
CosNaming::NamingContext_var testContext;
try {
// Bind the context to root.
testContext = rootContext->bind_new_context(testContextName);
}
catch(CosNaming::NamingContext::AlreadyBound& ex) {
// If the context already exists, this exception will be raised.
// In this case, just resolve the name and assign testContext
// to the object returned:
CORBA::Object_var obj;
obj = rootContext->resolve(testContextName);
testContext = CosNaming::NamingContext::_narrow(obj);
if( CORBA::is_nil(testContext) ) {
cerr << "Failed to narrow naming context." << endl;
return false;
}
}
CosNaming::Name serviceContextName;
serviceContextName.length(1);
serviceContextName[0].id = CORBA::string_dup(_bound_name[1].id);
serviceContextName[0].kind =
CORBA::string_dup(_bound_name[1].kind);
CosNaming::NamingContext_var serviceContext;
try {
serviceContext =
testContext->bind_new_context(serviceContextName);
}
catch(CosNaming::NamingContext::AlreadyBound& ex) {
// If the context already exists, this exception will be raised.
// In this case, just resolve the name and assign testContext
// to the object returned:
CORBA::Object_var serviceobj;
serviceobj = testContext->resolve(serviceContextName);
serviceContext = CosNaming::NamingContext::_narrow(serviceobj);
if( CORBA::is_nil(serviceContext) ) {
cerr << "Failed to narrow naming context." << endl;
return false;
}
}
CosNaming::Name objectName;
objectName.length(1);
objectName[0].id = CORBA::string_dup(_bound_name[2].id);
objectName[0].kind = CORBA::string_dup(_bound_name[2].kind);
try {
serviceContext->bind(objectName, obj);
}
catch(CosNaming::NamingContext::AlreadyBound& ex) {
serviceContext->rebind(objectName, obj);
}
// Note: Using rebind() will overwrite any Object previously bound
// to /test/Echo with obj.
// Alternatively, bind() can be used, which will raise a
// CosNaming::NamingContext::AlreadyBound exception if the
name
// supplied is already bound to an object.
// Amendment: When using OrbixNames, it is necessary to first try
bind
// and then rebind, as rebind on it's own will throw a
NotFoundexception if
// the Name has not already been bound. [This is incorrect
behaviour -
// it should just bind].
}
catch(CORBA::TRANSIENT& ex) {
cerr << "NameServiceClient Caught system exception TRANSIENT"
<< " -- unable to contact the "
<< "naming service." << endl
<< "Make sure the naming server is running and that omniORB is
"
<< "configured correctly." << endl;
return false;
}
catch(CORBA::SystemException& ex) {
cerr << "NameServiceClient Caught a CORBA::" << ex._name()
<< " while using the naming service." << endl;
return false;
}
return true;
}
bool
NameServiceClient::_GetRootContext ( CosNaming::NamingContext_var& rc )
{
bool res = true;
try {
// Obtain a reference to the root context of the Name service:
CORBA::Object_var obj;
obj = _orb->resolve_initial_references("NameService");
// Narrow the reference returned.
rc = CosNaming::NamingContext::_narrow(obj);
if( CORBA::is_nil(rc) ) {
cerr << "Failed to narrow the root naming context." << endl;
res = false;
}
}
catch (CORBA::NO_RESOURCES&) {
cerr << "NameServiceClient Caught NO_RESOURCES exception."
<< " You must configure omniORB"
<< " with the location"
<< " of the naming service." << endl;
res = false;
}
catch (CORBA::ORB::InvalidName&) {
// This should not happen!
cerr << "NameService is required [does not exist]." << endl;
res = false;
}
return res;
}
</NameServiceClient.cpp>
Ralph A. Preston
The MITRE Corporation
202 Burlington Road, MS E095
Bedford, MA 01730
Office: 781-271-7914 Fax: 781-271-8915