update dev300-m58
[ooovba.git] / bridges / source / remote / urp / urp_job.hxx
blob64f64f28f6af1f3f00deff66038b72797b8bbf54
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_job.hxx,v $
10 * $Revision: 1.11 $
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 ************************************************************************/
30 #ifndef _URP_JOB_HXX_
31 #define _URP_JOB_HXX_
32 #include <list>
33 #include <typelib/typedescription.hxx>
34 #include <uno/any2.h>
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"
42 namespace bridges_urp
44 const sal_Int32 MULTIJOB_STANDARD_MEMORY_SIZE = 1024;
45 const sal_Int32 MULTIJOB_PER_CALL_MEMORY_SIZE = 96;
47 class Unmarshal;
48 struct urp_BridgeImpl;
50 template < class t >
51 inline t mymax( const t &t1 , const t &t2 )
53 return t1 > t2 ? t1 : t2;
56 class Job
58 public:
59 Job( uno_Environment *pEnvRemote,
60 remote_Context *pContext,
61 sal_Sequence *pTid,
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 )
71 , m_pTid( 0 )
72 , m_counter( pEnvRemote , value )
74 if ( m_pContext )
76 m_pContext->aBase.acquire( &m_pContext->aBase );
80 ~Job();
82 inline void setUnmarshal( Unmarshal *p )
83 { m_pUnmarshal = p; }
85 public:
86 remote_Context *m_pContext;
87 Unmarshal *m_pUnmarshal;
88 struct urp_BridgeImpl *m_pBridgeImpl;
89 sal_Sequence *m_pTid;
90 ::bridges_remote::RemoteThreadCounter m_counter;
93 class ClientJob : public Job
95 public:
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
103 void *pReturn,
104 void *ppArgs[],
105 uno_Any **ppException );
107 // ~ClientJob
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.
111 inline ~ClientJob()
113 if( m_bReleaseForTypeDescriptionNecessary )
114 typelib_typedescription_release( (typelib_TypeDescription*) m_pInterfaceType );
115 uno_releaseIdFromCurrentThread();
118 sal_Bool pack();
119 void wait();
120 sal_Bool extract( );
121 void initiate();
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; }
129 public:
130 typelib_InterfaceMethodTypeDescription *m_pMethodType;
131 typelib_InterfaceAttributeTypeDescription *m_pAttributeType;
132 sal_Bool m_bExceptionOccured;
134 private:
135 void **m_ppArgs;
136 void *m_pReturn;
137 typelib_InterfaceTypeDescription *m_pInterfaceType;
138 sal_Bool m_bReleaseForTypeDescriptionNecessary;
140 uno_Any **m_ppException;
141 sal_Bool m_bOneway;
142 sal_Bool m_bBridgePropertyCall;
143 sal_uInt16 m_nMethodIndex;
144 uno_Environment *m_pEnvRemote;
145 rtl_uString *m_pOid;
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;
156 sal_Bool *m_pbIsIn;
157 sal_Bool *m_pbIsOut;
158 sal_Bool m_bIsOneway;
159 typelib_TypeDescription *m_pReturnType;
160 typelib_TypeDescription **m_ppArgType;
164 struct ServerJobEntry
166 rtl_uString *m_pOid;
167 remote_Interface *m_pRemoteI;
168 typelib_TypeDescriptionReference *m_pInterfaceTypeRef;
169 void **m_ppArgs;
170 void *m_pReturn;
171 uno_Any m_exception;
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
180 public:
181 ServerMultiJob( uno_Environment *pEnvRemote,
182 remote_Context *pContext,
183 sal_Sequence *pTid,
184 struct urp_BridgeImpl *pBridgeImpl,
185 Unmarshal *pUnmarshal,
186 sal_Int32 nMaxMessages );
187 ~ServerMultiJob();
188 public:
189 sal_Bool extract( );
190 void initiate();
191 void execute();
193 public:
194 // setMethodType or setAttributeType MUST be called before extract
195 inline void setMethodType(
196 typelib_InterfaceMethodTypeDescription *pMethodType,
197 sal_Bool bIsReleaseCall,
198 sal_Bool bIsOneway )
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 );
221 TYPELIB_DANGER_GET(
222 (typelib_TypeDescription ** )&(m_aTypeInfo[m_nCalls].m_pInterfaceType) ,
223 pTypeRef );
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;
274 return pHeap;
276 void prepareRuntimeException( const ::rtl::OUString &sMessage, sal_Int32 nCall );
278 private:
279 uno_Environment *m_pEnvRemote;
280 sal_Int32 m_nCalls;
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,
301 rtl_uString *pOid,
302 typelib_TypeDescription const * pMemberType,
303 typelib_InterfaceTypeDescription *pInterfaceType,
304 void *pReturn,
305 void *ppArgs[],
306 uno_Any **ppException )
307 : Job(
308 pEnvRemote, pContext, pBridgeImpl, ::bridges_remote::RTC_HOLDENVWEAK )
309 , m_ppArgs( ppArgs )
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;
329 m_pMethodType = 0;
331 else
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 )
349 // setter
350 m_nMethodIndex ++;
353 if( typelib_TypeClass_INTERFACE_METHOD == pMemberType->eTypeClass )
355 // if( (( typelib_InterfaceMemberTypeDescription * ) pMemberType)->nPosition
356 // == REMOTE_RELEASE_METHOD_INDEX )
357 // {
358 // m_bOneway = sal_True;
359 // }
360 // else
361 if( pBridgeImpl->m_properties.bForceSynchronous )
363 m_bOneway = sal_False;
364 if( (( typelib_InterfaceMethodTypeDescription * ) pMemberType)->bOneWay )
366 m_bCallingConventionForced = sal_True;
369 else
371 m_bOneway = (( typelib_InterfaceMethodTypeDescription * ) pMemberType)->bOneWay;
374 else
376 m_bOneway = sal_False;
381 #endif