1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: urp_reader.cxx,v $
10 * $Revision: 1.18.20.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_bridges.hxx"
35 #include <osl/diagnose.h>
36 #include <rtl/ustrbuf.hxx>
38 #include <bridges/remote/connection.h>
39 #include <bridges/remote/counter.hxx>
40 #include <bridges/remote/context.h>
41 #include <bridges/remote/helper.hxx>
43 #include <com/sun/star/uno/XCurrentContext.hpp>
44 #include <uno/environment.h>
46 #include "urp_reader.hxx"
47 #include "urp_writer.hxx"
48 #include "urp_dispatch.hxx"
49 #include "urp_job.hxx"
50 #include "urp_bridgeimpl.hxx"
51 #include "urp_log.hxx"
52 #include "urp_propertyobject.hxx"
54 using namespace ::rtl
;
55 using namespace ::osl
;
56 using namespace ::com::sun::star::uno
;
58 #if OSL_DEBUG_LEVEL > 1
59 static MyCounter
thisCounter( "DEBUG : ReaderThread" );
66 * This callback is used to ensure, that the release call is sent for the correct type.
69 void SAL_CALL
urp_releaseRemoteCallback (
70 remote_Interface
*, rtl_uString
*pOid
,
71 typelib_TypeDescriptionReference
*pTypeRef
, uno_Environment
*pEnvRemote
)
73 remote_Context
*pContext
= (remote_Context
*) pEnvRemote
->pContext
;
74 urp_BridgeImpl
*pImpl
= (urp_BridgeImpl
*) ( pContext
->m_pBridgeImpl
);
76 pImpl
->m_pWriter
->insertReleaseRemoteCall( pOid
, pTypeRef
);
89 sal_Bool bSynchronous
;
91 sal_Bool bIgnoreCache
;
92 sal_Bool bBridgePropertyCall
;
93 ///--------------------------
99 bException
= sal_False
;
100 bMoreFlags
= sal_False
;
101 bIgnoreCache
= sal_False
;
102 bBridgePropertyCall
= sal_False
;
104 //---------------------------
105 }; // end struct MessageFlags
107 inline sal_Bool
OReaderThread::getMemberTypeDescription(
108 typelib_InterfaceAttributeTypeDescription
**ppAttributeType
,
109 typelib_InterfaceMethodTypeDescription
**ppMethodType
,
110 sal_Bool
*pbIsSetter
,
111 sal_uInt16 nMethodId
,
112 typelib_TypeDescriptionReference
* pITypeRef
)
114 if( pITypeRef
->eTypeClass
!= typelib_TypeClass_INTERFACE
)
116 OUStringBuffer sMessage
;
117 sMessage
.appendAscii( "interface type is not of typeclass interface (" );
118 sMessage
.append( (sal_Int32
) pITypeRef
->eTypeClass
);
119 m_pBridgeImpl
->addError( sMessage
.makeStringAndClear() );
120 OSL_ENSURE( 0 , "type is not an interface" );
124 typelib_InterfaceTypeDescription
*pInterfaceType
= 0;
126 (typelib_TypeDescription
**)&pInterfaceType
, pITypeRef
);
127 if( ! pInterfaceType
)
129 OUStringBuffer sMessage
;
130 sMessage
.appendAscii( "No typedescription can be retrieved for type " );
131 sMessage
.append( OUString( pITypeRef
->pTypeName
) );
132 m_pBridgeImpl
->addError( sMessage
.makeStringAndClear() );
133 OSL_ENSURE( 0 , "urp: unknown type " );
137 if( ! pInterfaceType
->aBase
.bComplete
)
139 typelib_typedescription_complete( (typelib_TypeDescription
**) &pInterfaceType
);
142 if ( nMethodId
>= pInterfaceType
->nMapFunctionIndexToMemberIndex
)
144 OUStringBuffer sMessage
;
145 sMessage
.appendAscii( "vtable out of range for type " );
146 sMessage
.append( OUString( pITypeRef
->pTypeName
) );
147 sMessage
.appendAscii( " (" );
148 sMessage
.append( (sal_Int32
) nMethodId
);
149 sMessage
.appendAscii( " )" );
150 m_pBridgeImpl
->addError( sMessage
.makeStringAndClear() );
152 OSL_ENSURE( 0 , "vtable index out of range" );
156 sal_Int32 nMemberIndex
= pInterfaceType
->pMapFunctionIndexToMemberIndex
[ nMethodId
];
158 if( !( pInterfaceType
->nAllMembers
> nMemberIndex
&& nMemberIndex
>= 0 ) )
160 OUStringBuffer sMessage
;
161 sMessage
.appendAscii( "vtable out of range for type " );
162 sMessage
.append( OUString( pITypeRef
->pTypeName
) );
163 sMessage
.appendAscii( " (" );
164 sMessage
.append( (sal_Int32
) nMethodId
);
165 sMessage
.appendAscii( " )" );
166 m_pBridgeImpl
->addError( sMessage
.makeStringAndClear() );
168 OSL_ENSURE( 0 , "vtable index out of range" );
172 typelib_InterfaceMemberTypeDescription
*pMemberType
= 0;
173 typelib_typedescriptionreference_getDescription(
174 (typelib_TypeDescription
**) &pMemberType
,pInterfaceType
->ppAllMembers
[nMemberIndex
]);
178 OUStringBuffer sMessage
;
179 sMessage
.appendAscii( "unknown method type description for type" );
180 sMessage
.append( OUString( pITypeRef
->pTypeName
) );
181 sMessage
.appendAscii( " (" );
182 sMessage
.append( (sal_Int32
) nMethodId
);
183 sMessage
.appendAscii( " )" );
184 m_pBridgeImpl
->addError( sMessage
.makeStringAndClear() );
186 OSL_ENSURE( 0 , "unknown method type description" );
190 if( typelib_TypeClass_INTERFACE_ATTRIBUTE
== pMemberType
->aBase
.eTypeClass
)
192 // Note: pMapMemberIndexToFunctionIndex always contains the function
193 // index of the attribute getter! setter function index is getter index
195 *ppAttributeType
= (typelib_InterfaceAttributeTypeDescription
*) pMemberType
;
197 pInterfaceType
->pMapMemberIndexToFunctionIndex
[nMemberIndex
] == nMethodId
);
201 *ppMethodType
= (typelib_InterfaceMethodTypeDescription
*) pMemberType
;
204 TYPELIB_DANGER_RELEASE( (typelib_TypeDescription
* )pInterfaceType
);
208 OReaderThread::OReaderThread( remote_Connection
*pConnection
,
209 uno_Environment
*pEnvRemote
,
210 OWriterThread
* pWriterThread
) :
211 m_pConnection( pConnection
),
212 m_pEnvRemote( pEnvRemote
),
213 m_pWriterThread( pWriterThread
),
214 m_bDestroyMyself( sal_False
),
215 m_bContinue( sal_True
),
216 m_pBridgeImpl((struct urp_BridgeImpl
*)
217 ((remote_Context
*)pEnvRemote
->pContext
)->m_pBridgeImpl
),
218 m_unmarshal( m_pBridgeImpl
, m_pEnvRemote
, ::bridges_remote::remote_createStub
)
220 m_pEnvRemote
->acquireWeak( m_pEnvRemote
);
221 m_pConnection
->acquire( m_pConnection
);
222 #if OSL_DEBUG_LEVEL > 1
223 thisCounter
.acquire();
228 OReaderThread::~OReaderThread( )
230 m_pEnvRemote
->releaseWeak( m_pEnvRemote
);
231 #if OSL_DEBUG_LEVEL > 1
232 thisCounter
.release();
236 // may only be called in the callstack of this thread !!!!!
237 // run() -> dispose() -> destroyYourself()
238 void OReaderThread::destroyYourself()
240 m_bDestroyMyself
= sal_True
;
241 m_pConnection
->release( m_pConnection
);
243 m_bContinue
= sal_False
;
246 void OReaderThread::onTerminated()
248 if( m_bDestroyMyself
)
255 void OReaderThread::disposeEnvironment()
257 struct remote_Context
*pContext
=
258 ( struct remote_Context
* ) m_pEnvRemote
->pContext
;
259 m_bContinue
= sal_False
;
260 if( ! pContext
->m_pBridgeImpl
->m_bDisposed
)
262 uno_Environment
*pEnvRemote
= 0;
263 m_pEnvRemote
->harden( &pEnvRemote
, m_pEnvRemote
);
266 pEnvRemote
->dispose( m_pEnvRemote
);
267 pEnvRemote
->release( m_pEnvRemote
);
271 // environment has been disposed eitherway !
276 inline sal_Bool
OReaderThread::readBlock( sal_Int32
*pnMessageCount
)
278 m_unmarshal
.setSize( 8 );
279 if( 8 != m_pConnection
->read( m_pConnection
, m_unmarshal
.getBuffer(), 8 ) )
281 OUString
s( RTL_CONSTASCII_USTRINGPARAM( "Unexpected connection closure" ) );
282 m_pBridgeImpl
->addError( s
);
287 m_unmarshal
.unpackInt32( &nSize
);
288 m_unmarshal
.unpackInt32( pnMessageCount
);
293 // no exception can be thrown, because there is no thread id, which could be
294 // used. -> terminate !
296 s
.appendAscii( "Packet-size too big (" );
297 s
.append( (sal_Int64
) (sal_uInt32
) nSize
);
298 s
.append( sal_Unicode( ')' ) );
299 m_pBridgeImpl
->addError( s
.makeStringAndClear() );
300 OSL_ENSURE( 0 , "urp bridge: Packet-size too big" );
306 // normal termination !
310 // allocate the necessary memory
311 if( ! m_unmarshal
.setSize( nSize
) )
314 s
.appendAscii( "Packet-size too big, couln't allocate necessary memory (" );
315 s
.append( (sal_Int64
) (sal_uInt32
) nSize
);
316 s
.append( sal_Unicode( ')' ) );
317 m_pBridgeImpl
->addError( s
.makeStringAndClear() );
318 OSL_ENSURE( 0 , "urp bridge: messages size too large, terminating connection" );
322 sal_Int32 nRead
= m_pConnection
->read( m_pConnection
, m_unmarshal
.getBuffer() , nSize
);
327 s
.appendAscii( "Unexpected connection closure, inconsistent packet (" );
328 s
.append( (sal_Int64
) (sal_uInt32
) nSize
);
329 s
.appendAscii( " asked, " );
330 s
.append( (sal_Int64
) (sal_uInt32
) nRead
);
331 s
.appendAscii( " got )" );
332 m_pBridgeImpl
->addError( s
.makeStringAndClear() );
333 // couldn't get the asked amount of bytes, quit
334 // should only occur, when the environment has already been disposed
335 OSL_ENSURE( m_pBridgeImpl
->m_bDisposed
, "urp bridge: inconsistent packet, terminating connection." );
341 inline sal_Bool
OReaderThread::readFlags( struct MessageFlags
*pFlags
)
344 if( ! m_unmarshal
.unpackInt8( &nBitField
) )
346 m_pBridgeImpl
->addError( "Unexpected end of message header (1)" );
350 if( HDRFLAG_LONGHEADER
& nBitField
)
352 // this is a long header, interpret the byte as bitfield
353 pFlags
->bTid
= (HDRFLAG_NEWTID
& nBitField
);
354 pFlags
->bRequest
= (HDRFLAG_REQUEST
& nBitField
);
356 if( pFlags
->bRequest
)
359 pFlags
->bType
= ( HDRFLAG_NEWTYPE
& nBitField
);
360 pFlags
->bOid
= ( HDRFLAG_NEWOID
& nBitField
);
361 pFlags
->bIgnoreCache
= ( HDRFLAG_IGNORECACHE
& nBitField
);
362 pFlags
->bMoreFlags
= ( HDRFLAG_MOREFLAGS
& nBitField
);
364 if( pFlags
->bMoreFlags
)
366 // another byte with flags
368 if( ! m_unmarshal
.unpackInt8( &moreFlags
) )
370 m_pBridgeImpl
->addError( "Unexpected end of message header (2)" );
373 pFlags
->bSynchronous
= ( HDRFLAG_SYNCHRONOUS
& moreFlags
);
374 pFlags
->bMustReply
= ( HDRFLAG_MUSTREPLY
& moreFlags
);
375 OSL_ENSURE( pFlags
->bSynchronous
&& pFlags
->bMustReply
||
376 ! pFlags
->bSynchronous
&& !pFlags
->bMustReply
,
377 "urp-bridge : customized calls currently not supported !");
380 if( HDRFLAG_LONGMETHODID
& nBitField
)
382 // methodid as unsigned short
383 if( ! m_unmarshal
.unpackInt16( &(pFlags
->nMethodId
)) )
385 m_pBridgeImpl
->addError( "Unexpected end of message header (3)" );
392 if( ! m_unmarshal
.unpackInt8( &id
) )
394 m_pBridgeImpl
->addError( "Unexpected end of message header (4)" );
397 pFlags
->nMethodId
= (sal_uInt16
) id
;
403 pFlags
->bRequest
= sal_False
;
404 pFlags
->bException
= ( HDRFLAG_EXCEPTION
& nBitField
);
410 pFlags
->bRequest
= sal_True
;
411 if( 0x40 & nBitField
)
414 if( ! m_unmarshal
.unpackInt8( &lower
) )
416 m_pBridgeImpl
->addError( "Unexpected end of message header (5)" );
419 pFlags
->nMethodId
= ( nBitField
& 0x3f ) << 8 | lower
;
423 pFlags
->nMethodId
= ( nBitField
& 0x3f );
429 void OReaderThread::run()
431 // This vars are needed to hold oid,tid and type information, which should not be cached.
432 Type lastTypeNoCache
;
433 OUString lastOidNoCache
;
434 ByteSequence lastTidNoCache
;
438 sal_Int32 nMessageCount
;
439 if( ! readBlock( &nMessageCount
) )
441 disposeEnvironment();
445 uno_Environment
*pEnvRemote
= 0;
446 m_pEnvRemote
->harden( &pEnvRemote
, m_pEnvRemote
);
449 // environment has been disposed already, quit here
452 ServerMultiJob
*pMultiJob
= 0;
453 remote_Interface
*pLastRemoteI
= 0;
454 while( ! m_unmarshal
.finished() )
456 #ifdef BRIDGES_URP_PROT
457 sal_uInt32 nLogStart
= m_unmarshal
.getPos();
458 sal_Bool bIsOneWay
= sal_False
;
459 OUString sMemberName
;
463 if( ! readFlags( &flags
) )
465 m_pBridgeImpl
->addError( "incomplete message, skipping block" );
466 OSL_ENSURE ( 0 , "urp-bridge : incomplete message, skipping block" );
470 // use these ** to access the ids fast ( avoid acquire/release calls )
471 sal_Sequence
**ppLastTid
= flags
.bIgnoreCache
?
472 (sal_Sequence
**) &lastTidNoCache
:
473 (sal_Sequence
**) &(m_pBridgeImpl
->m_lastInTid
);
474 rtl_uString
**ppLastOid
= flags
.bIgnoreCache
?
475 (rtl_uString
** ) &lastOidNoCache
:
476 (rtl_uString
** ) &(m_pBridgeImpl
->m_lastInOid
);
477 typelib_TypeDescriptionReference
**ppLastType
=
479 (typelib_TypeDescriptionReference
** ) &lastTypeNoCache
:
480 (typelib_TypeDescriptionReference
** ) &(m_pBridgeImpl
->m_lastInType
);
485 typelib_TypeDescriptionReference
*pTypeRef
= 0;
486 if( m_unmarshal
.unpackType( &pTypeRef
) )
488 // release the old type
489 typelib_typedescriptionreference_release( *ppLastType
);
491 *ppLastType
= pTypeRef
;
493 // no release on pTypeRef necessary (will be released by type dtor)
497 typelib_typedescriptionreference_release( pTypeRef
);
498 m_pBridgeImpl
->addError( "error during unpacking (maybe cached) interface type" );
499 OSL_ENSURE( 0 , "urp-bridge : error during unpacking interface type, terminating connection" );
500 disposeEnvironment();
503 if( m_pBridgeImpl
->m_lastInType
.getTypeClass() != TypeClass_INTERFACE
)
505 OUStringBuffer sMessage
;
506 sMessage
.appendAscii( "interface type is not of typeclass interface (" );
507 sMessage
.append( (sal_Int32
) m_pBridgeImpl
->m_lastInType
.getTypeClass() );
508 m_pBridgeImpl
->addError( sMessage
.makeStringAndClear() );
509 OSL_ENSURE( 0 , "urp-bridge : not an interface type" );
510 disposeEnvironment();
516 rtl_uString
*pOid
= 0;
517 if( m_unmarshal
.unpackOid( &pOid
) )
519 rtl_uString_release( *ppLastOid
);
524 rtl_uString_release( pOid
);
525 m_pBridgeImpl
->addError( "error during unpacking (maybe cached) oid" );
526 OSL_ENSURE( 0 , "urp-bridge : error during unpacking cached data, terminating connection" );
527 disposeEnvironment();
534 sal_Sequence
*pSeq
= 0;
535 if( m_unmarshal
.unpackTid( &pSeq
) )
537 rtl_byte_sequence_release( *ppLastTid
);
542 rtl_byte_sequence_release( pSeq
);
544 m_pBridgeImpl
->addError( "error during unpacking (maybe cached) tid" );
545 OSL_ENSURE( 0 , "urp-bridge : error during unpacking cached data, terminating connection" );
546 disposeEnvironment();
554 bool bHasCc
= m_pBridgeImpl
->m_properties
.bCurrentContext
555 && flags
.nMethodId
!= REMOTE_RELEASE_METHOD_INDEX
556 && !rtl::OUString( *ppLastOid
).equalsAsciiL(
557 RTL_CONSTASCII_STRINGPARAM(
558 g_NameOfUrpProtocolPropertiesObject
) );
559 remote_Interface
* pCc
= 0;
562 typelib_TypeDescription
* pType
= 0;
565 XCurrentContext::static_type().getTypeLibType() );
566 bool ok
= m_unmarshal
.unpack( &pCc
, pType
);
567 TYPELIB_DANGER_RELEASE( pType
);
572 ("urp_bridge: error while unpacking current"
574 disposeEnvironment();
579 //--------------------------
581 //--------------------------
582 // get the membertypedescription
583 typelib_InterfaceMethodTypeDescription
*pMethodType
= 0;
584 typelib_InterfaceAttributeTypeDescription
*pAttributeType
= 0;
585 sal_Bool bIsSetter
= sal_False
;
587 if( getMemberTypeDescription(
588 &pAttributeType
, &pMethodType
, &bIsSetter
,
589 flags
.nMethodId
, *ppLastType
) )
591 if( ! pLastRemoteI
|| flags
.bOid
|| flags
.bType
)
593 // a new interface must be retrieved
595 // retrieve the interface NOW from the environment
596 // (avoid race conditions : oneway followed by release )
597 typelib_InterfaceTypeDescription
*pInterfaceType
= 0;
600 (typelib_TypeDescription
** ) &pInterfaceType
,
602 if( !pInterfaceType
)
604 OUStringBuffer sMessage
;
605 sMessage
.appendAscii( "Couldn't retrieve type description for type " );
606 sMessage
.append( OUString( (*ppLastType
)->pTypeName
) );
607 m_pBridgeImpl
->addError( sMessage
.makeStringAndClear() );
610 disposeEnvironment();
611 pLastRemoteI
= 0; // stubs are released during dispose eitherway
614 pEnvRemote
->pExtEnv
->getRegisteredInterface(
615 pEnvRemote
->pExtEnv
, ( void ** ) &pLastRemoteI
,
616 *ppLastOid
, pInterfaceType
);
617 TYPELIB_DANGER_RELEASE( (typelib_TypeDescription
* )pInterfaceType
);
620 REMOTE_RELEASE_METHOD_INDEX
!= flags
.nMethodId
&&
621 0 == rtl_ustr_ascii_compare_WithLength(
622 (*ppLastOid
)->buffer
, (*ppLastOid
)->length
, g_NameOfUrpProtocolPropertiesObject
) )
624 // check for bridge internal propertyobject
625 pLastRemoteI
= m_pBridgeImpl
->m_pPropertyObject
;
626 pLastRemoteI
->acquire( pLastRemoteI
);
627 flags
.bBridgePropertyCall
= sal_True
;
630 // NOTE : Instance provider is called in the executing thread
631 // Otherwise, instance provider may block the bridge
634 sal_Bool bCallIsOneway
= sal_False
;
635 if( flags
.bMoreFlags
)
637 // flags override the default !
638 bCallIsOneway
= ! flags
.bSynchronous
;
640 else if( pMethodType
&& pMethodType
->bOneWay
)
642 bCallIsOneway
= sal_True
;
645 if( pMultiJob
&& ! flags
.bTid
&& bCallIsOneway
&& ! pMultiJob
->isFull())
647 // add to the existing multijob, nothing to do here
651 // create a new multijob
654 // there exists an old one, start it first.
655 pMultiJob
->initiate();
658 pMultiJob
= new ServerMultiJob(
660 static_cast< remote_Context
* >(
661 pEnvRemote
->pContext
),
662 *ppLastTid
, m_pBridgeImpl
, &m_unmarshal
,
666 pMultiJob
->setCurrentContext( bHasCc
, pCc
);
667 pMultiJob
->setIgnoreCache( flags
.bIgnoreCache
);
668 pMultiJob
->setType( *ppLastType
);
671 pMultiJob
->setMethodType( pMethodType
,
672 REMOTE_RELEASE_METHOD_INDEX
== flags
.nMethodId
,
675 else if( pAttributeType
)
677 pMultiJob
->setAttributeType( pAttributeType
, bIsSetter
, bCallIsOneway
);
685 pMultiJob
->setInterface( pLastRemoteI
);
687 pMultiJob
->setOid( *ppLastOid
);
688 } /* getMemberTypeDescription */
693 pLastRemoteI
= 0; // stubs are released during dispose eitherway
694 disposeEnvironment();
697 #ifdef BRIDGES_URP_PROT
698 bIsOneWay
= pMethodType
&& pMethodType
->bOneWay
;
699 sMemberName
= pMethodType
?
700 pMethodType
->aBase
.pMemberName
:
701 pAttributeType
->aBase
.pMemberName
;
702 sal_uInt32 nLogHeader
= m_unmarshal
.getPos();
704 if( ! pMultiJob
->extract( ) )
706 // severe error during extracting, dispose
709 pLastRemoteI
= 0; // stubs are released during dispose eitherway
710 disposeEnvironment();
714 #ifdef BRIDGES_URP_PROT
715 urp_logServingRequest(
716 m_pBridgeImpl
, m_unmarshal
.getPos() - nLogStart
,
717 m_unmarshal
.getPos() - nLogHeader
,
721 if ( flags
.bBridgePropertyCall
)
723 // call to the bridge internal object.
724 // these calls MUST be executed within the dispatcher thread in order
725 // to synchronize properly with protocol changes
726 // NOTE : Threadid is not preserved for this call.
728 // lock the marshaling NOW !
730 MutexGuard
guard( m_pBridgeImpl
->m_marshalingMutex
);
732 pMultiJob
->execute();
734 if( m_pBridgeImpl
->m_pPropertyObject
->changesHaveBeenCommited() )
737 props
= m_pBridgeImpl
->m_pPropertyObject
->getCommitedChanges();
739 // This call modified the protocol, apply the changes NOW !
740 m_pBridgeImpl
->applyProtocolChanges( props
);
749 //--------------------------
751 //--------------------------
754 pMultiJob
->initiate();
759 pLastRemoteI
->release( pLastRemoteI
);
762 ClientJob
*pClientJob
=
763 m_pBridgeImpl
->m_clientJobContainer
.remove( *( ByteSequence
* )ppLastTid
);
765 // Bridge MUST be already disposed, otherwise we got a wrong threadid
767 OSL_ASSERT( pClientJob
|| m_pBridgeImpl
->m_bDisposed
);
770 OUStringBuffer
error( 128 );
771 error
.appendAscii( "ThreadID " );
772 OString o
= byteSequence2HumanReadableString( *(ByteSequence
* )ppLastTid
);
773 error
.appendAscii( o
.getStr(), o
.getLength() );
774 error
.appendAscii( " unknown, so couldn't unmarshal reply" );
775 m_pBridgeImpl
->addError( error
.makeStringAndClear() );
777 disposeEnvironment();
781 pClientJob
->m_bExceptionOccured
= flags
.bException
;
783 pClientJob
->setUnmarshal( &m_unmarshal
);
784 #ifdef BRIDGES_URP_PROT
785 sMemberName
= pClientJob
->m_pMethodType
?
786 pClientJob
->m_pMethodType
->aBase
.pMemberName
:
787 pClientJob
->m_pAttributeType
->aBase
.pMemberName
;
788 sal_uInt32 nLogHeader
= m_unmarshal
.getPos();
790 if( ! pClientJob
->extract( ) )
792 // severe error during extracting, dispose
793 pLastRemoteI
= 0; // stubs are released during dispose eitherway
794 disposeEnvironment();
797 #ifdef BRIDGES_URP_PROT
799 m_pBridgeImpl
, m_unmarshal
.getPos() - nLogStart
,
800 m_unmarshal
.getPos() - nLogHeader
, sMemberName
);
802 sal_Bool bBridgePropertyCallAndWaitingForReply
=
803 pClientJob
->isBridgePropertyCall();
805 pClientJob
->initiate();
807 if( bBridgePropertyCallAndWaitingForReply
)
809 // NOTE : This must be the reply for commit change. The new properties
810 // are now applied by the clientJob thread, but the reader thread
811 // must wait for it, because the next message on the wire already
812 // uses the new protocol settings.
813 // waiting for the commit change reply
814 m_pBridgeImpl
->m_pPropertyObject
->waitUntilChangesAreCommitted();
817 } // end while( !m_unmarshal.finished() )
820 pLastRemoteI
->release( pLastRemoteI
);
823 pMultiJob
->initiate();
826 pEnvRemote
->release( pEnvRemote
);
831 m_pConnection
->release( m_pConnection
);