📄 storable_naming_context.cpp
字号:
#include "Storable_Naming_Context.h"
#include "Bindings_Iterator_T.h"
// The following #pragma is needed to disable a warning that occurs
// in MSVC 6 due to the overly long debugging symbols generated for
// the ACE_Auto_Basic_Ptr<ACE_Hash_Map_Iterator_Ex<TAO_...> > template
// instance used by some of the methods in this file.
#ifdef _MSC_VER
# pragma warning(disable: 4786) /* identifier was truncated to '255'
characters in the browser
information */
#endif /* _MSC_VER */
#include "ace/Auto_Ptr.h"
#include "ace/OS_NS_stdio.h"
const char * TAO_Storable_Naming_Context::root_name_;
ACE_UINT32 TAO_Storable_Naming_Context::gcounter_;
TAO_Storable_Base * TAO_Storable_Naming_Context::gfl_;
int TAO_Storable_Naming_Context::redundant_;
ACE_RCSID (Naming,
Storable_Naming_Context,
"Storable_Naming_Context.cpp,v 1.10 2003/11/01 11:15:09 dhinton Exp")
int
TAO_Storable_Bindings_Map::unbind (const char *id,
const char *kind)
{
ACE_TRACE("unbind");
TAO_Persistent_ExtId name (id, kind);
return this->map_.unbind (name);
}
int
TAO_Storable_Bindings_Map::bind (const char *id,
const char *kind,
CORBA::Object_ptr obj,
CosNaming::BindingType type)
{
ACE_TRACE("bind");
return this->shared_bind (id, kind, obj, type, 0);
}
int
TAO_Storable_Bindings_Map::rebind (const char *id,
const char *kind,
CORBA::Object_ptr obj,
CosNaming::BindingType type)
{
ACE_TRACE("rebind");
return this->shared_bind (id, kind, obj, type, 1);
}
int
TAO_Storable_Bindings_Map::find (const char *id,
const char *kind,
CORBA::Object_ptr & obj,
CosNaming::BindingType &type)
{
ACE_TRACE("find");
TAO_Persistent_ExtId name (id, kind);
TAO_Persistent_IntId entry;
if (this->map_.find (name,
entry) != 0)
{
return -1;
}
else
{
ACE_DECLARE_NEW_CORBA_ENV;
obj = orb_->string_to_object (entry.ref_ ACE_ENV_ARG_PARAMETER);
ACE_CHECK_RETURN (-1);
type = entry.type_;
return 0;
}
}
TAO_Storable_Bindings_Map::TAO_Storable_Bindings_Map (size_t hash_table_size,
CORBA::ORB_ptr orb)
: map_ (hash_table_size),
orb_(CORBA::ORB::_duplicate (orb))
{
ACE_TRACE("TAO_Storable_Bindings_Map");
}
TAO_Storable_Bindings_Map::~TAO_Storable_Bindings_Map (void)
{
ACE_TRACE("~TAO_Storable_Bindings_Map");
}
TAO_Storable_Bindings_Map::HASH_MAP &
TAO_Storable_Bindings_Map::map (void)
{
ACE_TRACE("map");
return map_;
}
size_t
TAO_Storable_Bindings_Map::current_size (void)
{
ACE_TRACE("current_size");
return map_.current_size ();
}
size_t
TAO_Storable_Bindings_Map::total_size (void)
{
ACE_TRACE("total_size");
return map_.total_size ();
}
int
TAO_Storable_Bindings_Map::shared_bind (const char * id,
const char * kind,
CORBA::Object_ptr obj,
CosNaming::BindingType type,
int rebind)
{
ACE_TRACE("shared_bind");
TAO_Persistent_ExtId new_name (CORBA::string_dup(id), CORBA::string_dup(kind));
TAO_Persistent_IntId new_entry (orb_->object_to_string(obj), type);
TAO_Persistent_IntId old_entry;
if (rebind == 0)
{
// Do a normal bind.
return this->map_.bind (new_name, new_entry);
}
else
// Rebind.
{
// Check that types of old and new entries match.
if (this->map_.find (new_name,
old_entry) == 0
&& type != old_entry.type_)
return -2;
else
return this->map_.rebind (new_name, new_entry);
}
}
void TAO_Storable_Naming_Context::Write(TAO_Storable_Base& wrtr)
{
ACE_TRACE("Write");
TAO_NS_Persistence_Header header;
header.size (ACE_static_cast(unsigned int,
storable_context_->current_size()));
header.destroyed (destroyed_);
wrtr << header;
if( storable_context_->current_size() == 0 )
return;
ACE_Hash_Map_Iterator<TAO_Persistent_ExtId,TAO_Persistent_IntId,
ACE_Null_Mutex> it = storable_context_->map().begin();
ACE_Hash_Map_Iterator<TAO_Persistent_ExtId,TAO_Persistent_IntId,
ACE_Null_Mutex> itend = storable_context_->map().end();
ACE_Hash_Map_Entry<TAO_Persistent_ExtId,TAO_Persistent_IntId> ent = *it;
while (!(it == itend))
{
TAO_NS_Persistence_Record record;
CosNaming::BindingType bt = (*it).int_id_.type_;
if (bt == CosNaming::ncontext)
record.type(TAO_NS_Persistence_Record::NCONTEXT);
else if (bt == CosNaming::nobject)
record.type(TAO_NS_Persistence_Record::OBJREF);
//else
//there shouldn't be any other, can there be ??
//ignore for now
// todo - are we using this i ??
//int i = storable_context_->current_size();
const char *myid = (*it).ext_id_.id();
ACE_CString id(myid);
record.id(id);
const char *mykind = (*it).ext_id_.kind();
ACE_CString kind(mykind);
record.kind(kind);
ACE_CString name;
if (bt == CosNaming::nobject)
{
name.set((*it).int_id_.ref_);
}
else
{
CORBA::Object_var obj = orb_->string_to_object((*it).int_id_.ref_);
PortableServer::ObjectId_var oid = poa_->reference_to_id(obj.in());
CORBA::String_var nm = PortableServer::ObjectId_to_string(oid.in());
const char *newname = nm.in();
name.set(newname);
}
record.ref(name);
wrtr << record;
it.advance();
}
}
// Helper function to load a new context into the binding_map
int
TAO_Storable_Naming_Context::load_map(File_Open_Lock_and_Check *flck
ACE_ENV_ARG_DECL)
{
ACE_TRACE("load_map");
// assume file already open for reading
TAO_Storable_Bindings_Map *bindings_map;
// create the new bindings map
ACE_NEW_THROW_EX (bindings_map,
TAO_Storable_Bindings_Map (hash_table_size_,orb_),
CORBA::NO_MEMORY ());
// get the data for this bindings map from the file
TAO_NS_Persistence_Header header;
TAO_NS_Persistence_Record record;
// we are only using the size from this header
flck->peer() >> header;
// reset the destroyed flag
this->destroyed_ = header.destroyed();
// read in the data for the map
for (unsigned int i=0; i<header.size(); i++)
{
flck->peer() >> record;
if( record.type() == TAO_NS_Persistence_Record::NCONTEXT )
{
PortableServer::ObjectId_var id =
PortableServer::string_to_ObjectId(record.ref().c_str());
const char * intf = interface_->_interface_repository_id();
CORBA::Object_var objref = poa_->create_reference_with_id (
id.in (),
intf );
bindings_map->bind( record.id().c_str(),
record.kind().c_str(),
objref.in(),
CosNaming::ncontext );
}
else
{
CORBA::Object_var objref = orb_->string_to_object (record.ref().c_str());
bindings_map->bind( record.id().c_str(),
record.kind().c_str(),
objref.in(),
CosNaming::nobject );
}
}
storable_context_ = bindings_map;
context_ = storable_context_;
return 0;
}
TAO_Storable_Naming_Context::
File_Open_Lock_and_Check::File_Open_Lock_and_Check(
TAO_Storable_Naming_Context * context,
const char * mode
ACE_ENV_ARG_DECL)
:closed_(1),
context_(context)
{
ACE_TRACE("File_Open_Lock_and_Check");
// We only accept a subset of mode argument, check it
rwflags_ = 0;
for( unsigned int i = 0; i<ACE_OS::strlen(mode); i++ )
{
switch (mode[i])
{
case 'r': rwflags_ |= mode_read;
break;
case 'w': rwflags_ |= mode_write;
break;
case 'c': rwflags_ |= mode_create;
break;
default: rwflags_ = -1;
}
}
if( rwflags_ <= 0 )
{
errno = EINVAL;
ACE_THROW(CORBA::PERSIST_STORE());
}
// build the file name
ACE_CString file_name(context->persistence_directory_);
file_name += "/";
file_name += context->name_;
// Create the stream
fl_ = context->factory_->create_stream(file_name, mode);
if (TAO_Storable_Naming_Context::redundant_)
{
if (fl_->open() != 0)
{
delete fl_;
ACE_THROW(CORBA::PERSIST_STORE());
}
// acquire a lock on it
if (fl_ -> flock(0, 0, 0) != 0)
{
fl_->close();
delete fl_;
ACE_THROW(CORBA::INTERNAL());
}
// now that the file is successfully opened and locked it must be
// unlocked/closed before we leave this class
closed_ = 0;
if ( ! (rwflags_ & mode_create) )
{
// Check if our copy is up to date
time_t new_last_changed = fl_->last_changed();
if( new_last_changed > context->last_changed_ )
{
context->last_changed_ = new_last_changed;
// Throw our map away
delete context->storable_context_;
// and build a new one from disk
context->load_map(this ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
}
}
}
else if ( ! context->storable_context_ || (rwflags_ & mode_write) )
{
if (fl_->open() != 0)
{
delete fl_;
ACE_THROW(CORBA::PERSIST_STORE());
}
// now that the file is successfully opened
// unlocked/closed before we leave this class
closed_ = 0;
if(!context->storable_context_)
{
// Load the map from disk
context->load_map(this ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
}
}
}
void
TAO_Storable_Naming_Context::
File_Open_Lock_and_Check::release(void)
{
ACE_TRACE("release");
if ( ! closed_ )
{
// If we updated the disk, save the time stamp
if(TAO_Storable_Naming_Context::redundant_)
{
if( rwflags_ & mode_write )
context_->last_changed_ = fl_->last_changed();
fl_->funlock(0, 0, 0);
}
fl_->close();
delete fl_;
closed_ = 1;
}
}
TAO_Storable_Naming_Context::
File_Open_Lock_and_Check::~File_Open_Lock_and_Check(void)
{
ACE_TRACE("~File_Open_Lock_and_Check");
this->release();
}
TAO_Storable_Base &
TAO_Storable_Naming_Context::
File_Open_Lock_and_Check::peer(void)
{
ACE_TRACE("peer");
return *fl_;
}
TAO_Storable_Naming_Context::TAO_Storable_Naming_Context (
CORBA::ORB_ptr orb,
PortableServer::POA_ptr poa,
const char *poa_id,
TAO_Naming_Service_Persistence_Factory *factory,
const ACE_TCHAR *persistence_directory,
size_t hash_table_size)
: TAO_Hash_Naming_Context (poa,
poa_id),
counter_ (0),
storable_context_ (0),
orb_(CORBA::ORB::_duplicate (orb)),
name_ (poa_id),
poa_ (PortableServer::POA::_duplicate (poa)),
factory_(factory),
persistence_directory_ (ACE_TEXT_ALWAYS_CHAR(persistence_directory)),
hash_table_size_(hash_table_size),
last_changed_(0)
{
ACE_TRACE("TAO_Storable_Naming_Context");
}
TAO_Storable_Naming_Context::~TAO_Storable_Naming_Context (void)
{
ACE_TRACE("~TAO_Storable_Naming_Context");
// build the file name
ACE_CString file_name(persistence_directory_);
file_name += "/";
file_name += name_;
// and delete the file
TAO_Storable_Base * fl = factory_->create_stream(file_name, "w");
fl->remove();
}
CosNaming::NamingContext_ptr
TAO_Storable_Naming_Context::make_new_context (
CORBA::ORB_ptr orb,
PortableServer::POA_ptr poa,
const char *poa_id,
size_t context_size,
TAO_Naming_Service_Persistence_Factory *factory,
const ACE_TCHAR *persistence_directory,
TAO_Storable_Naming_Context **new_context
ACE_ENV_ARG_DECL)
{
ACE_TRACE("make_new_context");
// Store the stub we will return here.
CosNaming::NamingContext_var result;
// Put together a servant for the new Naming Context.
TAO_Storable_Naming_Context *context_impl = 0;
ACE_NEW_THROW_EX (context_impl,
TAO_Storable_Naming_Context (orb,
poa,
poa_id,
factory,
persistence_directory,
context_size),
CORBA::NO_MEMORY ());
ACE_CHECK_RETURN (result._retn ());
// Put <context_impl> into the auto pointer temporarily, in case next
// allocation fails.
ACE_Auto_Basic_Ptr<TAO_Storable_Naming_Context> temp (context_impl);
TAO_Naming_Context *context = 0;
ACE_NEW_THROW_EX (context,
TAO_Naming_Context (context_impl),
CORBA::NO_MEMORY ());
ACE_CHECK_RETURN (result._retn ());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -