Update ooo320-m1
[ooovba.git] / bridges / source / remote / urp / urp_reader.cxx
blob3837f22b94e149dce846c6dd3592d5da5b17cca9
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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"
33 #include <string.h>
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" );
60 #endif
62 namespace bridges_urp
65 /**
66 * This callback is used to ensure, that the release call is sent for the correct type.
68 ***/
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 );
80 struct MessageFlags
82 sal_uInt16 nMethodId;
83 sal_Bool bRequest;
84 sal_Bool bType;
85 sal_Bool bOid;
86 sal_Bool bTid;
87 sal_Bool bException;
88 sal_Bool bMustReply;
89 sal_Bool bSynchronous;
90 sal_Bool bMoreFlags;
91 sal_Bool bIgnoreCache;
92 sal_Bool bBridgePropertyCall;
93 ///--------------------------
94 inline MessageFlags()
96 bTid = sal_False;
97 bOid = sal_False;
98 bType = sal_False;
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" );
121 return sal_False;
124 typelib_InterfaceTypeDescription *pInterfaceType = 0;
125 TYPELIB_DANGER_GET(
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 " );
134 return sal_False;
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" );
153 return sal_False;
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" );
169 return sal_False;
172 typelib_InterfaceMemberTypeDescription *pMemberType = 0;
173 typelib_typedescriptionreference_getDescription(
174 (typelib_TypeDescription **) &pMemberType,pInterfaceType->ppAllMembers[nMemberIndex]);
176 if(! pMemberType )
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" );
187 return sal_False;
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
194 // + 1.
195 *ppAttributeType = (typelib_InterfaceAttributeTypeDescription *) pMemberType;
196 *pbIsSetter = ! (
197 pInterfaceType->pMapMemberIndexToFunctionIndex[nMemberIndex] == nMethodId );
199 else
201 *ppMethodType = (typelib_InterfaceMethodTypeDescription *) pMemberType;
204 TYPELIB_DANGER_RELEASE( (typelib_TypeDescription * )pInterfaceType );
205 return sal_True;
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();
224 #endif
228 OReaderThread::~OReaderThread( )
230 m_pEnvRemote->releaseWeak( m_pEnvRemote );
231 #if OSL_DEBUG_LEVEL > 1
232 thisCounter.release();
233 #endif
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 );
242 m_pConnection = 0;
243 m_bContinue = sal_False;
246 void OReaderThread::onTerminated()
248 if( m_bDestroyMyself )
250 delete this;
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 );
264 if( pEnvRemote )
266 pEnvRemote->dispose( m_pEnvRemote );
267 pEnvRemote->release( m_pEnvRemote );
269 else
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 );
283 return sal_False;
286 sal_Int32 nSize;
287 m_unmarshal.unpackInt32( &nSize );
288 m_unmarshal.unpackInt32( pnMessageCount );
290 if( nSize < 0 )
292 // buffer too big
293 // no exception can be thrown, because there is no thread id, which could be
294 // used. -> terminate !
295 OUStringBuffer s;
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" );
301 return sal_False;
304 if( 0 == nSize )
306 // normal termination !
307 return sal_False;
310 // allocate the necessary memory
311 if( ! m_unmarshal.setSize( nSize ) )
313 OUStringBuffer s;
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" );
319 return sal_False;
322 sal_Int32 nRead = m_pConnection->read( m_pConnection , m_unmarshal.getBuffer() , nSize );
324 if( nSize != nRead )
326 OUStringBuffer s;
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." );
336 return sal_False;
338 return sal_True;
341 inline sal_Bool OReaderThread::readFlags( struct MessageFlags *pFlags )
343 sal_uInt8 nBitField;
344 if( ! m_unmarshal.unpackInt8( &nBitField ) )
346 m_pBridgeImpl->addError( "Unexpected end of message header (1)" );
347 return sal_False;
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 )
358 // request
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
367 sal_Int8 moreFlags;
368 if( ! m_unmarshal.unpackInt8( &moreFlags ) )
370 m_pBridgeImpl->addError( "Unexpected end of message header (2)" );
371 return sal_False;
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)" );
386 return sal_False;
389 else
391 sal_uInt8 id;
392 if( ! m_unmarshal.unpackInt8( &id ) )
394 m_pBridgeImpl->addError( "Unexpected end of message header (4)" );
395 return sal_False;
397 pFlags->nMethodId = (sal_uInt16) id;
400 else
402 // reply
403 pFlags->bRequest = sal_False;
404 pFlags->bException = ( HDRFLAG_EXCEPTION & nBitField );
407 else
409 // short request
410 pFlags->bRequest = sal_True;
411 if( 0x40 & nBitField )
413 sal_uInt8 lower;
414 if( ! m_unmarshal.unpackInt8( &lower ) )
416 m_pBridgeImpl->addError( "Unexpected end of message header (5)" );
417 return sal_False;
419 pFlags->nMethodId = ( nBitField & 0x3f ) << 8 | lower;
421 else
423 pFlags->nMethodId = ( nBitField & 0x3f );
426 return sal_True;
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;
436 while( m_bContinue )
438 sal_Int32 nMessageCount;
439 if( ! readBlock( &nMessageCount ) )
441 disposeEnvironment();
442 break;
445 uno_Environment *pEnvRemote = 0;
446 m_pEnvRemote->harden( &pEnvRemote , m_pEnvRemote );
447 if( !pEnvRemote )
449 // environment has been disposed already, quit here
450 break;
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;
460 #endif
461 MessageFlags flags;
463 if( ! readFlags( &flags ) )
465 m_pBridgeImpl->addError( "incomplete message, skipping block" );
466 OSL_ENSURE ( 0 , "urp-bridge : incomplete message, skipping block" );
467 break;
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 =
478 flags.bIgnoreCache ?
479 (typelib_TypeDescriptionReference ** ) &lastTypeNoCache :
480 (typelib_TypeDescriptionReference ** ) &(m_pBridgeImpl->m_lastInType);
482 // get new type
483 if( flags.bType )
485 typelib_TypeDescriptionReference *pTypeRef = 0;
486 if( m_unmarshal.unpackType( &pTypeRef ) )
488 // release the old type
489 typelib_typedescriptionreference_release( *ppLastType );
490 // set the new type
491 *ppLastType = pTypeRef;
493 // no release on pTypeRef necessary (will be released by type dtor)
495 else
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();
501 break;
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();
511 break;
514 if( flags.bOid )
516 rtl_uString *pOid = 0;
517 if( m_unmarshal.unpackOid( &pOid ) )
519 rtl_uString_release( *ppLastOid );
520 *ppLastOid = pOid;
522 else
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();
528 break;
532 if( flags.bTid )
534 sal_Sequence *pSeq = 0;
535 if( m_unmarshal.unpackTid( &pSeq ) )
537 rtl_byte_sequence_release( *ppLastTid );
538 *ppLastTid = pSeq;
540 else
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();
547 break;
551 // do the job
552 if( flags.bRequest )
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;
560 if ( bHasCc )
562 typelib_TypeDescription * pType = 0;
563 TYPELIB_DANGER_GET(
564 &pType,
565 XCurrentContext::static_type().getTypeLibType() );
566 bool ok = m_unmarshal.unpack( &pCc, pType );
567 TYPELIB_DANGER_RELEASE( pType );
568 if ( !ok )
570 OSL_ENSURE(
571 false,
572 ("urp_bridge: error while unpacking current"
573 " context") );
574 disposeEnvironment();
575 break;
579 //--------------------------
580 // handle request
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;
599 TYPELIB_DANGER_GET(
600 (typelib_TypeDescription ** ) &pInterfaceType ,
601 *ppLastType );
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() );
608 delete pMultiJob;
609 pMultiJob = 0;
610 disposeEnvironment();
611 pLastRemoteI = 0; // stubs are released during dispose eitherway
612 break;
614 pEnvRemote->pExtEnv->getRegisteredInterface(
615 pEnvRemote->pExtEnv, ( void ** ) &pLastRemoteI,
616 *ppLastOid, pInterfaceType );
617 TYPELIB_DANGER_RELEASE( (typelib_TypeDescription * )pInterfaceType );
619 if( !pLastRemoteI &&
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
649 else
651 // create a new multijob
652 if( pMultiJob )
654 // there exists an old one, start it first.
655 pMultiJob->initiate();
658 pMultiJob = new ServerMultiJob(
659 pEnvRemote,
660 static_cast< remote_Context * >(
661 pEnvRemote->pContext ),
662 *ppLastTid, m_pBridgeImpl, &m_unmarshal,
663 nMessageCount );
666 pMultiJob->setCurrentContext( bHasCc, pCc );
667 pMultiJob->setIgnoreCache( flags.bIgnoreCache );
668 pMultiJob->setType( *ppLastType );
669 if( pMethodType )
671 pMultiJob->setMethodType( pMethodType ,
672 REMOTE_RELEASE_METHOD_INDEX == flags.nMethodId,
673 bCallIsOneway );
675 else if( pAttributeType )
677 pMultiJob->setAttributeType( pAttributeType, bIsSetter, bCallIsOneway );
679 else
681 OSL_ASSERT( 0 );
684 if( pLastRemoteI )
685 pMultiJob->setInterface( pLastRemoteI );
686 else
687 pMultiJob->setOid( *ppLastOid );
688 } /* getMemberTypeDescription */
689 else
691 delete pMultiJob;
692 pMultiJob = 0;
693 pLastRemoteI = 0; // stubs are released during dispose eitherway
694 disposeEnvironment();
695 break;
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();
703 #endif
704 if( ! pMultiJob->extract( ) )
706 // severe error during extracting, dispose
707 delete pMultiJob;
708 pMultiJob = 0;
709 pLastRemoteI = 0; // stubs are released during dispose eitherway
710 disposeEnvironment();
711 break;
714 #ifdef BRIDGES_URP_PROT
715 urp_logServingRequest(
716 m_pBridgeImpl, m_unmarshal.getPos() - nLogStart,
717 m_unmarshal.getPos() - nLogHeader,
718 !bIsOneWay,
719 sMemberName );
720 #endif
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() )
736 Properties props;
737 props = m_pBridgeImpl->m_pPropertyObject->getCommitedChanges();
739 // This call modified the protocol, apply the changes NOW !
740 m_pBridgeImpl->applyProtocolChanges( props );
743 delete pMultiJob;
744 pMultiJob = 0;
747 else
749 //--------------------------
750 // handle reply
751 //--------------------------
752 if( pMultiJob )
754 pMultiJob->initiate();
755 pMultiJob = 0;
757 if( pLastRemoteI )
759 pLastRemoteI->release( pLastRemoteI );
760 pLastRemoteI = 0;
762 ClientJob *pClientJob =
763 m_pBridgeImpl->m_clientJobContainer.remove( *( ByteSequence * )ppLastTid );
765 // Bridge MUST be already disposed, otherwise we got a wrong threadid
766 // from remote !
767 OSL_ASSERT( pClientJob || m_pBridgeImpl->m_bDisposed );
768 if( ! pClientJob )
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() );
776 pLastRemoteI = 0;
777 disposeEnvironment();
778 break;
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();
789 #endif
790 if( ! pClientJob->extract( ) )
792 // severe error during extracting, dispose
793 pLastRemoteI = 0; // stubs are released during dispose eitherway
794 disposeEnvironment();
795 break;
797 #ifdef BRIDGES_URP_PROT
798 urp_logGettingReply(
799 m_pBridgeImpl, m_unmarshal.getPos() - nLogStart,
800 m_unmarshal.getPos() - nLogHeader, sMemberName );
801 #endif
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() )
819 if( pLastRemoteI )
820 pLastRemoteI->release( pLastRemoteI );
822 if( pMultiJob )
823 pMultiJob->initiate();
825 if( pEnvRemote )
826 pEnvRemote->release( pEnvRemote );
829 if( m_pConnection )
831 m_pConnection->release( m_pConnection );
832 m_pConnection = 0;