Hi,
during OOo's compilation the following is done:
ccache g++ -fmessage-length=0 -c -I. -I. -I../inc -I../../../inc -I../../../unx/inc -I../../../unxlngi4.pro/inc -I. -I/home/rene/Debian/Pakete/OpenOffice.org/Hauptpaket/openoffice.org-1.0.3/build-tree/oo_1.0.3_src/solver/641/unxlngi4.pro/inc/stl -I/home/rene/Debian/Pakete/OpenOffice.org/Hauptpaket/openoffice.org-1.0.3/build-tree/oo_1.0.3_src/solver/641/unxlngi4.pro/inc/external -I/home/rene/Debian/Pakete/OpenOffice.org/Hauptpaket/openoffice.org-1.0.3/build-tree/oo_1.0.3_src/solver/641/unxlngi4.pro/inc -I/home/rene/Debian/Pakete/OpenOffice.org/Hauptpaket/openoffice.org-1.0.3/build-tree/oo_1.0.3_src/solenv/unxlngi4/inc -I/home/rene/Debian/Pakete/OpenOffice.org/Hauptpaket/openoffice.org-1.0.3/build-tree/oo_1.0.3_src/solenv/inc -I/home/rene/Debian/Pakete/OpenOffice.org/Hauptpaket/openoffice.org-1.0.3/build-tree/oo_1.0.3_src/res -I/home/rene/Debian/Pakete/OpenOffice.org/Hauptpaket/openoffice.org-1.0.3/stlport-home/stlport -I/home/rene/Debian/Pakete/OpenOffice.org/Hauptpaket/openoffice.org-1.0.3/stlport-home/include/stlport -I/home/rene/Debian/Pakete/OpenOffice.org/Hauptpaket/openoffice.org-1.0.3/stlport-home/include/stlport -I/home/rene/Debian/Pakete/OpenOffice.org/Hauptpaket/openoffice.org-1.0.3/build-tree/oo_1.0.3_src/solenv/inc/Xp31 -I/usr/lib/j2se/1.3/include -I/usr/lib/j2se/1.3/include/linux -I/usr/lib/j2se/1.3/include/native_threads/include -I/usr/X11R6/include -I. -I../../../res -I. -O -pipe -mcpu=pentiumpro -fno-for-scope -fpermissive -fexceptions -fno-enforce-eh-specs -fpic -DLINUX -DUNX -DVCL -DGCC -DC300 -DINTEL -DCVER=C300 -D_USE_NAMESPACE -DGLIBC=2 -DX86 -D_PTHREADS -D_REENTRANT -DNEW_SOLAR -D_USE_NAMESPACE=1 -DSTLPORT_VERSION=400 -D__DMAKE -DUNIX -DCPPU_ENV=gcc3 -DSUPD=641 -DBUILD=8584 -DPRODUCT -DNDEBUG -DPRODUCT_FULL -DEXCEPTIONS_ON -DCUI -DSOLAR_JAVA -DSRC641 -DSHAREDLIB -D_DLL_ -DMULTITHREAD -w -o ../../../unxlngi4.pro/slo/urp_reader.o /home/rene/Debian/Pakete/OpenOffice.org/Hauptpaket/openoffice.org-1.0.3/build-tree/oo_1.0.3_src/bridges/source/remote/urp/urp_reader.cxx
This worked with g++ 3.2 but not with 3.3.
It constantly consumes all my mamor (512 MB RAM, 512 MB swap) till it
gets OOM-killed by the kernel.
As I asked on debian-devel, James answered me:
20:11 < elmo > g++-3.3 has a silly inline default, IIRC, if you're
OOM-ing because of g++-3.3 with a large C++ source like
OOo, you could try lowering it
20:11 < elmo > there was a thread about it on the gcc list; I'm
reasonably sure it didn't get resolved before 3.3 was
released
[...]
20:18 < elmo > rene: see
http://gcc.gnu.org/ml/gcc/2003-05/msg00362.html and
other mails in that thread
OK, I tried with -finline-limit=x, x=4,3,2,1,0, compiled with -fno-inline,
with -O0 and I even removed 3 of the 4 inlines from the source. No effect.
It may be worth noting that the free "normal" memory during the "normal"
compilation is between 4-12M during compile anyhow...
I attach the source file here; a preprocessed source isn't available
because it is not generated :( (it seems that g++ fails during
preprocessing..)
What is the cause of that? Bug in g++? Should I report one "officially"?
Is there a workaround?
Regards,
Rene
/*************************************************************************
*
* $RCSfile: urp_reader.cxx,v $
*
* $Revision: 1.9 $
*
* last change: $Author: jbu $ $Date: 2001/08/31 16:16:52 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
*
* - GNU Lesser General Public License Version 2.1
* - Sun Industry Standards Source License Version 1.1
*
* Sun Microsystems Inc., October, 2000
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2000 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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
*
*
* Sun Industry Standards Source License Version 1.1
* =================================================
* The contents of this file are subject to the Sun Industry Standards
* Source License Version 1.1 (the "License"); You may not use this file
* except in compliance with the License. You may obtain a copy of the
* License at http://www.openoffice.org/license.html.
*
* Software provided under this License is provided on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
* See the License for the specific provisions governing your rights and
* obligations concerning the Software.
*
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
*
* Copyright: 2000 by Sun Microsystems, Inc.
*
* All Rights Reserved.
*
* Contributor(s): _______________________________________
*
*
************************************************************************/
#include <string.h>
#include <osl/diagnose.h>
#include <rtl/ustrbuf.hxx>
#include <bridges/remote/connection.h>
#include <bridges/remote/counter.hxx>
#include <bridges/remote/context.h>
#include <bridges/remote/helper.hxx>
#include <uno/environment.h>
#include "urp_reader.hxx"
#include "urp_writer.hxx"
#include "urp_dispatch.hxx"
#include "urp_job.hxx"
#include "urp_bridgeimpl.hxx"
#include "urp_log.hxx"
#include "urp_propertyobject.hxx"
using namespace ::rtl;
using namespace ::osl;
using namespace ::com::sun::star::uno;
#ifdef DEBUG
static MyCounter thisCounter( "DEBUG : ReaderThread" );
#endif
namespace bridges_urp
{
/**
* This callback is used to ensure, that the release call is sent for the correct type.
*
***/
void SAL_CALL urp_releaseRemoteCallback (
remote_Interface *pRemoteI,rtl_uString *pOid,
typelib_TypeDescriptionReference *pTypeRef,
uno_Environment *pEnvRemote )
{
remote_Context *pContext = (remote_Context *) pEnvRemote->pContext;
urp_BridgeImpl *pImpl = (urp_BridgeImpl*) ( pContext->m_pBridgeImpl );
pImpl->m_pWriter->insertReleaseRemoteCall( pOid , pTypeRef );
}
struct MessageFlags
{
sal_uInt16 nMethodId;
sal_Bool bRequest;
sal_Bool bType;
sal_Bool bOid;
sal_Bool bTid;
sal_Bool bException;
sal_Bool bMustReply;
sal_Bool bSynchronous;
sal_Bool bMoreFlags;
sal_Bool bIgnoreCache;
sal_Bool bBridgePropertyCall;
///--------------------------
inline MessageFlags()
{
bTid = sal_False;
bOid = sal_False;
bType = sal_False;
bException = sal_False;
bMoreFlags = sal_False;
bIgnoreCache = sal_False;
bBridgePropertyCall = sal_False;
}
//---------------------------
}; // end struct MessageFlags
inline sal_Bool OReaderThread::getMemberTypeDescription(
typelib_InterfaceAttributeTypeDescription **ppAttributeType,
typelib_InterfaceMethodTypeDescription **ppMethodType,
sal_Bool *pbIsSetter,
sal_uInt16 nMethodId ,
typelib_TypeDescriptionReference * pITypeRef )
{
if( pITypeRef->eTypeClass != typelib_TypeClass_INTERFACE )
{
OUString sMessage( RTL_CONSTASCII_USTRINGPARAM( "interface type is not of typeclass interface (" ));
sMessage += OUString::valueOf( (sal_Int32) pITypeRef->eTypeClass );
m_pBridgeImpl->addError( sMessage );
OSL_ENSURE( 0 , "type is not an interface" );
return sal_False;
}
typelib_InterfaceTypeDescription *pInterfaceType = 0;
TYPELIB_DANGER_GET(
(typelib_TypeDescription **)&pInterfaceType , pITypeRef );
if( ! pInterfaceType )
{
OUString sMessage( RTL_CONSTASCII_USTRINGPARAM( "No typedescription can be retrieved for type " ));
sMessage += pITypeRef->pTypeName;
m_pBridgeImpl->addError( sMessage );
OSL_ENSURE( 0 , "urp: unknown type " );
return sal_False;
}
if( ! pInterfaceType->aBase.bComplete )
{
typelib_typedescription_complete( (typelib_TypeDescription **) &pInterfaceType );
}
if( nMethodId < 0 || nMethodId > pInterfaceType->nAllMembers *2 )
{
OUString sMessage( RTL_CONSTASCII_USTRINGPARAM( "vtable out of range for type " ));
sMessage += pITypeRef->pTypeName;
sMessage += OUString::createFromAscii( " (" );
sMessage += OUString::valueOf( (sal_Int32) nMethodId );
sMessage += OUString::createFromAscii( " )" );
m_pBridgeImpl->addError( sMessage );
// (nMethodId > pInterfaceType->nAllMembers *2) is an essential condition
// for the vtable index to be correct
OSL_ENSURE( 0 , "vtable index out of range" );
return sal_False;
}
// TODO : check the range of nMethodId
sal_Int32 nMemberIndex = pInterfaceType->pMapFunctionIndexToMemberIndex[ nMethodId ];
if( !( pInterfaceType->nAllMembers > nMemberIndex && nMemberIndex >= 0 ) )
{
OUString sMessage( RTL_CONSTASCII_USTRINGPARAM( "vtable out of range for type " ));
sMessage += pITypeRef->pTypeName;
sMessage += OUString::createFromAscii( " (" );
sMessage += OUString::valueOf( (sal_Int32) nMethodId );
sMessage += OUString::createFromAscii( " )" );
m_pBridgeImpl->addError( sMessage );
OSL_ENSURE( 0 , "vtable index out of range" );
return sal_False;
}
typelib_InterfaceMemberTypeDescription *pMemberType = 0;
typelib_typedescriptionreference_getDescription(
(typelib_TypeDescription **) &pMemberType,pInterfaceType->ppAllMembers[nMemberIndex]);
if(! pMemberType )
{
OUString sMessage( RTL_CONSTASCII_USTRINGPARAM( "unknown method type description for type" ) );
sMessage += pITypeRef->pTypeName;
sMessage += OUString::createFromAscii( " (" );
sMessage += OUString::valueOf( (sal_Int32) nMethodId );
sMessage += OUString::createFromAscii( " )" );
m_pBridgeImpl->addError( sMessage );
OSL_ENSURE( 0 , "unknown method type description" );
return sal_False;
}
if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pMemberType->aBase.eTypeClass )
{
*ppAttributeType = (typelib_InterfaceAttributeTypeDescription *) pMemberType;
*pbIsSetter = ! (
pInterfaceType->pMapMemberIndexToFunctionIndex[nMemberIndex] == nMethodId );
}
else
{
*ppMethodType = (typelib_InterfaceMethodTypeDescription *) pMemberType;
}
TYPELIB_DANGER_RELEASE( (typelib_TypeDescription * )pInterfaceType );
return sal_True;
}
OReaderThread::OReaderThread( remote_Connection *pConnection,
uno_Environment *pEnvRemote,
OWriterThread * pWriterThread ) :
m_pConnection( pConnection ),
m_pEnvRemote( pEnvRemote ),
m_pWriterThread( pWriterThread ),
m_bDestroyMyself( sal_False ),
m_bContinue( sal_True ),
m_pBridgeImpl((struct urp_BridgeImpl*)
((remote_Context *)pEnvRemote->pContext)->m_pBridgeImpl ),
m_unmarshal( m_pBridgeImpl, m_pEnvRemote, ::bridges_remote::remote_createStub )
{
m_pEnvRemote->acquireWeak( m_pEnvRemote );
m_pConnection->acquire( m_pConnection );
#ifdef DEBUG
thisCounter.acquire();
#endif
}
OReaderThread::~OReaderThread( )
{
m_pEnvRemote->releaseWeak( m_pEnvRemote );
#ifdef DEBUG
thisCounter.release();
#endif
}
// may only be called in the callstack of this thread !!!!!
// run() -> dispose() -> destroyYourself()
void OReaderThread::destroyYourself()
{
m_bDestroyMyself = sal_True;
m_pConnection->release( m_pConnection );
m_pConnection = 0;
m_bContinue = sal_False;
}
void OReaderThread::onTerminated()
{
if( m_bDestroyMyself )
{
delete this;
}
}
void OReaderThread::disposeEnvironment()
{
struct remote_Context *pContext =
( struct remote_Context * ) m_pEnvRemote->pContext;
m_bContinue = sal_False;
if( ! pContext->m_pBridgeImpl->m_bDisposed )
{
uno_Environment *pEnvRemote = 0;
m_pEnvRemote->harden( &pEnvRemote , m_pEnvRemote );
if( pEnvRemote )
{
pEnvRemote->dispose( m_pEnvRemote );
pEnvRemote->release( m_pEnvRemote );
}
else
{
// environment has been disposed eitherway !
}
}
}
inline sal_Bool OReaderThread::readBlock( sal_Int32 *pnMessageCount )
{
m_unmarshal.setSize( 8 );
if( 8 != m_pConnection->read( m_pConnection , m_unmarshal.getBuffer(), 8 ) )
{
OUString s( RTL_CONSTASCII_USTRINGPARAM( "Unexpected connection closure" ) );
m_pBridgeImpl->addError( s );
return sal_False;
}
sal_Int32 nSize;
m_unmarshal.unpackInt32( &nSize );
m_unmarshal.unpackInt32( pnMessageCount );
if( nSize < 0 )
{
// buffer too big
// no exception can be thrown, because there is no thread id, which could be
// used. -> terminate !
OUString s( RTL_CONSTASCII_USTRINGPARAM( "Packet-size too big (" ) );
s += OUString::valueOf( (sal_Int64) (sal_uInt32 ) nSize );
s += OUString( RTL_CONSTASCII_USTRINGPARAM( ")" ) );
m_pBridgeImpl->addError( s );
OSL_ENSURE( 0 , "urp bridge: Packet-size too big" );
disposeEnvironment();
return sal_False;
}
if( 0 == nSize )
{
// normal termination !
return sal_False;
}
// allocate the necessary memory
if( ! m_unmarshal.setSize( nSize ) )
{
OUString s( RTL_CONSTASCII_USTRINGPARAM( "Packet-size too big, couln't allocate necessary memory (" ) );
s += OUString::valueOf( (sal_Int64) (sal_uInt32 ) nSize );
s += OUString( RTL_CONSTASCII_USTRINGPARAM( ")" ) );
m_pBridgeImpl->addError( s );
OSL_ENSURE( 0 , "urp bridge: messages size too large, terminating connection" );
return sal_False;
}
sal_Int32 nRead = m_pConnection->read( m_pConnection , m_unmarshal.getBuffer() , nSize );
if( nSize != nRead )
{
OUString s( RTL_CONSTASCII_USTRINGPARAM( "Unexpected connection closure, inconsistent packet (" ) );
s += OUString::valueOf( (sal_Int64) (sal_uInt32 ) nSize );
s += OUString( RTL_CONSTASCII_USTRINGPARAM( " asked, " ) );
s += OUString::valueOf( (sal_Int64) (sal_uInt32 ) nRead );
s += OUString( RTL_CONSTASCII_USTRINGPARAM( " got )" ) );
m_pBridgeImpl->addError( s );
// couldn't get the asked amount of bytes, quit
// should only occur, when the environment has already been disposed
OSL_ENSURE( m_pBridgeImpl->m_bDisposed , "urp bridge: inconsistent packet, terminating connection." );
return sal_False;
}
return sal_True;
}
inline sal_Bool OReaderThread::readFlags( struct MessageFlags *pFlags )
{
sal_uInt8 nBitField;
if( ! m_unmarshal.unpackInt8( &nBitField ) )
{
m_pBridgeImpl->addError( "Unexpected end of message header (1)" );
return sal_False;
}
if( HDRFLAG_LONGHEADER & nBitField )
{
// this is a long header, interpret the byte as bitfield
pFlags->bTid = (HDRFLAG_NEWTID & nBitField );
pFlags->bRequest = (HDRFLAG_REQUEST & nBitField);
if( pFlags->bRequest )
{
// request
pFlags->bType = ( HDRFLAG_NEWTYPE & nBitField );
pFlags->bOid = ( HDRFLAG_NEWOID & nBitField );
pFlags->bIgnoreCache = ( HDRFLAG_IGNORECACHE & nBitField );
pFlags->bMoreFlags = ( HDRFLAG_MOREFLAGS & nBitField );
if( pFlags->bMoreFlags )
{
// another byte with flags
sal_Int8 moreFlags;
if( ! m_unmarshal.unpackInt8( &moreFlags ) )
{
m_pBridgeImpl->addError( "Unexpected end of message header (2)" );
return sal_False;
}
pFlags->bSynchronous = ( HDRFLAG_SYNCHRONOUS & moreFlags );
pFlags->bMustReply = ( HDRFLAG_MUSTREPLY & moreFlags );
OSL_ENSURE( pFlags->bSynchronous && pFlags->bMustReply ||
! pFlags->bSynchronous && !pFlags->bMustReply,
"urp-bridge : customized calls currently not supported !");
}
if( HDRFLAG_LONGMETHODID & nBitField )
{
// methodid as unsigned short
if( ! m_unmarshal.unpackInt16( &(pFlags->nMethodId )) )
{
m_pBridgeImpl->addError( "Unexpected end of message header (3)" );
return sal_False;
}
}
else
{
sal_uInt8 id;
if( ! m_unmarshal.unpackInt8( &id ) )
{
m_pBridgeImpl->addError( "Unexpected end of message header (4)" );
return sal_False;
}
pFlags->nMethodId = (sal_uInt16) id;
}
}
else
{
// reply
pFlags->bRequest = sal_False;
pFlags->bException = ( HDRFLAG_EXCEPTION & nBitField );
}
}
else
{
// short request
pFlags->bRequest = sal_True;
if( 0x40 & nBitField )
{
sal_uInt8 lower;
if( ! m_unmarshal.unpackInt8( &lower ) )
{
m_pBridgeImpl->addError( "Unexpected end of message header (5)" );
return sal_False;
}
pFlags->nMethodId = ( nBitField & 0x3f ) << 8 | lower;
}
else
{
pFlags->nMethodId = ( nBitField & 0x3f );
}
}
return sal_True;
}
void OReaderThread::run()
{
// This vars are needed to hold oid,tid and type information, which should not be cached.
Type lastTypeNoCache;
OUString lastOidNoCache;
ByteSequence lastTidNoCache;
while( m_bContinue )
{
sal_Int32 nMessageCount;
if( ! readBlock( &nMessageCount ) )
{
disposeEnvironment();
break;
}
uno_Environment *pEnvRemote = 0;
m_pEnvRemote->harden( &pEnvRemote , m_pEnvRemote );
if( !pEnvRemote )
{
// environment has been disposed already, quit here
break;
}
ServerMultiJob *pMultiJob = 0;
remote_Interface *pLastRemoteI = 0;
while( ! m_unmarshal.finished() )
{
#ifdef BRIDGES_URP_PROT
sal_uInt32 nLogStart = m_unmarshal.getPos();
sal_Bool bIsOneWay = sal_False;
OUString sMemberName;
#endif
MessageFlags flags;
if( ! readFlags( &flags ) )
{
m_pBridgeImpl->addError( "incomplete message, skipping block" );
OSL_ENSURE ( 0 , "urp-bridge : incomplete message, skipping block" );
break;
}
// use these ** to access the ids fast ( avoid acquire/release calls )
sal_Sequence **ppLastTid = flags.bIgnoreCache ?
(sal_Sequence **) &lastTidNoCache :
(sal_Sequence **) &(m_pBridgeImpl->m_lastInTid);
rtl_uString **ppLastOid = flags.bIgnoreCache ?
(rtl_uString ** ) &lastOidNoCache :
(rtl_uString ** ) &(m_pBridgeImpl->m_lastInOid);
typelib_TypeDescriptionReference **ppLastType =
flags.bIgnoreCache ?
(typelib_TypeDescriptionReference ** ) &lastTidNoCache :
(typelib_TypeDescriptionReference ** ) &(m_pBridgeImpl->m_lastInType);
// get new type
if( flags.bType )
{
typelib_TypeDescriptionReference *pTypeRef = 0;
if( m_unmarshal.unpackType( &pTypeRef ) )
{
// release the old type
typelib_typedescriptionreference_release( *ppLastType );
// set the new type
*ppLastType = pTypeRef;
// no release on pTypeRef necessary (will be released by type dtor)
}
else
{
typelib_typedescriptionreference_release( pTypeRef );
m_pBridgeImpl->addError( "error during unpacking (maybe cached) interface type" );
OSL_ENSURE( 0 , "urp-bridge : error during unpacking interface type, terminating connection" );
disposeEnvironment();
break;
}
if( m_pBridgeImpl->m_lastInType.getTypeClass() != typelib_TypeClass_INTERFACE )
{
OUString sMessage( RTL_CONSTASCII_USTRINGPARAM( "interface type is not of typeclass interface (" ));
sMessage += OUString::valueOf( (sal_Int32) m_pBridgeImpl->m_lastInType.getTypeClass() );
m_pBridgeImpl->addError( sMessage );
OSL_ENSURE( 0 , "urp-bridge : not an interface type" );
disposeEnvironment();
break;
}
}
if( flags.bOid )
{
rtl_uString *pOid = 0;
if( m_unmarshal.unpackOid( &pOid ) )
{
rtl_uString_release( *ppLastOid );
*ppLastOid = pOid;
}
else
{
rtl_uString_release( pOid );
m_pBridgeImpl->addError( "error during unpacking (maybe cached) oid" );
OSL_ENSURE( 0 , "urp-bridge : error during unpacking cached data, terminating connection" );
disposeEnvironment();
break;
}
}
if( flags.bTid )
{
sal_Sequence *pSeq = 0;
if( m_unmarshal.unpackTid( &pSeq ) )
{
rtl_byte_sequence_release( *ppLastTid );
*ppLastTid = pSeq;
}
else
{
rtl_byte_sequence_release( pSeq );
m_pBridgeImpl->addError( "error during unpacking (maybe cached) tid" );
OSL_ENSURE( 0 , "urp-bridge : error during unpacking cached data, terminating connection" );
disposeEnvironment();
break;
}
}
// do the job
if( flags.bRequest )
{
//--------------------------
// handle request
//--------------------------
// get the membertypedescription
typelib_InterfaceMethodTypeDescription *pMethodType = 0;
typelib_InterfaceAttributeTypeDescription *pAttributeType = 0;
sal_Bool bIsSetter = sal_False;
if( getMemberTypeDescription(
&pAttributeType, &pMethodType, &bIsSetter,
flags.nMethodId, *ppLastType ) )
{
if( ! pLastRemoteI || flags.bOid || flags.bType )
{
// a new interface must be retrieved
// retrieve the interface NOW from the environment
// (avoid race conditions : oneway followed by release )
typelib_InterfaceTypeDescription *pInterfaceType = 0;
TYPELIB_DANGER_GET(
(typelib_TypeDescription ** ) &pInterfaceType ,
*ppLastType );
if( !pInterfaceType )
{
OUString sMessage( RTL_CONSTASCII_USTRINGPARAM( "Couldn't retrieve type description for type " ) );
sMessage += (*ppLastType)->pTypeName;
m_pBridgeImpl->addError( sMessage );
delete pMultiJob;
pMultiJob = 0;
disposeEnvironment();
pLastRemoteI = 0; // stubs are released during dispose eitherway
break;
}
pEnvRemote->pExtEnv->getRegisteredInterface(
pEnvRemote->pExtEnv, ( void ** ) &pLastRemoteI,
*ppLastOid, pInterfaceType );
TYPELIB_DANGER_RELEASE( (typelib_TypeDescription * )pInterfaceType );
if( !pLastRemoteI &&
REMOTE_RELEASE_METHOD_INDEX != flags.nMethodId &&
0 == rtl_ustr_ascii_compare_WithLength(
(*ppLastOid)->buffer, (*ppLastOid)->length, g_NameOfUrpProtocolPropertiesObject ) )
{
// check for bridge internal propertyobject
pLastRemoteI = m_pBridgeImpl->m_pPropertyObject;
pLastRemoteI->acquire( pLastRemoteI );
flags.bBridgePropertyCall = sal_True;
}
// NOTE : Instance provider is called in the executing thread
// Otherwise, instance provider may block the bridge
}
sal_Bool bCallIsOneway = sal_False;
if( flags.bMoreFlags )
{
// flags override the default !
bCallIsOneway = ! flags.bSynchronous;
}
else if( pMethodType && pMethodType->bOneWay )
{
bCallIsOneway = sal_True;
}
if( pMultiJob && ! flags.bTid && bCallIsOneway && ! pMultiJob->isFull())
{
// add to the existing multijob, nothing to do here
}
else
{
// create a new multijob
if( pMultiJob )
{
// there exists an old one, start it first.
pMultiJob->initiate();
}
pMultiJob = new ServerMultiJob(
pEnvRemote, *ppLastTid,
m_pBridgeImpl, &m_unmarshal , nMessageCount );
}
pMultiJob->setIgnoreCache( flags.bIgnoreCache );
pMultiJob->setType( *ppLastType );
if( pMethodType )
{
pMultiJob->setMethodType( pMethodType ,
REMOTE_RELEASE_METHOD_INDEX == flags.nMethodId,
bCallIsOneway );
}
else if( pAttributeType )
{
pMultiJob->setAttributeType( pAttributeType, bIsSetter, bCallIsOneway );
}
else
{
OSL_ASSERT( 0 );
}
if( pLastRemoteI )
pMultiJob->setInterface( pLastRemoteI );
else
pMultiJob->setOid( *ppLastOid );
} /* getMemberTypeDescription */
else
{
delete pMultiJob;
pMultiJob = 0;
pLastRemoteI = 0; // stubs are released during dispose eitherway
disposeEnvironment();
break;
}
#ifdef BRIDGES_URP_PROT
bIsOneWay = pMethodType && pMethodType->bOneWay;
sMemberName = pMethodType ?
pMethodType->aBase.pMemberName :
pAttributeType->aBase.pMemberName;
sal_uInt32 nLogHeader = m_unmarshal.getPos();
#endif
if( ! pMultiJob->extract( ) )
{
// severe error during extracting, dispose
delete pMultiJob;
pMultiJob = 0;
pLastRemoteI = 0; // stubs are released during dispose eitherway
disposeEnvironment();
break;
}
#ifdef BRIDGES_URP_PROT
urp_logServingRequest(
m_pBridgeImpl, m_unmarshal.getPos() - nLogStart,
m_unmarshal.getPos() - nLogHeader,
!bIsOneWay,
sMemberName );
#endif
if ( flags.bBridgePropertyCall )
{
// call to the bridge internal object.
// these calls MUST be executed within the dispatcher thread in order
// to synchronize properly with protocol changes
// NOTE : Threadid is not preserved for this call.
// lock the marshaling NOW !
{
MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
pMultiJob->execute();
if( m_pBridgeImpl->m_pPropertyObject->changesHaveBeenCommited() )
{
Properties props;
props = m_pBridgeImpl->m_pPropertyObject->getCommitedChanges();
// This call modified the protocol, apply the changes NOW !
m_pBridgeImpl->applyProtocolChanges( props );
}
}
delete pMultiJob;
pMultiJob = 0;
}
}
else
{
//--------------------------
// handle reply
//--------------------------
if( pMultiJob )
{
pMultiJob->initiate();
pMultiJob = 0;
}
if( pLastRemoteI )
{
pLastRemoteI->release( pLastRemoteI );
pLastRemoteI = 0;
}
ClientJob *pClientJob =
m_pBridgeImpl->m_clientJobContainer.remove( *( ByteSequence * )ppLastTid );
// Bridge MUST be already disposed, otherwise we got a wrong threadid
// from remote !
OSL_ASSERT( pClientJob || m_pBridgeImpl->m_bDisposed );
if( ! pClientJob )
{
OUStringBuffer error( 128 );
error.appendAscii( "ThreadID " );
OString o = byteSequence2HumanReadableString( *(ByteSequence* )ppLastTid );
error.appendAscii( o.getStr(), o.getLength() );
error.appendAscii( " unknown, so couldn't unmarshal reply" );
m_pBridgeImpl->addError( error.makeStringAndClear() );
pLastRemoteI = 0;
disposeEnvironment();
break;
}
pClientJob->m_bExceptionOccured = flags.bException;
pClientJob->setUnmarshal( &m_unmarshal );
#ifdef BRIDGES_URP_PROT
sMemberName = pClientJob->m_pMethodType ?
pClientJob->m_pMethodType->aBase.pMemberName :
pClientJob->m_pAttributeType->aBase.pMemberName;
sal_uInt32 nLogHeader = m_unmarshal.getPos();
#endif
if( ! pClientJob->extract( ) )
{
// severe error during extracting, dispose
pLastRemoteI = 0; // stubs are released during dispose eitherway
disposeEnvironment();
break;
}
#ifdef BRIDGES_URP_PROT
urp_logGettingReply(
m_pBridgeImpl, m_unmarshal.getPos() - nLogStart,
m_unmarshal.getPos() - nLogHeader, sMemberName );
#endif
sal_Bool bBridgePropertyCallAndWaitingForReply =
m_pBridgeImpl->m_pPropertyObject->waitingForCommitChangeReply() &&
pClientJob->isBridgePropertyCall();
pClientJob->initiate();
if( bBridgePropertyCallAndWaitingForReply )
{
// NOTE : This must be the reply for commit change. The new properties
// are now applied by the clientJob thread, but the reader thread
// must wait for it, because the next message on the wire already
// uses the new protocol settings.
// waiting for the commit change reply
m_pBridgeImpl->m_pPropertyObject->waitUntilChangesAreCommitted();
}
}
} // end while( !m_unmarshal.finished() )
if( pLastRemoteI )
pLastRemoteI->release( pLastRemoteI );
if( pMultiJob )
pMultiJob->initiate();
if( pEnvRemote )
pEnvRemote->release( pEnvRemote );
}
if( m_pConnection )
{
m_pConnection->release( m_pConnection );
m_pConnection = 0;
}
}
}
Attachment:
pgpIQWNqu5mOU.pgp
Description: PGP signature