[omniORB-dev] Removing an entry from proxyObjectFactory
Christian Perez
Christian.Perez@irisa.fr
Wed, 26 Feb 2003 17:00:33 +0100
This is a multi-part message in MIME format.
--------------30269C50EFB09E59EDDFEC71
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit
Hi,
Duncan Grisby wrote:
>
> On Thursday 20 February, Christian Perez wrote:
>
> If you can convince yourself that that situation will never arise in
> your application, it would be safe to unload stubs, and unregister
> their proxyObjectFactories.
Good news !
> > In attachement, you'll find such an implementation of proxyFactory.cc
> > derived from omniORB3 (location src/lib/omniORB2/orbcore/proxyFactory.cc).
> > This implementation is based on the used of the map of the C++ STL.
>
> There are two problems here. First, your suggestion is not thread
> safe. Second, it is not possible to use STL within omniORB, since it
> is not available everywhere.
The file was provided to illustrate the kind of modification I suggested.
As it was stated in the file, it was not a thread-safe implementation nor
a final implementation (it was derived from omniORB-3!)
Taking into your comments (no STL), here is a modified version of proxyFactory.cc
derived from omniORB-4. If you do not see any drawbacks, it would be very
nice if it could be inserted it into omniORB-4.
It has been successfully tested within a non trivial application.
Best regards,
Christian Pérez
--------------30269C50EFB09E59EDDFEC71
Content-Type: text/plain; charset=us-ascii;
name="proxyFactory-fix.cc"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="proxyFactory-fix.cc"
// -*- Mode: C++; -*-
// Package : omniORB
// proxyFactory.cc Created on: 24/2/99
// Author : Sai Lai Lo (sll)
//
// Copyright (C) 1996, 1997 Olivetti & Oracle Research Laboratory
//
// 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 proxyObjectFactory.
//
/*
$Log: proxyFactory.cc,v $
Revision 1.2.2.5 2001/09/19 17:26:53 dpg1
Full clean-up after orb->destroy().
Revision 1.2.2.4 2001/04/18 18:18:05 sll
Big checkin with the brand new internal APIs.
Revision 1.2.2.3 2000/11/09 12:27:59 dpg1
Huge merge from omni3_develop, plus full long long from omni3_1_develop.
Revision 1.2.2.2 2000/09/27 17:58:56 sll
Changed include/omniORB3 to include/omniORB4
Revision 1.2.2.1 2000/07/17 10:35:58 sll
Merged from omni3_develop the diff between omni3_0_0_pre3 and omni3_0_0.
Revision 1.3 2000/07/13 15:25:55 dpg1
Merge from omni3_develop for 3.0 release.
Revision 1.1.2.1 1999/09/22 14:27:05 djr
Major rewrite of orbcore to support POA.
*/
#include <omniORB4/CORBA.h>
#include <omniORB4/proxyFactory.h>
OMNI_NAMESPACE_BEGIN(omni)
static proxyObjectFactory** ofl = 0;
static int ofl_size = 0;
static int ofl_len = 0;
static omni_mutex* ofl_mutex = 0;
proxyObjectFactory::~proxyObjectFactory()
{
OMNIORB_ASSERT(pd_repoId);
// Remove itself from the global list
ofl_mutex->lock();
// Binary search to find the factory.
int bottom = 0;
int top = ofl_len;
int pos = -1;
while( bottom < top ) {
int middle = (bottom + top) / 2;
int cmp = strcmp(pd_repoId, ofl[middle]->pd_repoId);
if( cmp < 0 ) top = middle;
else if( cmp > 0 ) bottom = middle + 1;
else { pos = middle; break; }
}
// sanity check
if (pos == -1) {
if( omniORB::trace(1) ) {
omniORB::logger l;
l << "Could not find proxyObjectFactory " << this->pd_repoId
<< " whitin its desctructor at "
<< __FILE__ << ": line " << __LINE__ << "\n";
}
} else {
// remove it by shifting all pointers
// this is not the most efficient ;(
ofl_len = ofl_len - 1;
if (pos != ofl_len ) {
// this is not the last : shift
memcpy((void*)&ofl[pos], (void*)&ofl[pos+1], (ofl_len - pos) * sizeof(proxyObjectFactory*));
}
}
ofl_mutex->unlock();
}
proxyObjectFactory::proxyObjectFactory(const char* repoId)
: pd_repoId(repoId)
{
// These factories are constructed statically in the stubs, thus
// there should be no possiblilty of concurrency.
// This is not longer true as we try to support dynamic code loading and unloading
OMNIORB_ASSERT(repoId);
if( !ofl ) {
ofl_size = 5;
ofl = new proxyObjectFactory* [ofl_size];
ofl_len = 0;
// We can not rely on the order of initialization of global object
// This should be ok as there are some proxyObjectFactory created
// during the loading of the omniORB library, which is assumed to be a sequential operaion
ofl_mutex = new omni_mutex();
}
ofl_mutex->lock();
if( ofl_len == ofl_size ) {
int new_ofl_size = ofl_size * 2;
proxyObjectFactory** new_ofl = new proxyObjectFactory* [new_ofl_size];
for( int i = 0; i < ofl_size; i++ ) new_ofl[i] = ofl[i];
delete[] ofl;
ofl = new_ofl;
ofl_size = new_ofl_size;
}
// Binary search to determine the insertion point.
int bottom = 0;
int top = ofl_len;
while( bottom < top ) {
int middle = (bottom + top) / 2;
int cmp = strcmp(repoId, ofl[middle]->pd_repoId);
if( cmp < 0 ) top = middle;
else if( cmp > 0 ) bottom = middle + 1;
else {
ofl[middle] = this;
if( omniORB::trace(15) )
omniORB::logf("Replaced proxyObjectFactory for %s.", repoId);
ofl_mutex->unlock();
return;
}
}
OMNIORB_ASSERT(top == bottom);
for( int i = ofl_len; i > bottom; i-- )
ofl[i] = ofl[i - 1];
ofl[bottom] = this;
ofl_len++;
ofl_mutex->unlock();
}
void
proxyObjectFactory::shutdown()
{
ofl_mutex->lock();
ofl_size = 0;
ofl_len = 0;
delete[] ofl;
ofl_mutex->unlock();
delete ofl_mutex;
}
proxyObjectFactory*
proxyObjectFactory::lookup(const char* repoId)
{
// Factories should all be registered before the ORB is initialised,
// so at this point the list is read-only. Concurrent accesses are
// safe, except that the list is deleted when the ORB is shutdown.
// There is a very small possibility that we will segfault below,
// but that can only happen if the application is creating an object
// reference at the same time as they are shutting down the ORB.
OMNIORB_ASSERT(repoId);
ofl_mutex->lock();
// Binary search to find the factory.
int bottom = 0;
int top = ofl_len;
proxyObjectFactory* res = 0;
while( bottom < top ) {
int middle = (bottom + top) / 2;
int cmp = strcmp(repoId, ofl[middle]->pd_repoId);
if( cmp < 0 ) top = middle;
else if( cmp > 0 ) bottom = middle + 1;
else { res = ofl[middle]; break; }
}
ofl_mutex->unlock();
return res;
}
OMNI_NAMESPACE_END(omni)
--------------30269C50EFB09E59EDDFEC71--