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.hxx,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 ************************************************************************/
33 #include <typelib/typedescription.hxx>
35 #include <uno/environment.h>
36 #include <uno/threadpool.h>
37 #include "urp_threadid.hxx"
38 #include "urp_unmarshal.hxx"
39 #include "urp_bridgeimpl.hxx"
44 const sal_Int32 MULTIJOB_STANDARD_MEMORY_SIZE
= 1024;
45 const sal_Int32 MULTIJOB_PER_CALL_MEMORY_SIZE
= 96;
48 struct urp_BridgeImpl
;
51 inline t
mymax( const t
&t1
, const t
&t2
)
53 return t1
> t2
? t1
: t2
;
59 Job( uno_Environment
*pEnvRemote
,
60 remote_Context
*pContext
,
62 struct urp_BridgeImpl
*pBridgeImpl
,
63 Unmarshal
*pUnmarshal
);
65 Job( uno_Environment
*pEnvRemote
,
66 remote_Context
*pContext
,
67 struct urp_BridgeImpl
*pBridgeImpl
,
68 ::bridges_remote::RemoteThreadCounter_HoldEnvWeak value
)
69 : m_pContext( pContext
)
70 , m_pBridgeImpl( pBridgeImpl
)
72 , m_counter( pEnvRemote
, value
)
76 m_pContext
->aBase
.acquire( &m_pContext
->aBase
);
82 inline void setUnmarshal( Unmarshal
*p
)
86 remote_Context
*m_pContext
;
87 Unmarshal
*m_pUnmarshal
;
88 struct urp_BridgeImpl
*m_pBridgeImpl
;
90 ::bridges_remote::RemoteThreadCounter m_counter
;
93 class ClientJob
: public Job
96 // pContext is null for bridge-internal UrpProtocolProperties requests
97 inline ClientJob( uno_Environment
*pEnvRemote
, // weak !
98 remote_Context
*pContext
,
99 struct urp_BridgeImpl
*pBridgeImpl
,
100 rtl_uString
*pOid
, // weak
101 typelib_TypeDescription
const * pMemberType
, // weak
102 typelib_InterfaceTypeDescription
*pInterfaceType
, // weak
105 uno_Any
**ppException
);
108 // no release for method type and attribute type necessary, because
109 // it was acquired by the caller of urp_sendRequest. The lifetime
110 // of the ClientJob object is always shorter than the urp_sendRequest call.
113 if( m_bReleaseForTypeDescriptionNecessary
)
114 typelib_typedescription_release( (typelib_TypeDescription
*) m_pInterfaceType
);
115 uno_releaseIdFromCurrentThread();
123 inline void setBridgePropertyCall()
124 { m_bBridgePropertyCall
= sal_True
; }
125 inline sal_Bool
isBridgePropertyCall()
126 { return m_bBridgePropertyCall
; }
127 inline sal_Bool
isOneway()
128 { return m_bOneway
; }
130 typelib_InterfaceMethodTypeDescription
*m_pMethodType
;
131 typelib_InterfaceAttributeTypeDescription
*m_pAttributeType
;
132 sal_Bool m_bExceptionOccured
;
137 typelib_InterfaceTypeDescription
*m_pInterfaceType
;
138 sal_Bool m_bReleaseForTypeDescriptionNecessary
;
140 uno_Any
**m_ppException
;
142 sal_Bool m_bBridgePropertyCall
;
143 sal_uInt16 m_nMethodIndex
;
144 uno_Environment
*m_pEnvRemote
;
146 sal_Bool m_bCallingConventionForced
;
149 struct MemberTypeInfo
151 typelib_InterfaceTypeDescription
*m_pInterfaceType
;
152 typelib_InterfaceMethodTypeDescription
*m_pMethodType
;
153 typelib_InterfaceAttributeTypeDescription
*m_pAttributeType
;
154 sal_Int32 m_nArgCount
;
155 sal_Bool m_bIsReleaseCall
;
158 sal_Bool m_bIsOneway
;
159 typelib_TypeDescription
*m_pReturnType
;
160 typelib_TypeDescription
**m_ppArgType
;
164 struct ServerJobEntry
167 remote_Interface
*m_pRemoteI
;
168 typelib_TypeDescriptionReference
*m_pInterfaceTypeRef
;
172 uno_Any
*m_pException
;
173 remote_Interface
*m_pCurrentContext
;
174 sal_Bool m_bHasCurrentContext
;
175 sal_Bool m_bIgnoreCache
;
178 class ServerMultiJob
: public Job
181 ServerMultiJob( uno_Environment
*pEnvRemote
,
182 remote_Context
*pContext
,
184 struct urp_BridgeImpl
*pBridgeImpl
,
185 Unmarshal
*pUnmarshal
,
186 sal_Int32 nMaxMessages
);
194 // setMethodType or setAttributeType MUST be called before extract
195 inline void setMethodType(
196 typelib_InterfaceMethodTypeDescription
*pMethodType
,
197 sal_Bool bIsReleaseCall
,
200 m_aTypeInfo
[m_nCalls
].m_pMethodType
= pMethodType
;
201 m_aTypeInfo
[m_nCalls
].m_pAttributeType
= 0;
202 m_aTypeInfo
[m_nCalls
].m_nArgCount
= pMethodType
->nParams
;
203 m_aTypeInfo
[m_nCalls
].m_bIsReleaseCall
= bIsReleaseCall
;
204 m_aTypeInfo
[m_nCalls
].m_bIsOneway
= bIsOneway
;
207 inline void setAttributeType(
208 typelib_InterfaceAttributeTypeDescription
*pAttributeType
, sal_Bool bIsSetter
, sal_Bool bIsOneway
)
210 m_aTypeInfo
[m_nCalls
].m_pAttributeType
= pAttributeType
;
211 m_aTypeInfo
[m_nCalls
].m_pMethodType
= 0;
212 m_aTypeInfo
[m_nCalls
].m_nArgCount
= bIsSetter
? 1 : 0;
213 m_aTypeInfo
[m_nCalls
].m_bIsReleaseCall
= sal_False
;
214 m_aTypeInfo
[m_nCalls
].m_bIsOneway
= bIsOneway
;
217 inline void setType( typelib_TypeDescriptionReference
*pTypeRef
)
219 m_aEntries
[m_nCalls
].m_pInterfaceTypeRef
= pTypeRef
;
220 typelib_typedescriptionreference_acquire( m_aEntries
[m_nCalls
].m_pInterfaceTypeRef
);
222 (typelib_TypeDescription
** )&(m_aTypeInfo
[m_nCalls
].m_pInterfaceType
) ,
225 // setOid or setInterface MUST be called before extract
226 inline void setOid( rtl_uString
*pOid
)
228 m_aEntries
[m_nCalls
].m_pOid
= pOid
;
229 rtl_uString_acquire( m_aEntries
[m_nCalls
].m_pOid
);
230 m_aEntries
[m_nCalls
].m_pRemoteI
= 0;
233 // setOid or setInterface MUST be called
234 inline void setInterface( remote_Interface
*pRemoteI
)
236 m_aEntries
[m_nCalls
].m_pRemoteI
= pRemoteI
;
237 pRemoteI
->acquire( pRemoteI
);
238 m_aEntries
[m_nCalls
].m_pOid
= 0;
241 inline void setCurrentContext(
242 bool bHasCurrentContext
, remote_Interface
*pCurrentContext
)
244 m_aEntries
[m_nCalls
].m_pCurrentContext
= pCurrentContext
;
245 m_aEntries
[m_nCalls
].m_bHasCurrentContext
= bHasCurrentContext
;
248 inline void setIgnoreCache( sal_Bool bIgnoreCache
)
250 m_aEntries
[m_nCalls
].m_bIgnoreCache
= bIgnoreCache
;
253 inline sal_Bool
isFull()
254 { return m_nCalls
>= m_nMaxMessages
; }
256 inline sal_Int8
*getHeap( sal_Int32 nSizeToAlloc
)
258 if( nSizeToAlloc
+ m_nCurrentMemPosition
> m_nCurrentMemSize
)
260 m_lstMem
.push_back( m_pCurrentMem
);
261 m_nCurrentMemSize
= mymax( nSizeToAlloc
, MULTIJOB_STANDARD_MEMORY_SIZE
) +
262 (m_nMaxMessages
-m_nCalls
)*MULTIJOB_PER_CALL_MEMORY_SIZE
;
263 m_pCurrentMem
= (sal_Int8
*) rtl_allocateMemory( m_nCurrentMemSize
);
264 m_nCurrentMemPosition
= 0;
266 sal_Int8
*pHeap
= m_pCurrentMem
+ m_nCurrentMemPosition
;
267 m_nCurrentMemPosition
+= nSizeToAlloc
;
269 // care for alignment
270 if( m_nCurrentMemPosition
& 0x7 )
272 m_nCurrentMemPosition
= ( ((sal_uInt32
)m_nCurrentMemPosition
) & ( 0xffffffff - 0x7 )) + 8;
276 void prepareRuntimeException( const ::rtl::OUString
&sMessage
, sal_Int32 nCall
);
279 uno_Environment
*m_pEnvRemote
;
281 sal_Int32 m_nMaxMessages
;
283 ServerJobEntry
*m_aEntries
;
284 MemberTypeInfo
*m_aTypeInfo
;
286 sal_Int8
*m_pCurrentMem
;
287 sal_Int32 m_nCurrentMemSize
;
288 sal_Int32 m_nCurrentMemPosition
;
290 // list of memory pointers, that must be freed
291 ::std::list
< sal_Int8
* > m_lstMem
;
296 //---------------------------------------------------------------------------------------------
297 inline ClientJob::ClientJob(
298 uno_Environment
*pEnvRemote
,
299 remote_Context
*pContext
,
300 struct urp_BridgeImpl
*pBridgeImpl
,
302 typelib_TypeDescription
const * pMemberType
,
303 typelib_InterfaceTypeDescription
*pInterfaceType
,
306 uno_Any
**ppException
)
308 pEnvRemote
, pContext
, pBridgeImpl
, ::bridges_remote::RTC_HOLDENVWEAK
)
310 , m_pReturn( pReturn
)
311 , m_pInterfaceType( pInterfaceType
) // weak
312 , m_bReleaseForTypeDescriptionNecessary( sal_False
)
313 , m_ppException( ppException
)
314 , m_bBridgePropertyCall( sal_False
)
315 , m_pEnvRemote( pEnvRemote
) // weak
316 , m_pOid( pOid
) // weak
317 , m_bCallingConventionForced( sal_False
)
319 uno_getIdOfCurrentThread( &m_pTid
);
321 if( typelib_TypeClass_INTERFACE_METHOD
== pMemberType
->eTypeClass
)
323 m_pMethodType
= ( typelib_InterfaceMethodTypeDescription
* ) pMemberType
;
324 m_pAttributeType
= 0;
326 else if( typelib_TypeClass_INTERFACE_ATTRIBUTE
== pMemberType
->eTypeClass
)
328 m_pAttributeType
= ( typelib_InterfaceAttributeTypeDescription
* ) pMemberType
;
333 OSL_ASSERT( ! "wrong member type" );
336 // calculate method index
337 if( ! m_pInterfaceType
->aBase
.bComplete
)
339 // must be acquired because typedescription may be exchanged
340 typelib_typedescription_acquire((typelib_TypeDescription
*) m_pInterfaceType
);
341 m_bReleaseForTypeDescriptionNecessary
= sal_True
;
342 typelib_typedescription_complete( (typelib_TypeDescription
** ) &m_pInterfaceType
);
344 m_nMethodIndex
= (sal_uInt16
) m_pInterfaceType
->pMapMemberIndexToFunctionIndex
[
345 ((typelib_InterfaceMemberTypeDescription
*)pMemberType
)->nPosition
];
347 if( m_pAttributeType
&& m_ppArgs
)
353 if( typelib_TypeClass_INTERFACE_METHOD
== pMemberType
->eTypeClass
)
355 // if( (( typelib_InterfaceMemberTypeDescription * ) pMemberType)->nPosition
356 // == REMOTE_RELEASE_METHOD_INDEX )
358 // m_bOneway = sal_True;
361 if( pBridgeImpl
->m_properties
.bForceSynchronous
)
363 m_bOneway
= sal_False
;
364 if( (( typelib_InterfaceMethodTypeDescription
* ) pMemberType
)->bOneWay
)
366 m_bCallingConventionForced
= sal_True
;
371 m_bOneway
= (( typelib_InterfaceMethodTypeDescription
* ) pMemberType
)->bOneWay
;
376 m_bOneway
= sal_False
;