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_job.cxx,v $
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 <osl/mutex.hxx>
38 #include <rtl/alloc.h>
39 #include <rtl/ustrbuf.hxx>
41 #include <uno/current_context.h>
42 #include <uno/current_context.hxx>
43 #include <uno/threadpool.h>
45 #include <bridges/cpp_uno/type_misc.hxx>
46 #include <bridges/remote/proxy.hxx>
48 #include <com/sun/star/uno/Any.hxx>
49 #include <com/sun/star/uno/XCurrentContext.hpp>
50 #include <com/sun/star/lang/DisposedException.hpp>
52 #include "urp_job.hxx"
53 #include "urp_bridgeimpl.hxx"
54 #include "urp_writer.hxx"
55 #include "urp_dispatch.hxx"
56 #include "urp_log.hxx"
57 #include "urp_marshal.hxx"
58 #include "urp_propertyobject.hxx"
59 #include "urp_reader.hxx"
61 using namespace ::std
;
62 using namespace ::rtl
;
63 using namespace ::osl
;
64 using namespace ::com::sun::star::uno
;
66 using namespace bridges_urp
;
70 static void SAL_CALL
doit(void * job
) {
71 ServerMultiJob
* p
= static_cast< ServerMultiJob
* >(job
);
80 static sal_Bool
isDisposedExceptionDescriptionAvail( const Type
&type
)
82 static sal_Bool bInit
;
83 static sal_Bool bReturn
;
84 // we don't care for thread safety here, as both threads must come
88 typelib_TypeDescription
*pTD
= 0;
89 typelib_typedescriptionreference_getDescription( & pTD
, type
.getTypeLibType() );
93 typelib_typedescription_release( pTD
);
104 //--------------------------------------------------------------------------------------
105 static void prepareRuntimeExceptionClientSide( uno_Any
**ppException
, const OUString
&s
)
107 com::sun::star::lang::DisposedException
exception( s
, Reference
< XInterface
> () );
108 Type type
= ::getCppuType( &exception
);
109 if( !isDisposedExceptionDescriptionAvail( type
) )
111 // if it is not available (probably missing type library),
112 // then we are satisfied with throwing a normal runtime exception,
113 // for which cppu provides a static description
114 type
= getCppuType( ( RuntimeException
* ) 0 );
116 uno_type_any_construct( *ppException
, &exception
, type
.getTypeLibType() , 0 );
120 Job::Job( uno_Environment
*pEnvRemote
,
121 remote_Context
*pContext
,
123 struct urp_BridgeImpl
*pBridgeImpl
,
124 Unmarshal
*pUnmarshal
)
125 : m_pContext( pContext
)
126 , m_pUnmarshal( pUnmarshal
)
127 , m_pBridgeImpl( pBridgeImpl
)
129 , m_counter( pEnvRemote
)
133 m_pContext
->aBase
.acquire( &m_pContext
->aBase
);
136 rtl_byte_sequence_acquire( pTid
);
142 rtl_byte_sequence_release( m_pTid
);
145 m_pContext
->aBase
.release( &m_pContext
->aBase
);
152 //--------------------------------------------------------------------------------------
153 sal_Bool
ClientJob::extract( )
155 sal_Bool bReturn
= sal_True
;
156 //-------------------------------
157 // Handle the reply, unpack data
158 //-------------------------------
159 if( m_bExceptionOccured
)
161 bReturn
= m_pUnmarshal
->unpackAny( *m_ppException
);
165 //---------------------------------
167 //---------------------------------
170 if( m_pMethodType
->pReturnTypeRef
->eTypeClass
!= typelib_TypeClass_VOID
)
172 typelib_TypeDescription
*pType
= 0;
173 TYPELIB_DANGER_GET( &pType
, m_pMethodType
->pReturnTypeRef
);
174 bReturn
= m_pUnmarshal
->unpack( m_pReturn
, pType
) && bReturn
;
175 TYPELIB_DANGER_RELEASE( pType
);
180 for( i
= 0 ; i
< m_pMethodType
->nParams
; i
++ )
182 if( m_pMethodType
->pParams
[i
].bOut
)
184 typelib_TypeDescription
*pType
= 0;
185 TYPELIB_DANGER_GET( &pType
, m_pMethodType
->pParams
[i
].pTypeRef
);
186 if( m_pMethodType
->pParams
[i
].bIn
)
188 uno_destructData( m_ppArgs
[i
] , pType
, ::bridges_remote::remote_release
);
190 bReturn
= m_pUnmarshal
->unpack( m_ppArgs
[i
] , pType
) && bReturn
;
191 TYPELIB_DANGER_RELEASE( pType
);
195 else if( m_pAttributeType
&& m_pReturn
)
197 typelib_TypeDescription
*pType
= 0;
198 TYPELIB_DANGER_GET( &pType
, m_pAttributeType
->pAttributeTypeRef
);
199 bReturn
= m_pUnmarshal
->unpack( m_pReturn
, pType
) && bReturn
;
200 TYPELIB_DANGER_RELEASE( pType
);
202 else if( m_pAttributeType
&& m_ppArgs
)
214 //-------------------------------------------------------------------------------------------
215 void ClientJob::initiate()
217 uno_threadpool_putJob( m_pBridgeImpl
->m_hThreadPool
, m_pTid
, this, 0, sal_False
);
220 //--------------------------------------------------------------------------------------------
221 sal_Bool
ClientJob::pack()
223 sal_Bool bSuccess
= sal_True
;
224 MutexGuard
guard( m_pBridgeImpl
->m_marshalingMutex
);
227 REMOTE_RELEASE_METHOD_INDEX
== m_pMethodType
->aBase
.nPosition
&&
228 ! m_pBridgeImpl
->m_bDisposed
&&
229 m_pBridgeImpl
->m_pWriter
->getIdentifier() != ::osl::Thread::getCurrentIdentifier() )
231 // all release calls are delegated to the writer thread to avoid
232 // multiple synchron calls with the same thread id and reentrant
233 // marshaling (in case during destruction of parameters a release is
235 m_pBridgeImpl
->m_pWriter
->insertReleaseRemoteCall(
236 m_pOid
, m_pInterfaceType
->aBase
.pWeakRef
);
238 // No waiting, please
241 else if ( m_pMethodType
&&
242 REMOTE_RELEASE_METHOD_INDEX
== m_pMethodType
->aBase
.nPosition
&&
243 m_pBridgeImpl
->m_bDisposed
)
245 // no exception for release calls !
248 else if( m_pBridgeImpl
->m_bDisposed
)
250 OUStringBuffer
buf( 128 );
251 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM( "URP-Bridge: disposed" ) );
252 buf
.append( m_pBridgeImpl
->getErrorsAsString() );
253 prepareRuntimeExceptionClientSide( m_ppException
, buf
.makeStringAndClear() );
257 // build up the flag byte
258 sal_Bool bType
= sal_False
, bOid
= sal_False
, bTid
= sal_False
;
259 sal_uInt8 nFlags
= 0;
260 if( m_pBridgeImpl
->m_lastOutType
.getTypeLibType() != m_pInterfaceType
->aBase
.pWeakRef
&&
261 ! typelib_typedescriptionreference_equals(
262 m_pBridgeImpl
->m_lastOutType
.getTypeLibType(), m_pInterfaceType
->aBase
.pWeakRef
) )
265 nFlags
= nFlags
| HDRFLAG_NEWTYPE
;
268 if( m_pBridgeImpl
->m_lastOutOid
.pData
!= m_pOid
&&
269 rtl_ustr_compare_WithLength( m_pBridgeImpl
->m_lastOutOid
.pData
->buffer
,
270 m_pBridgeImpl
->m_lastOutOid
.pData
->length
,
275 nFlags
= nFlags
| HDRFLAG_NEWOID
;
278 if( m_pBridgeImpl
->m_lastOutTid
.getHandle() != m_pTid
&&
279 !(m_pBridgeImpl
->m_lastOutTid
== *(ByteSequence
*) &(m_pTid
) ) )
282 nFlags
= nFlags
| HDRFLAG_NEWTID
;
286 if( m_bCallingConventionForced
)
288 nFlags
= nFlags
| HDRFLAG_MOREFLAGS
;
290 #ifdef BRIDGES_URP_PROT
291 sal_Int32 nLogStart
= m_pBridgeImpl
->m_blockMarshaler
.getPos();
293 // Short request headers can only handle 14-bit method IDs, so
294 // unconditionally use a long header for method IDs that are too large:
295 if( nFlags
|| m_nMethodIndex
>= 0xC000 )
297 // the flag byte is needed + request
298 nFlags
= nFlags
| HDRFLAG_LONGHEADER
| HDRFLAG_REQUEST
; //
300 // as long as we do not have customized calls, no MOREFLAGS must be set
301 if( m_nMethodIndex
>= 0x100 )
303 nFlags
= nFlags
| HDRFLAG_LONGMETHODID
;
305 m_pBridgeImpl
->m_blockMarshaler
.packInt8( &nFlags
);
307 if( nFlags
& HDRFLAG_MOREFLAGS
)
309 sal_uInt8 nMoreFlags
= 0;
312 nMoreFlags
= HDRFLAG_SYNCHRONOUS
|HDRFLAG_MUSTREPLY
;
314 m_pBridgeImpl
->m_blockMarshaler
.packInt8( &nMoreFlags
);
316 if( nFlags
& HDRFLAG_LONGMETHODID
)
318 sal_uInt16 nMethod
= (sal_uInt16
) m_nMethodIndex
;
319 m_pBridgeImpl
->m_blockMarshaler
.packInt16( &nMethod
);
323 sal_uInt8 nMethod
= (sal_uInt8
) m_nMethodIndex
;
324 m_pBridgeImpl
->m_blockMarshaler
.packInt8( &nMethod
);
329 // no flag byte needed, simply marshal the method index
330 if( m_nMethodIndex
>= 64 )
332 sal_uInt16 nMethod
= ( sal_uInt16
) m_nMethodIndex
;
333 nMethod
= nMethod
| 0x4000;
334 m_pBridgeImpl
->m_blockMarshaler
.packInt16( &nMethod
);
338 sal_uInt8 nMethod
= (sal_uInt8
) m_nMethodIndex
;
339 m_pBridgeImpl
->m_blockMarshaler
.packInt8( &nMethod
);
343 // marshal type,oid,tid
346 m_pBridgeImpl
->m_lastOutType
= m_pInterfaceType
->aBase
.pWeakRef
;
347 m_pBridgeImpl
->m_blockMarshaler
.packType( &(m_pBridgeImpl
->m_lastOutType
) );
351 m_pBridgeImpl
->m_lastOutOid
= *(OUString
*)&m_pOid
;
352 m_pBridgeImpl
->m_blockMarshaler
.packOid( m_pBridgeImpl
->m_lastOutOid
);
356 m_pBridgeImpl
->m_lastOutTid
= *(ByteSequence
*)&(m_pTid
);
357 m_pBridgeImpl
->m_blockMarshaler
.packTid( m_pBridgeImpl
->m_lastOutTid
);
360 if ( m_pBridgeImpl
->m_properties
.bCurrentContext
361 && m_nMethodIndex
!= REMOTE_RELEASE_METHOD_INDEX
365 rtl::OUString
aEnvName( RTL_CONSTASCII_USTRINGPARAM( "urp" ) );
366 bSuccess
= bSuccess
&& uno_getCurrentContext(
367 &pCc
, aEnvName
.pData
, m_pContext
);
368 typelib_TypeDescription
* pType
= 0;
370 &pType
, XCurrentContext::static_type().getTypeLibType() );
371 bSuccess
= bSuccess
&& m_pBridgeImpl
->m_blockMarshaler
.pack(
373 TYPELIB_DANGER_RELEASE( pType
);
376 remote_Interface
* p
= static_cast< remote_Interface
* >( pCc
);
381 // marshal arguments !
382 #ifdef BRIDGES_URP_PROT
383 sal_Int32 nLogHeader
= m_pBridgeImpl
->m_blockMarshaler
.getPos();
388 for( i
= 0 ; i
< m_pMethodType
->nParams
; i
++ )
390 if( m_pMethodType
->pParams
[i
].bIn
)
392 typelib_TypeDescription
*pType
= 0;
393 TYPELIB_DANGER_GET( &pType
, m_pMethodType
->pParams
[i
].pTypeRef
);
397 bSuccess
&& m_pBridgeImpl
->m_blockMarshaler
.pack( m_ppArgs
[i
] , pType
);
398 TYPELIB_DANGER_RELEASE( pType
);
402 bSuccess
= sal_False
;
403 OUStringBuffer
buffer( 128 );
404 buffer
.appendAscii( RTL_CONSTASCII_STRINGPARAM( "no typedescription available for type" ) );
405 buffer
.append( m_pMethodType
->pParams
[i
].pTypeRef
->pTypeName
);
406 m_pBridgeImpl
->addError( buffer
.makeStringAndClear() );
411 else if( m_pAttributeType
&& m_pReturn
)
415 else if( m_pAttributeType
&& m_ppArgs
)
417 typelib_TypeDescription
*pType
= 0;
418 TYPELIB_DANGER_GET( &pType
, m_pAttributeType
->pAttributeTypeRef
);
421 bSuccess
= bSuccess
&& m_pBridgeImpl
->m_blockMarshaler
.pack( m_ppArgs
[0] , pType
);
422 TYPELIB_DANGER_RELEASE( pType
);
426 bSuccess
= sal_False
;
427 OUStringBuffer
buffer( 128 );
428 buffer
.appendAscii( RTL_CONSTASCII_STRINGPARAM( "no typedescription available for type" ) );
429 buffer
.append( m_pAttributeType
->pAttributeTypeRef
->pTypeName
);
430 m_pBridgeImpl
->addError( buffer
.makeStringAndClear() );
438 #ifdef BRIDGES_URP_PROT
439 urp_logCall( m_pBridgeImpl
, m_pBridgeImpl
->m_blockMarshaler
.getPos() - nLogStart
,
440 m_pBridgeImpl
->m_blockMarshaler
.getPos() - nLogHeader
, ! m_bOneway
,
441 m_pMethodType
? m_pMethodType
->aBase
.pMemberName
:
442 m_pAttributeType
->aBase
.pMemberName
);
449 uno_threadpool_attach( m_pBridgeImpl
->m_hThreadPool
);
450 m_pBridgeImpl
->m_clientJobContainer
.add( *(ByteSequence
*)&(m_pTid
), this );
453 m_pBridgeImpl
->m_nMarshaledMessages
++;
454 //---------------------------
455 // Inform the writer thread, that there is some work to do
456 //---------------------------
457 m_pBridgeImpl
->m_pWriter
->touch( ! m_bOneway
);
466 // Something went wrong during packing, which means, that the caches may not be in sync
467 // anymore. So we have no other choice than to dispose the environment.
468 m_pEnvRemote
->dispose( m_pEnvRemote
);
469 OUStringBuffer
buf( 128 );
470 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM( "Error during marshaling " ) );
473 buf
.append( m_pMethodType
->aBase
.aBase
.pTypeName
);
475 else if( m_pAttributeType
)
477 buf
.append( m_pAttributeType
->aBase
.aBase
.pTypeName
);
479 buf
.appendAscii( "\n" );
480 buf
.append( m_pBridgeImpl
->getErrorsAsString() );
481 prepareRuntimeExceptionClientSide( m_ppException
, buf
.makeStringAndClear() );
487 //------------------------------------------------------------------------------------
488 void ClientJob::wait()
490 //---------------------------
491 // Wait for the reply
492 //---------------------------
493 void * pDisposeReason
= 0;
495 uno_threadpool_enter(m_pBridgeImpl
->m_hThreadPool
, &pDisposeReason
);
497 if( ! pDisposeReason
)
499 // thread has been disposed !
500 // avoid leak due continous calling on a disposed reference. The
501 // reply may or may not be within the container. If the reader thread
502 // got into problems during unmarshaling the reply for this request,
503 // it won't be in the container anymore, but it is eiterway safe to call
506 m_pBridgeImpl
->m_clientJobContainer
.remove( *(ByteSequence
*) &m_pTid
);
509 // this is not our job, it is probably one of the callstack below, so
511 m_pBridgeImpl
->m_clientJobContainer
.add( *(ByteSequence
*) &m_pTid
, pJob
);
514 OUStringBuffer
sMessage( 256 );
515 sMessage
.appendAscii( RTL_CONSTASCII_STRINGPARAM( "URP_Bridge : disposed\n" ) );
516 sMessage
.append( m_pBridgeImpl
->getErrorsAsString() );
517 prepareRuntimeExceptionClientSide( m_ppException
, sMessage
.makeStringAndClear() );
518 m_bExceptionOccured
= sal_True
;
522 OSL_ASSERT( pDisposeReason
== (void*)this );
524 if( !m_bExceptionOccured
)
528 uno_threadpool_detach( m_pBridgeImpl
->m_hThreadPool
);
531 //------------------------------------------------------------------------------------
533 //------------------------------------------------------------------------------------
534 ServerMultiJob::ServerMultiJob(
535 uno_Environment
*pEnvRemote
,
536 remote_Context
*pContext
,
538 struct urp_BridgeImpl
*pBridgeImpl
,
539 Unmarshal
*pUnmarshal
,
540 sal_Int32 nMaxMessages
)
541 : Job( pEnvRemote
, pContext
, pTid
, pBridgeImpl
, pUnmarshal
)
542 , m_pEnvRemote( pEnvRemote
)
544 , m_nMaxMessages( nMaxMessages
)
545 , m_nCurrentMemPosition( 0 )
547 m_pEnvRemote
->acquire( m_pEnvRemote
);
548 m_nCurrentMemSize
= MULTIJOB_STANDARD_MEMORY_SIZE
+ m_nMaxMessages
* (
549 MULTIJOB_PER_CALL_MEMORY_SIZE
+ sizeof(ServerJobEntry
) + sizeof(MemberTypeInfo
) );
550 m_pCurrentMem
= ( sal_Int8
* ) rtl_allocateMemory( m_nCurrentMemSize
);
551 m_aEntries
= ( ServerJobEntry
* ) getHeap( m_nMaxMessages
* sizeof( ServerJobEntry
) );
552 m_aTypeInfo
= ( MemberTypeInfo
* ) getHeap( m_nMaxMessages
* sizeof( MemberTypeInfo
) );
555 ServerMultiJob::~ServerMultiJob()
558 for( i
= 0 ; i
< m_nCalls
; i
++ )
560 struct MemberTypeInfo
*const pMTI
= &( m_aTypeInfo
[i
] );
561 struct ServerJobEntry
*const pSJE
= &( m_aEntries
[i
] );
563 if( pSJE
->m_pRemoteI
)
564 pSJE
->m_pRemoteI
->release( pSJE
->m_pRemoteI
);
567 rtl_uString_release( pSJE
->m_pOid
);
569 if( pSJE
->m_pInterfaceTypeRef
)
570 typelib_typedescriptionreference_release( pSJE
->m_pInterfaceTypeRef
);
572 if( pMTI
->m_pInterfaceType
)
573 TYPELIB_DANGER_RELEASE( (typelib_TypeDescription
*)pMTI
->m_pInterfaceType
);
575 for( sal_Int32 iArgs
= 0 ; iArgs
< pMTI
->m_nArgCount
; iArgs
++ )
577 if( pMTI
->m_ppArgType
[iArgs
] )
578 TYPELIB_DANGER_RELEASE( pMTI
->m_ppArgType
[iArgs
] );
580 if( pMTI
->m_pReturnType
)
581 TYPELIB_DANGER_RELEASE( pMTI
->m_pReturnType
);
583 if( pMTI
->m_pMethodType
)
584 typelib_typedescription_release( (typelib_TypeDescription
*)pMTI
->m_pMethodType
);
585 if( pMTI
->m_pAttributeType
)
586 typelib_typedescription_release( (typelib_TypeDescription
*)pMTI
->m_pAttributeType
);
589 rtl_freeMemory( m_pCurrentMem
);
590 for( list
< sal_Int8
*>::iterator ii
= m_lstMem
.begin() ; ii
!= m_lstMem
.end() ; ++ii
)
591 rtl_freeMemory( *ii
);
594 m_pEnvRemote
->release( m_pEnvRemote
);
597 //-------------------------------------------------------------------------------------
598 void ServerMultiJob::execute()
600 Reference
< XCurrentContext
> xOldCc
;
601 bool bHasOldCc
= false;
602 for( sal_Int32 i
= 0; i
< m_nCalls
; i
++ )
604 struct MemberTypeInfo
* const pMTI
= &( m_aTypeInfo
[i
] );
605 struct ServerJobEntry
* const pSJE
= &( m_aEntries
[i
] );
607 if ( pSJE
->m_bHasCurrentContext
)
611 xOldCc
= com::sun::star::uno::getCurrentContext();
614 rtl::OUString
aEnvName( RTL_CONSTASCII_USTRINGPARAM( "urp" ) );
615 if ( !uno_setCurrentContext(
616 pSJE
->m_pCurrentContext
, aEnvName
.pData
, m_pContext
) )
618 throw RuntimeException(
620 RTL_CONSTASCII_USTRINGPARAM(
621 "fatal: uno_setCurrentContext failed" ) ),
622 Reference
< XInterface
>() );
624 if ( pSJE
->m_pCurrentContext
)
626 pSJE
->m_pCurrentContext
->release( pSJE
->m_pCurrentContext
);
630 if( ! pSJE
->m_pRemoteI
)
632 // -------------------
634 // ------------------
635 // be robust : Sending a release on a not constructed object
636 // provokes an segfault. Make sure, the call
637 // is not a release call.
638 remote_Context
*pRemoteC
= ((remote_Context
*)m_pEnvRemote
->pContext
);
640 if( ! pMTI
->m_bIsReleaseCall
&& pRemoteC
->m_pInstanceProvider
)
642 pSJE
->m_pException
= &(pSJE
->m_exception
);
644 pRemoteC
->m_pInstanceProvider
->getInstance(
645 pRemoteC
->m_pInstanceProvider
,
649 pMTI
->m_pInterfaceType
,
650 &(pSJE
->m_pException
));
654 prepareRuntimeException(
655 OUString( RTL_CONSTASCII_USTRINGPARAM( "urp: No instance provider set")),i
);
659 if( pSJE
->m_pException
)
661 // errors during extracting, do nothing
663 else if( ! pSJE
->m_pRemoteI
)
665 // May only occur during the queryInterface call on the initial object !!!
666 // construct the return value
667 uno_type_any_construct( (uno_Any
*) pSJE
->m_pReturn
, 0 , 0 , 0 );
671 pSJE
->m_pException
= &(pSJE
->m_exception
);
673 if( pMTI
->m_bIsReleaseCall
)
675 pSJE
->m_pRemoteI
->release( pSJE
->m_pRemoteI
);
676 pSJE
->m_pException
= 0;
680 pSJE
->m_pRemoteI
->pDispatcher(
682 pMTI
->m_pMethodType
? (typelib_TypeDescription
*) pMTI
->m_pMethodType
:
683 (typelib_TypeDescription
*) pMTI
->m_pAttributeType
,
686 &(pSJE
->m_pException
) );
689 if( pSJE
->m_pRemoteI
)
692 Do the release here, in case of ForceSynchronous=1, calls
693 originated by the destructor of an UNO object must be sent BEFORE the
694 release returns ( otherwise we don't own the thread anymore ! )
696 pSJE
->m_pRemoteI
->release( pSJE
->m_pRemoteI
);
697 pSJE
->m_pRemoteI
= 0;
700 // now destruct parameters and marshal replies
701 // Note : when call is synchron => m_nCalls == 1
702 if( pMTI
->m_bIsOneway
)
704 // Oneway call, destruct in parameters
705 for( sal_Int32 j
= 0 ; j
< pMTI
->m_pMethodType
->nParams
; j
++ )
707 // usually all parameters must be in parameters, but to be robust ...
708 if( pMTI
->m_pbIsIn
[j
] && !cppu_isSimpleType( pMTI
->m_ppArgType
[j
] ) )
710 uno_destructData( pSJE
->m_ppArgs
[j
] , pMTI
->m_ppArgType
[j
] , 0 );
714 if( pSJE
->m_pException
)
716 uno_any_destruct( pSJE
->m_pException
, ::bridges_remote::remote_release
);
722 // synchron, get the mutex to marshal reply and send immeadiatly
723 MutexGuard
guard( m_pBridgeImpl
->m_marshalingMutex
);
725 sal_Bool bTid
= sal_False
;
726 sal_uInt8 nFlags
= HDRFLAG_LONGHEADER
;
727 ByteSequence tid
= m_pTid
;
728 if( !( tid
== m_pBridgeImpl
->m_lastOutTid
) || pSJE
->m_bIgnoreCache
)
731 nFlags
= nFlags
| HDRFLAG_NEWTID
;
735 if( pSJE
->m_pException
)
737 nFlags
= nFlags
| HDRFLAG_EXCEPTION
;
739 #ifdef BRIDGES_URP_PROT
740 sal_Int32 nLogStart
= m_pBridgeImpl
->m_blockMarshaler
.getPos();
742 m_pBridgeImpl
->m_blockMarshaler
.packInt8( &nFlags
);
746 if( ! pSJE
->m_bIgnoreCache
)
748 m_pBridgeImpl
->m_lastOutTid
= tid
;
750 m_pBridgeImpl
->m_blockMarshaler
.packTid( tid
, pSJE
->m_bIgnoreCache
);
753 #ifdef BRIDGES_URP_PROT
754 sal_Int32 nLogHeader
= m_pBridgeImpl
->m_blockMarshaler
.getPos();
757 if( pSJE
->m_pException
)
759 //--------------------
760 // an exception was thrown
761 //--------------------
762 m_pBridgeImpl
->m_blockMarshaler
.packAny( &(pSJE
->m_exception
) );
763 uno_any_destruct( &(pSJE
->m_exception
) , ::bridges_remote::remote_release
);
765 // destroy in parameters
766 for( sal_Int32 j
= 0 ; j
< pMTI
->m_nArgCount
; j
++ )
768 if( pMTI
->m_pbIsIn
[j
] && ! cppu_isSimpleType( pMTI
->m_ppArgType
[j
] ))
770 uno_destructData( pSJE
->m_ppArgs
[j
] , pMTI
->m_ppArgType
[j
] ,
771 ::bridges_remote::remote_release
);
777 //---------------------------
779 //--------------------------
780 if( pMTI
->m_pReturnType
)
782 m_pBridgeImpl
->m_blockMarshaler
.pack(
783 pSJE
->m_pReturn
, pMTI
->m_pReturnType
);
784 if( ! cppu_isSimpleType( pMTI
->m_pReturnType
) )
786 uno_destructData( pSJE
->m_pReturn
, pMTI
->m_pReturnType
,
787 ::bridges_remote::remote_release
);
790 for( sal_Int32 j
= 0 ; j
< pMTI
->m_nArgCount
; j
++ )
792 if( pMTI
->m_pbIsOut
[j
] )
794 m_pBridgeImpl
->m_blockMarshaler
.pack(
795 pSJE
->m_ppArgs
[j
] , pMTI
->m_ppArgType
[j
] );
797 if( ! cppu_isSimpleType( pMTI
->m_ppArgType
[j
] ) )
799 uno_destructData( pSJE
->m_ppArgs
[j
], pMTI
->m_ppArgType
[j
] ,
800 ::bridges_remote::remote_release
);
805 #ifdef BRIDGES_URP_PROT
807 typelib_InterfaceMemberTypeDescription
*pMemberType
=
808 pMTI
->m_pMethodType
?
809 (typelib_InterfaceMemberTypeDescription
*)pMTI
->m_pMethodType
:
810 (typelib_InterfaceMemberTypeDescription
*)pMTI
->m_pAttributeType
;
812 urp_logReplying( m_pBridgeImpl
,
813 m_pBridgeImpl
->m_blockMarshaler
.getPos() - nLogStart
,
814 m_pBridgeImpl
->m_blockMarshaler
.getPos() - nLogHeader
,
815 pMemberType
->pMemberName
);
819 m_pBridgeImpl
->m_nMarshaledMessages
++;
820 // put it on the wire
821 m_pBridgeImpl
->m_pWriter
->touch( sal_True
);
822 } // MutexGuard marshalingMutex
826 if ( !com::sun::star::uno::setCurrentContext( xOldCc
) )
828 throw RuntimeException(
830 RTL_CONSTASCII_USTRINGPARAM(
831 "fatal: com::sun::star::uno::setCurrentContext"
833 Reference
< XInterface
>() );
838 //-------------------------------------------------------------------------------------
839 void ServerMultiJob::prepareRuntimeException( const OUString
& sMessage
, sal_Int32 nCall
)
841 // -------------------------------
842 // Construct the DisposedException
843 // -------------------------------
844 com::sun::star::lang::DisposedException
exception( sMessage
, Reference
< XInterface
> () );
845 Type type
= getCppuType( &exception
);
846 if( !isDisposedExceptionDescriptionAvail( type
) )
848 // if it is not available (probably missing type library),
849 // then we are satisfied with throwing a normal runtime exception,
850 // for which cppu provides a static description
851 type
= getCppuType( ( RuntimeException
* ) 0 );
854 m_aEntries
[nCall
].m_pException
= &(m_aEntries
[nCall
].m_exception
);
855 uno_type_any_construct( m_aEntries
[nCall
].m_pException
, &exception
, type
.getTypeLibType() , 0 );
858 //-------------------------------------------------------------------------------------
859 void ServerMultiJob::initiate()
861 uno_threadpool_putJob(
862 m_pBridgeImpl
->m_hThreadPool
,
866 m_aTypeInfo
[0].m_bIsOneway
);
870 //-------------------------------------------------------------------------------------
871 sal_Bool
ServerMultiJob::extract()
873 sal_Bool bContinue
= sal_True
;
874 struct MemberTypeInfo
* const pMTI
= &(m_aTypeInfo
[m_nCalls
]);
875 struct ServerJobEntry
* const pSJE
= &(m_aEntries
[m_nCalls
]);
877 pSJE
->m_pException
= 0;
880 pMTI
->m_pReturnType
= 0;
882 if( pMTI
->m_nArgCount
)
885 ( typelib_TypeDescription
** ) getHeap( sizeof(void*) * pMTI
->m_nArgCount
);
886 pSJE
->m_ppArgs
= (void**) getHeap( sizeof( void * ) * pMTI
->m_nArgCount
);
887 pMTI
->m_pbIsIn
= (sal_Bool
*) getHeap( sizeof( sal_Bool
) * pMTI
->m_nArgCount
);
888 pMTI
->m_pbIsOut
= (sal_Bool
*) getHeap( sizeof( sal_Bool
) * pMTI
->m_nArgCount
);
890 if( pMTI
->m_pMethodType
&&
891 pMTI
->m_pMethodType
->pReturnTypeRef
->eTypeClass
!= typelib_TypeClass_VOID
)
893 TYPELIB_DANGER_GET( &(pMTI
->m_pReturnType
), pMTI
->m_pMethodType
->pReturnTypeRef
);
895 else if( pMTI
->m_pAttributeType
&& ! pMTI
->m_nArgCount
)
897 TYPELIB_DANGER_GET( &(pMTI
->m_pReturnType
) , pMTI
->m_pAttributeType
->pAttributeTypeRef
);
901 if( pMTI
->m_pMethodType
)
903 for( sal_Int32 i
= 0 ; i
< pMTI
->m_nArgCount
; i
++ )
905 pMTI
->m_ppArgType
[i
] = 0;
906 TYPELIB_DANGER_GET( & ( pMTI
->m_ppArgType
[i
] ) , pMTI
->m_pMethodType
->pParams
[i
].pTypeRef
);
907 pMTI
->m_pbIsIn
[i
] = pMTI
->m_pMethodType
->pParams
[i
].bIn
;
908 pMTI
->m_pbIsOut
[i
] = pMTI
->m_pMethodType
->pParams
[i
].bOut
;
910 pSJE
->m_ppArgs
[i
] = getHeap( pMTI
->m_ppArgType
[i
]->nSize
);
911 if( pMTI
->m_pbIsIn
[i
] )
913 // everything needs to be constructed
914 bContinue
= m_pUnmarshal
->unpack(
915 pSJE
->m_ppArgs
[i
], pMTI
->m_ppArgType
[i
] ) && bContinue
;
919 else if( pMTI
->m_nArgCount
)
922 pMTI
->m_ppArgType
[0] = 0;
923 pMTI
->m_pbIsIn
[0] = sal_True
;
924 pMTI
->m_pbIsOut
[0] = sal_False
;
926 & ( pMTI
->m_ppArgType
[0] ) , pMTI
->m_pAttributeType
->pAttributeTypeRef
);
927 pSJE
->m_ppArgs
[0] = getHeap( pMTI
->m_ppArgType
[0]->nSize
);
928 bContinue
= m_pUnmarshal
->unpack(
929 pSJE
->m_ppArgs
[0], pMTI
->m_ppArgType
[0] ) && bContinue
;
932 if( pMTI
->m_pReturnType
)
934 pSJE
->m_pReturn
= getHeap( pMTI
->m_pReturnType
->nSize
);