📄 context.cc
字号:
// -*- Mode: C++; -*-// Package : omniORB// context.cc Created on: 9/1998// Author : David Riddoch (djr)//// Copyright (C) 1996-1999 AT&T Laboratories Cambridge//// This file is part of the omniORB library//// The omniORB library is free software; you can redistribute it and/or// modify it under the terms of the GNU Library General Public// License as published by the Free Software Foundation; either// version 2 of the License, or (at your option) any later version.//// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU// Library General Public License for more details.//// You should have received a copy of the GNU Library General Public// License along with this library; if not, write to the Free// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA// 02111-1307, USA////// Description:// Implementation of CORBA::Context.///* $Log: context.cc,v $ Revision 1.12.2.13 2002/01/16 11:31:56 dpg1 Race condition in use of registerNilCorbaObject/registerTrackedObject. (Reported by Teemu Torma). Revision 1.12.2.12 2001/11/27 14:35:07 dpg1 Context, DII fixes. Revision 1.12.2.11 2001/11/06 15:41:35 dpg1 Reimplement Context. Remove CORBA::Status. Tidying up. Revision 1.12.2.10 2001/09/24 10:41:08 dpg1 Minor codes for Dynamic library and omniORBpy. Revision 1.12.2.9 2001/09/19 17:26:44 dpg1 Full clean-up after orb->destroy(). Revision 1.12.2.8 2001/08/17 17:07:05 sll Remove the use of omniORB::logStream. Revision 1.12.2.7 2001/06/13 20:10:03 sll Minor update to make the ORB compiles with MSVC++. Revision 1.12.2.6 2001/04/19 09:14:16 sll Scoped where appropriate with the omni namespace. Revision 1.12.2.5 2000/12/05 17:41:00 dpg1 New cdrStream functions to marshal and unmarshal raw strings. Revision 1.12.2.4 2000/11/03 19:07:31 sll Use new marshalling functions for byte, octet and char. Use get_octet_array instead of get_char_array. Revision 1.12.2.3 2000/10/06 16:40:53 sll Changed to use cdrStream. Revision 1.12.2.2 2000/09/27 17:25:40 sll Changed include/omniORB3 to include/omniORB4. Revision 1.12.2.1 2000/07/17 10:35:40 sll Merged from omni3_develop the diff between omni3_0_0_pre3 and omni3_0_0. Revision 1.13 2000/07/13 15:26:03 dpg1 Merge from omni3_develop for 3.0 release. Revision 1.9.6.4 2000/06/22 10:40:11 dpg1 exception.h renamed to exceptiondefs.h to avoid name clash on some platforms. Revision 1.9.6.3 1999/10/29 13:18:10 djr Changes to ensure mutexes are constructed when accessed. Revision 1.9.6.2 1999/10/14 16:21:55 djr Implemented logging when system exceptions are thrown. Revision 1.9.6.1 1999/09/22 14:26:29 djr Major rewrite of orbcore to support POA. Revision 1.9 1999/06/26 18:03:30 sll Corrected minor bug in marshal. Revision 1.8 1999/06/25 13:50:24 sll Renamed compatibility flag to omniORB_27_CompatibleAnyExtraction. Revision 1.7 1999/06/22 14:59:03 sll set_one_value now correctly use the any extraction operator for string. It takes into account of the configuration variable copyStringInAnyExtraction. Revision 1.6 1999/05/25 17:39:35 sll Added check for invalid arguments using magic number. Revision 1.5 1999/04/21 11:24:37 djr Added marshalling methods, plus a few minor mods.*/#include <omniORB4/CORBA.h>#include <omniORB4/objTracker.h>#ifdef HAS_pch#pragma hdrstop#endif#include <context.h>#include <pseudo.h>#include <exceptiondefs.h>#include <ctype.h>#include <libcWrapper.h>#include <orbParameters.h>#define INIT_MAX_SEQ_LENGTH 6OMNI_NAMESPACE_BEGIN(omni)static ContextImpl* default_context = 0;ContextImpl::ContextImpl(const char* name, CORBA::Context_ptr parent){ if( !name ) name = ""; else if( *name ) check_context_name(name); pd_name = CORBA::string_dup(name); pd_parent = parent; pd_entries.length(INIT_MAX_SEQ_LENGTH); pd_entries.length(0); pd_children = 0; pd_nextSibling = 0; pd_refCount = 1; if( !CORBA::is_nil(pd_parent) ) ((ContextImpl*)pd_parent)->addChild(this);}ContextImpl::~ContextImpl(){ // This destructor can only be called when the reference count // has gone to zero, and there are no children. if( pd_refCount || pd_children ) throw omniORB::fatalException(__FILE__, __LINE__, "Application deleted a CORBA::Context explicitly"); OMNIORB_USER_CHECK(this != default_context); // This fails if the application releases the default context too many times. // <pd_name> freed by String_var. // We don't own <pd_parent>. for( CORBA::ULong i = 0; i < pd_entries.length(); i++ ){ if( pd_entries[i].name ) CORBA::string_free(pd_entries[i].name); if( pd_entries[i].value ) CORBA::string_free(pd_entries[i].value); } if( !CORBA::is_nil(pd_parent) ) ((ContextImpl*)pd_parent)->loseChild(this);}voidContextImpl::releaseDefault(){ if (default_context) { ContextImpl* d = default_context; default_context = 0; d->decrRefCount(); omniORB::logs(15, "Released default Context"); }}const char*ContextImpl::context_name() const{ // Never changes - no need to lock. return pd_name;}CORBA::Context_ptrContextImpl::parent() const{ // Never changes - no need to lock. return pd_parent;}voidContextImpl::create_child(const char* name, CORBA::Context_out out){ out = CORBA::Context::_nil(); // The c'tor checks that the name is legal. out = new ContextImpl(name, this);}voidContextImpl::set_one_value(const char* prop_name, const CORBA::Any& value){ // Check the property name is valid. if( !prop_name ) OMNIORB_THROW(BAD_PARAM, BAD_PARAM_NullStringUnexpected, CORBA::COMPLETED_NO); check_property_name(prop_name); CORBA::String_var name(CORBA::string_dup(prop_name)); const char* strval; if( !(value >>= strval) ) OMNIORB_THROW(BAD_PARAM, BAD_PARAM_AnyDoesNotContainAString, CORBA::COMPLETED_NO); insert_single_consume(name._retn(), ((omniORB::omniORB_27_CompatibleAnyExtraction)? (char*)strval:CORBA::string_dup(strval)));}voidContextImpl::set_values(CORBA::NVList_ptr values){ if( !CORBA::NVList::PR_is_valid(values) || CORBA::is_nil(values) ) OMNIORB_THROW(BAD_PARAM,BAD_PARAM_InvalidNVList, CORBA::COMPLETED_NO); CORBA::ULong count = values->count(); for( CORBA::ULong i = 0; i < count; i++ ){ CORBA::NamedValue_ptr nv = values->item(i); set_one_value(nv->name(), *nv->value()); }}voidContextImpl::delete_values(const char* pattern){ omni_tracedmutex_lock lock(pd_lock); CORBA::ULong bottom, top; if( !matchPattern(pattern, bottom, top) ) OMNIORB_THROW(BAD_CONTEXT, BAD_CONTEXT_NoMatchingProperty, CORBA::COMPLETED_NO); CORBA::ULong nmatches = top - bottom; CORBA::ULong count = pd_entries.length(); // delete entries, and move ones above down for( CORBA::ULong i = bottom; i + nmatches < count; i++ ){ CORBA::string_free(pd_entries[i].name); CORBA::string_free(pd_entries[i].value); pd_entries[i] = pd_entries[i + nmatches]; } pd_entries.length(pd_entries.length() - nmatches);}voidContextImpl::get_values(const char* start_scope, CORBA::Flags op_flags, const char* pattern, CORBA::NVList_out values_out){ if( !pattern || !*pattern ) OMNIORB_THROW(BAD_PARAM,BAD_PARAM_EmptyContextPattern,CORBA::COMPLETED_NO); ContextImpl* c = this; if( start_scope && *start_scope ){ // find the starting scope while( !CORBA::is_nil(c) && strcasecmp(c->pd_name, start_scope) ) c = (ContextImpl*)c->pd_parent; if( CORBA::is_nil(c) ) OMNIORB_THROW(BAD_CONTEXT, BAD_CONTEXT_StartingScopeNotFound, CORBA::COMPLETED_NO); } int wildcard = 0; if( pattern[strlen(pattern) - 1] == '*' ) wildcard = 1; CORBA::NVList_ptr nvlist = new NVListImpl(); try{ add_values(c, op_flags, pattern, wildcard, nvlist); } catch(...){ CORBA::release(nvlist); throw; } if( nvlist->count() == CORBA::ULong(0) ){ CORBA::release(nvlist); OMNIORB_THROW(BAD_CONTEXT, BAD_CONTEXT_NoMatchingProperty, CORBA::COMPLETED_NO); }else values_out = nvlist;}CORBA::BooleanContextImpl::NP_is_nil() const{ return 0;}CORBA::Context_ptrContextImpl::NP_duplicate(){ omni_tracedmutex_lock sync(pd_lock); pd_refCount++; return this;}voidContextImpl::insert_single_consume(char* name, char* value){ omni_tracedmutex_lock lock(pd_lock); // Binary search to determine insertion point CORBA::ULong count = pd_entries.length(); CORBA::ULong bottom = 0; CORBA::ULong top = count; CORBA::Long match = -1; while( bottom < top ){ CORBA::ULong i = (bottom + top) / 2; int cmp = strcasecmp(name, pd_entries[i].name); if( cmp < 0 ) top = i; else if( cmp > 0 ) bottom = (bottom == i) ? i + 1 : i; else{ match = i; break; } } if( match >= 0 ){ // Already has an entry - replace it. CORBA::string_free(pd_entries[match].value); CORBA::string_free(name); pd_entries[match].value = value; return; } if( count == pd_entries.maximum() ) // Allocate new space in decent chunks. pd_entries.length(count * 6 / 5 + 1); pd_entries.length(count + 1); // <bottom> is the index where we want to insert this value. for( CORBA::ULong i = count; i > bottom; i-- ) pd_entries[i] = pd_entries[i - 1]; pd_entries[bottom].name = name; pd_entries[bottom].value = value;}voidContextImpl::decrRefCount(){ CORBA::Boolean delete_me = 0; { omni_tracedmutex_lock sync(pd_lock); if( !pd_refCount ) { if( omniORB::traceLevel > 0 ) { omniORB::logger log; log << "omniORB: WARNING -- CORBA::release() was called too many times\n" " for a CORBA::Context object - the object has already been\n" " destroyed.\n"; } return; } // We can only delete <this> if there are no dependent children. if( --pd_refCount == 0 && !pd_children ) delete_me = 1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -