update dev300-m58
[ooovba.git] / bridges / source / remote / urp / urp_writer.cxx
bloba0e4a2088a6cc102d7ca83ecebd9b3cf80e06009
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_writer.cxx,v $
10 * $Revision: 1.17.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 <stdio.h>
34 #include <osl/time.h>
36 #include <osl/mutex.hxx>
37 #include <osl/conditn.h>
39 #include <typelib/typedescription.h>
41 #include <bridges/remote/connection.h>
42 #include <bridges/remote/remote.hxx>
44 #include <com/sun/star/uno/Sequence.hxx>
46 #include <bridges/remote/counter.hxx>
48 #include "urp_writer.hxx"
49 #include "urp_bridgeimpl.hxx"
50 #include "urp_marshal.hxx"
51 #include "urp_dispatch.hxx"
53 #if OSL_DEBUG_LEVEL > 1
54 static MyCounter thisCounter( "DEBUG : WriterThread" );
55 #endif
57 using namespace ::osl;
59 namespace bridges_urp {
61 OWriterThread::OWriterThread( remote_Connection *pConnection, urp_BridgeImpl *pBridgeImpl,
62 uno_Environment *pEnvRemote) :
63 m_bAbort( sal_False ),
64 m_bInBlockingWait( sal_False ),
65 m_bEnterBlockingWait( sal_False ),
66 m_pConnection( pConnection ),
67 m_pBridgeImpl( pBridgeImpl ),
68 m_pEnvRemote( pEnvRemote )
71 m_oslCondition = osl_createCondition();
72 osl_resetCondition( m_oslCondition );
73 m_pConnection->acquire( m_pConnection );
75 #if OSL_DEBUG_LEVEL > 1
76 thisCounter.acquire();
77 #endif
80 OWriterThread::~OWriterThread()
82 osl_destroyCondition( m_oslCondition );
83 m_pConnection->release( m_pConnection );
84 #if OSL_DEBUG_LEVEL > 1
85 thisCounter.release();
86 #endif
90 // touch is called with locked m_marshalingMutex
91 void OWriterThread::touch( sal_Bool bImmediately )
93 if( bImmediately || m_pBridgeImpl->m_blockMarshaler.getPos() > m_pBridgeImpl->m_properties.nFlushBlockSize )
95 write();
97 else
99 // wake the writer thread up
100 if( m_bInBlockingWait )
102 m_bInBlockingWait = sal_False;
103 osl_setCondition( m_oslCondition );
105 else
107 // ensure, that the writing thread does not enter blocking mode
108 m_bEnterBlockingWait = sal_False;
114 void OWriterThread::abortThread()
116 MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
118 m_bAbort = sal_True;
119 m_bEnterBlockingWait = sal_False;
120 if( m_bInBlockingWait )
122 m_bInBlockingWait = sal_False;
123 osl_setCondition( m_oslCondition );
128 // must be called with locked marshaling mutex
129 void OWriterThread::write()
131 if( ! m_pBridgeImpl->m_blockMarshaler.empty() && ! m_bAbort )
133 m_pBridgeImpl->m_blockMarshaler.finish( m_pBridgeImpl->m_nMarshaledMessages);
134 m_pBridgeImpl->m_nMarshaledMessages = 0;
136 sal_Int32 nLength = m_pBridgeImpl->m_blockMarshaler.getSize();
137 sal_Int8 *pBuf = m_pBridgeImpl->m_blockMarshaler.getBuffer();
139 if( nLength != m_pConnection->write( m_pConnection, pBuf, nLength ))
141 m_pBridgeImpl->m_blockMarshaler.restart();
142 return;
144 m_pConnection->flush( m_pConnection );
145 m_pBridgeImpl->m_blockMarshaler.restart();
149 void OWriterThread::sendEmptyMessage()
151 // must be called with locked marshaling mutex
152 sal_Int32 a[2] = {0,0};
153 m_pConnection->write( m_pConnection , (sal_Int8*) a , sizeof( sal_Int32) *2 );
156 void OWriterThread::insertReleaseRemoteCall(
157 rtl_uString *pOid,typelib_TypeDescriptionReference *pTypeRef)
160 ::osl::MutexGuard guard( m_releaseCallMutex );
162 struct RemoteReleaseCall call;
163 call.sOid = pOid;
164 call.typeInterface = pTypeRef;
165 m_lstReleaseCalls.push_back( call );
168 MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
169 if( m_bInBlockingWait )
171 m_bInBlockingWait = sal_False;
172 osl_setCondition( m_oslCondition );
174 else
176 // ensure, that the writing thread does not enter blocking mode
177 m_bEnterBlockingWait = sal_False;
182 /* The release calls for doubled interfaces
185 ***/
186 void OWriterThread::executeReleaseRemoteCalls()
188 ::std::list< struct RemoteReleaseCall > lstReleaseCalls;
190 ::osl::MutexGuard guard( m_releaseCallMutex );
191 lstReleaseCalls.swap( m_lstReleaseCalls );
194 for( ::std::list< struct RemoteReleaseCall >::iterator ii = lstReleaseCalls.begin();
195 ii != lstReleaseCalls.end();
196 ++ ii )
198 struct RemoteReleaseCall &call = (*ii) ;
200 typelib_TypeDescription *pInterfaceTypeDesc = 0;
201 typelib_TypeDescription *pReleaseMethod = 0;
203 call.typeInterface.getDescription( &pInterfaceTypeDesc );
204 if( ! pInterfaceTypeDesc->bComplete )
206 typelib_typedescription_complete( &pInterfaceTypeDesc );
209 uno_Any any;
210 uno_Any *pAny = &any;
212 typelib_typedescriptionreference_getDescription(
213 &pReleaseMethod ,
214 ((typelib_InterfaceTypeDescription*)pInterfaceTypeDesc)->ppAllMembers[REMOTE_RELEASE_METHOD_INDEX] );
216 urp_sendRequest_internal(
217 m_pEnvRemote , pReleaseMethod, call.sOid.pData,
218 (typelib_InterfaceTypeDescription*) pInterfaceTypeDesc, 0, 0,
219 &pAny );
221 typelib_typedescription_release( pReleaseMethod );
222 typelib_typedescription_release( pInterfaceTypeDesc );
227 void OWriterThread::run()
229 while( ! m_bAbort )
231 sal_Bool bWait;
233 MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
234 bWait = m_bEnterBlockingWait;
235 if( bWait )
237 osl_resetCondition( m_oslCondition );
238 m_bInBlockingWait = sal_True;
240 m_bEnterBlockingWait = sal_True;
243 // wait for some notification
244 if( bWait )
245 osl_waitCondition( m_oslCondition , 0 );
246 // (m_bInBlockingWait = sal_False was set by the activating thread)
248 if( m_bAbort )
249 break;
251 // Wait for the timeout
252 TimeValue value = { 0 , 1000 * m_pBridgeImpl->m_properties.nOnewayTimeoutMUSEC };
253 osl_resetCondition( m_oslCondition );
254 osl_waitCondition( m_oslCondition , &value );
256 // check if there are some release calls to be sent ....
257 executeReleaseRemoteCalls();
260 // write to the socket
261 MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
262 if( ! m_pBridgeImpl->m_blockMarshaler.empty() )
264 write();