summaryrefslogtreecommitdiff
path: root/stoc/source/invocation_adapterfactory
diff options
context:
space:
mode:
authorDaniel Boelzle <dbo@openoffice.org>2002-08-22 13:41:39 +0000
committerDaniel Boelzle <dbo@openoffice.org>2002-08-22 13:41:39 +0000
commit7942743f2987ad80325d398449c1fd175c03a48c (patch)
treedf7115733ee7920822d68088e187604c589beed1 /stoc/source/invocation_adapterfactory
parent914f823fa87519665873fcfb8967364b83cc8fc3 (diff)
#102239# reuse exported adapters
Diffstat (limited to 'stoc/source/invocation_adapterfactory')
-rw-r--r--stoc/source/invocation_adapterfactory/iafactory.cxx202
-rw-r--r--stoc/source/invocation_adapterfactory/makefile.mk13
2 files changed, 146 insertions, 69 deletions
diff --git a/stoc/source/invocation_adapterfactory/iafactory.cxx b/stoc/source/invocation_adapterfactory/iafactory.cxx
index 3139701104b2..8d727792c98f 100644
--- a/stoc/source/invocation_adapterfactory/iafactory.cxx
+++ b/stoc/source/invocation_adapterfactory/iafactory.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: iafactory.cxx,v $
*
- * $Revision: 1.6 $
+ * $Revision: 1.7 $
*
- * last change: $Author: dbo $ $Date: 2002-08-22 12:28:54 $
+ * last change: $Author: dbo $ $Date: 2002-08-22 14:41:39 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -60,6 +60,7 @@
************************************************************************/
#include <hash_map>
+#include <hash_set>
#include <osl/diagnose.h>
#include <osl/interlck.h>
@@ -138,7 +139,8 @@ struct hash_ptr
inline size_t operator() ( void * p ) const
{ return (size_t)p; }
};
-typedef hash_map< void *, uno_Interface *, hash_ptr, equal_to< void * > > t_receiver2adapter_map;
+typedef hash_set< void *, hash_ptr, equal_to< void * > > t_ptr_set;
+typedef hash_map< void *, t_ptr_set, hash_ptr, equal_to< void * > > t_ptr_map;
//==================================================================================================
class FactoryImpl
@@ -159,7 +161,7 @@ public:
typelib_TypeDescription * m_pConvertToTD;
Mutex m_mutex;
- t_receiver2adapter_map m_map;
+ t_ptr_map m_receiver2adapters;
FactoryImpl( Reference< XComponentContext > const & xContext ) SAL_THROW( (RuntimeException) );
virtual ~FactoryImpl() SAL_THROW( () );
@@ -217,14 +219,58 @@ struct AdapterImpl
void * pDest, typelib_TypeDescriptionReference * pType, uno_Any * pSource )
SAL_THROW( () );
+ inline void acquire()
+ SAL_THROW( () );
+ inline void release()
+ SAL_THROW( () );
+ inline ~AdapterImpl()
+ SAL_THROW( () );
inline AdapterImpl(
void * key, Reference< script::XInvocation > const & xReceiver,
const Sequence< Type > & rTypes,
FactoryImpl * pFactory )
SAL_THROW( (RuntimeException) );
- inline ~AdapterImpl()
- SAL_THROW( () );
};
+//__________________________________________________________________________________________________
+inline AdapterImpl::~AdapterImpl()
+ SAL_THROW( () )
+{
+ for ( sal_Int32 nPos = m_nInterfaces; nPos--; )
+ {
+ ::typelib_typedescription_release(
+ (typelib_TypeDescription *)m_pInterfaces[ nPos ].m_pTypeDescr );
+ }
+ delete [] m_pInterfaces;
+ //
+ (*m_pReceiver->release)( m_pReceiver );
+ m_pFactory->release();
+}
+//__________________________________________________________________________________________________
+inline void AdapterImpl::acquire()
+ SAL_THROW( () )
+{
+ ::osl_incrementInterlockedCount( &m_nRef );
+}
+//__________________________________________________________________________________________________
+inline void AdapterImpl::release()
+ SAL_THROW( () )
+{
+ MutexGuard guard( m_pFactory->m_mutex );
+ if (! ::osl_decrementInterlockedCount( &m_nRef ))
+ {
+ t_ptr_map::iterator iFind( m_pFactory->m_receiver2adapters.find( m_key ) );
+ OSL_ASSERT( m_pFactory->m_receiver2adapters.end() != iFind );
+ t_ptr_set & adapter_set = iFind->second;
+ size_t erased = adapter_set.erase( this );
+ OSL_ASSERT( 1 == erased );
+ if (adapter_set.empty())
+ {
+ m_pFactory->m_receiver2adapters.erase( iFind );
+ OSL_ASSERT( 1 == erased );
+ }
+ delete this;
+ }
+}
//--------------------------------------------------------------------------------------------------
static inline type_equals(
@@ -530,39 +576,18 @@ void AdapterImpl::invoke(
// cleanup constructed in params
::uno_destructData( &pInParamsSeq, m_pFactory->m_pAnySeqTD, 0 );
}
-//__________________________________________________________________________________________________
-inline AdapterImpl::~AdapterImpl()
-{
- for ( sal_Int32 nPos = m_nInterfaces; nPos--; )
- {
- ::typelib_typedescription_release(
- (typelib_TypeDescription *)m_pInterfaces[ nPos ].m_pTypeDescr );
- }
- delete [] m_pInterfaces;
- //
- (*m_pReceiver->release)( m_pReceiver );
- m_pFactory->release();
-}
extern "C"
{
//__________________________________________________________________________________________________
static void SAL_CALL adapter_acquire( uno_Interface * pUnoI )
{
- ::osl_incrementInterlockedCount(
- &static_cast< InterfaceAdapterImpl * >( pUnoI )->m_pAdapter->m_nRef );
+ static_cast< InterfaceAdapterImpl * >( pUnoI )->m_pAdapter->acquire();
}
//__________________________________________________________________________________________________
static void SAL_CALL adapter_release( uno_Interface * pUnoI )
{
- AdapterImpl * pThis = static_cast< InterfaceAdapterImpl * >( pUnoI )->m_pAdapter;
- MutexGuard guard( pThis->m_pFactory->m_mutex );
- if (! ::osl_decrementInterlockedCount( &pThis->m_nRef ))
- {
- size_t erased = pThis->m_pFactory->m_map.erase( pThis->m_key );
- OSL_ASSERT( 1 == erased );
- delete pThis;
- }
+ static_cast< InterfaceAdapterImpl * >( pUnoI )->m_pAdapter->release();
}
//__________________________________________________________________________________________________
static void SAL_CALL adapter_dispatch(
@@ -574,20 +599,20 @@ static void SAL_CALL adapter_dispatch(
{
case 0: // queryInterface()
{
- AdapterImpl * pThis =
+ AdapterImpl * that =
static_cast< InterfaceAdapterImpl * >( pUnoI )->m_pAdapter;
*ppException = 0; // no exc
typelib_TypeDescriptionReference * pDemanded =
*(typelib_TypeDescriptionReference **)pArgs[0];
// pInterfaces[0] is XInterface
- for ( sal_Int32 nPos = 0; nPos < pThis->m_nInterfaces; ++nPos )
+ for ( sal_Int32 nPos = 0; nPos < that->m_nInterfaces; ++nPos )
{
- typelib_InterfaceTypeDescription * pTD = pThis->m_pInterfaces[nPos].m_pTypeDescr;
+ typelib_InterfaceTypeDescription * pTD = that->m_pInterfaces[nPos].m_pTypeDescr;
while (pTD)
{
if (type_equals( ((typelib_TypeDescription *)pTD)->pWeakRef, pDemanded ))
{
- uno_Interface * pUnoI = &pThis->m_pInterfaces[nPos];
+ uno_Interface * pUnoI = &that->m_pInterfaces[nPos];
::uno_any_construct(
(uno_Any *)pReturn, &pUnoI, (typelib_TypeDescription *)pTD, 0 );
return;
@@ -609,18 +634,18 @@ static void SAL_CALL adapter_dispatch(
default:
{
- AdapterImpl * pThis =
+ AdapterImpl * that =
static_cast< InterfaceAdapterImpl * >( pUnoI )->m_pAdapter;
if (pMemberType->eTypeClass == typelib_TypeClass_INTERFACE_METHOD) // method
{
- pThis->invoke( pMemberType, pReturn, pArgs, ppException );
+ that->invoke( pMemberType, pReturn, pArgs, ppException );
}
else // attribute
{
if (pReturn)
- pThis->getValue( pMemberType, pReturn, pArgs, ppException );
+ that->getValue( pMemberType, pReturn, pArgs, ppException );
else
- pThis->setValue( pMemberType, pReturn, pArgs, ppException );
+ that->setValue( pMemberType, pReturn, pArgs, ppException );
}
}
}
@@ -747,17 +772,57 @@ FactoryImpl::~FactoryImpl() SAL_THROW( () )
(*m_pConverter->release)( m_pConverter );
+#ifdef DEBUG
+ OSL_ENSURE( m_receiver2adapters.empty(), "### still adapters out there!?" );
+#endif
g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
}
-// XInvocationAdapterFactory
-//__________________________________________________________________________________________________
-Reference< XInterface > FactoryImpl::createAdapter(
- const Reference< script::XInvocation > & xReceiver, const Type & rType )
- throw (RuntimeException)
+
+//--------------------------------------------------------------------------------------------------
+static inline AdapterImpl * lookup_adapter(
+ t_ptr_set ** pp_adapter_set,
+ t_ptr_map & map, void * key, Sequence< Type > const & rTypes )
+ SAL_THROW( () )
{
- return createAdapter( xReceiver, Sequence< Type >( &rType, 1 ) );
+ t_ptr_set & adapters_set = map[ key ];
+ *pp_adapter_set = &adapters_set;
+ if (adapters_set.empty())
+ return 0; // shortcut
+ // find matching adapter
+ Type const * pTypes = rTypes.getConstArray();
+ sal_Int32 nTypes = rTypes.getLength();
+ t_ptr_set::const_iterator iPos( adapters_set.begin() );
+ t_ptr_set::const_iterator const iEnd( adapters_set.end() );
+ while (iEnd != iPos)
+ {
+ AdapterImpl * that = reinterpret_cast< AdapterImpl * >( *iPos );
+ // iterate thru all types if that is a matching adapter
+ for ( sal_Int32 nPosTypes = nTypes; nPosTypes--; )
+ {
+ Type const & rType = pTypes[ nPosTypes ];
+ // find in adapter's type list
+ for ( sal_Int32 nPos = that->m_nInterfaces; nPos--; )
+ {
+ if (::typelib_typedescriptionreference_isAssignableFrom(
+ rType.getTypeLibType(),
+ ((typelib_TypeDescription *)that->
+ m_pInterfaces[ nPos ].m_pTypeDescr)->pWeakRef ))
+ {
+ // found
+ break;
+ }
+ }
+ if (nPos < 0) // type not found => next adapter
+ break;
+ }
+ if (nPosTypes < 0) // all types found
+ return that;
+ ++iPos;
+ }
+ return 0;
}
-// XInvocationAdapterFactory2
+
+// XInvocationAdapterFactory2 impl
//__________________________________________________________________________________________________
Reference< XInterface > FactoryImpl::createAdapter(
const Reference< script::XInvocation > & xReceiver, const Sequence< Type > & rTypes )
@@ -766,47 +831,42 @@ Reference< XInterface > FactoryImpl::createAdapter(
Reference< XInterface > xRet;
if (xReceiver.is() && rTypes.getLength())
{
- uno_Interface * pAdapter;
+ t_ptr_set * adapter_set;
+ AdapterImpl * that;
Reference< XInterface > xKey( xReceiver, UNO_QUERY );
{
ClearableMutexGuard guard( m_mutex );
- t_receiver2adapter_map::const_iterator const iFind( m_map.find( xKey.get() ) );
- if (m_map.end() == iFind) // no entry
+ that = lookup_adapter( &adapter_set, m_receiver2adapters, xKey.get(), rTypes );
+ if (0 == that) // no entry
{
guard.clear();
- // create adapter
- AdapterImpl * that = new AdapterImpl(
- xKey.get(), xReceiver, rTypes, this ); // already acquired: m_nRef == 1
- pAdapter = &that->m_pInterfaces[ 0 ];
-
+ // create adapter; already acquired: m_nRef == 1
+ AdapterImpl * pNew = new AdapterImpl( xKey.get(), xReceiver, rTypes, this );
// lookup again
ClearableMutexGuard guard( m_mutex );
- t_receiver2adapter_map::const_iterator const iFind( m_map.find( xKey.get() ) );
- if (m_map.end() == iFind) // no entry
+ that = lookup_adapter( &adapter_set, m_receiver2adapters, xKey.get(), rTypes );
+ if (0 == that) // again no entry
{
- // insert
- pair< t_receiver2adapter_map::iterator, bool > insertion(
- m_map.insert( t_receiver2adapter_map::value_type( xKey.get(), pAdapter ) ) );
+ pair< t_ptr_set::iterator, bool > insertion( adapter_set->insert( pNew ) );
OSL_ASSERT( insertion.second );
+ that = pNew;
}
else
{
- pAdapter = iFind->second;
- (*pAdapter->acquire)( pAdapter );
+ that->acquire();
guard.clear();
- delete that; // has never been inserted
+ delete pNew; // has never been inserted
}
}
- else // entry found
+ else // found adapter
{
- pAdapter = iFind->second;
- (*pAdapter->acquire)( pAdapter );
+ that->acquire();
}
}
- // map adapter to C++
- m_aUno2Cpp.mapInterface(
- (void **)&xRet, pAdapter, ::getCppuType( &xRet ) );
- (*pAdapter->release)( pAdapter );
+ // map one interface to C++
+ uno_Interface * pUnoI = &that->m_pInterfaces[ 0 ];
+ m_aUno2Cpp.mapInterface( (void **)&xRet, pUnoI, ::getCppuType( &xRet ) );
+ that->release();
OSL_ASSERT( xRet.is() );
if (! xRet.is())
{
@@ -816,6 +876,14 @@ Reference< XInterface > FactoryImpl::createAdapter(
}
return xRet;
}
+// XInvocationAdapterFactory impl
+//__________________________________________________________________________________________________
+Reference< XInterface > FactoryImpl::createAdapter(
+ const Reference< script::XInvocation > & xReceiver, const Type & rType )
+ throw (RuntimeException)
+{
+ return createAdapter( xReceiver, Sequence< Type >( &rType, 1 ) );
+}
// XServiceInfo
//__________________________________________________________________________________________________
diff --git a/stoc/source/invocation_adapterfactory/makefile.mk b/stoc/source/invocation_adapterfactory/makefile.mk
index 73ff17bbe606..58524f07b98b 100644
--- a/stoc/source/invocation_adapterfactory/makefile.mk
+++ b/stoc/source/invocation_adapterfactory/makefile.mk
@@ -2,9 +2,9 @@
#
# $RCSfile: makefile.mk,v $
#
-# $Revision: 1.8 $
+# $Revision: 1.9 $
#
-# last change: $Author: jbu $ $Date: 2001-06-22 16:20:57 $
+# last change: $Author: dbo $ $Date: 2002-08-22 14:41:39 $
#
# The Contents of this file are made available subject to the terms of
# either of the following licenses
@@ -95,6 +95,15 @@ SHL1DEF= $(MISC)$/$(SHL1TARGET).def
DEF1NAME= $(SHL1TARGET)
+.IF "$(debug)" != ""
+
+# msvc++: no inlining
+.IF "$(COM)" == "MSC"
+CFLAGS += -Ob0
+.ENDIF
+
+.ENDIF
+
# --- Targets ------------------------------------------------------
.INCLUDE : target.mk