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_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"
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" );
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();
80 OWriterThread::~OWriterThread()
82 osl_destroyCondition( m_oslCondition
);
83 m_pConnection
->release( m_pConnection
);
84 #if OSL_DEBUG_LEVEL > 1
85 thisCounter
.release();
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
)
99 // wake the writer thread up
100 if( m_bInBlockingWait
)
102 m_bInBlockingWait
= sal_False
;
103 osl_setCondition( m_oslCondition
);
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
);
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();
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
;
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
);
176 // ensure, that the writing thread does not enter blocking mode
177 m_bEnterBlockingWait
= sal_False
;
182 /* The release calls for doubled interfaces
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();
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
);
210 uno_Any
*pAny
= &any
;
212 typelib_typedescriptionreference_getDescription(
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,
221 typelib_typedescription_release( pReleaseMethod
);
222 typelib_typedescription_release( pInterfaceTypeDesc
);
227 void OWriterThread::run()
233 MutexGuard
guard( m_pBridgeImpl
->m_marshalingMutex
);
234 bWait
= m_bEnterBlockingWait
;
237 osl_resetCondition( m_oslCondition
);
238 m_bInBlockingWait
= sal_True
;
240 m_bEnterBlockingWait
= sal_True
;
243 // wait for some notification
245 osl_waitCondition( m_oslCondition
, 0 );
246 // (m_bInBlockingWait = sal_False was set by the activating thread)
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() )