19d1279ecSAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
39d1279ecSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
49d1279ecSAndrew Rist * or more contributor license agreements. See the NOTICE file
59d1279ecSAndrew Rist * distributed with this work for additional information
69d1279ecSAndrew Rist * regarding copyright ownership. The ASF licenses this file
79d1279ecSAndrew Rist * to you under the Apache License, Version 2.0 (the
89d1279ecSAndrew Rist * "License"); you may not use this file except in compliance
99d1279ecSAndrew Rist * with the License. You may obtain a copy of the License at
109d1279ecSAndrew Rist *
119d1279ecSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
129d1279ecSAndrew Rist *
139d1279ecSAndrew Rist * Unless required by applicable law or agreed to in writing,
149d1279ecSAndrew Rist * software distributed under the License is distributed on an
159d1279ecSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
169d1279ecSAndrew Rist * KIND, either express or implied. See the License for the
179d1279ecSAndrew Rist * specific language governing permissions and limitations
189d1279ecSAndrew Rist * under the License.
199d1279ecSAndrew Rist *
209d1279ecSAndrew Rist *************************************************************/
219d1279ecSAndrew Rist
229d1279ecSAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_automation.hxx"
26cdf0e10cSrcweir #include <stdio.h>
27cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
28cdf0e10cSrcweir #define DEBUGPRINTF(x) { printf(x); fflush( stdout ); }
29cdf0e10cSrcweir #else
30cdf0e10cSrcweir #define DEBUGPRINTF(x)
31cdf0e10cSrcweir #endif
32cdf0e10cSrcweir #include <tools/debug.hxx>
33cdf0e10cSrcweir #include <vcl/svapp.hxx>
34cdf0e10cSrcweir #include <vos/socket.hxx>
35cdf0e10cSrcweir #include <tools/stream.hxx>
36cdf0e10cSrcweir #include <vcl/timer.hxx>
37cdf0e10cSrcweir #include <tools/fsys.hxx>
38cdf0e10cSrcweir
39cdf0e10cSrcweir #include <automation/communi.hxx>
40cdf0e10cSrcweir
41cdf0e10cSrcweir
42cdf0e10cSrcweir /* Um den Destruktor protected zu machen wurde unten das delete entfernt.
43cdf0e10cSrcweir Die Methode wird ohnehin hucht benutzt.
44cdf0e10cSrcweir // delete *((AE*)pData+n);
45cdf0e10cSrcweir */
46cdf0e10cSrcweir
47cdf0e10cSrcweir #undef SV_IMPL_PTRARR_SORT
48cdf0e10cSrcweir #define SV_IMPL_PTRARR_SORT( nm,AE )\
49cdf0e10cSrcweir _SV_IMPL_SORTAR_ALG( nm,AE )\
50cdf0e10cSrcweir void nm::DeleteAndDestroy( sal_uInt16 nP, sal_uInt16 nL ) { \
51cdf0e10cSrcweir if( nL ) {\
52cdf0e10cSrcweir DBG_ASSERT( nP < nA && nP + nL <= nA, "ERR_VAR_DEL" );\
53cdf0e10cSrcweir for( sal_uInt16 n=nP; n < nP + nL; n++ ) \
54cdf0e10cSrcweir DBG_ERROR("Das Element der Liste wurde nicht gel�scht"); \
55cdf0e10cSrcweir SvPtrarr::Remove( nP, nL ); \
56cdf0e10cSrcweir } \
57cdf0e10cSrcweir } \
58cdf0e10cSrcweir _SV_SEEK_PTR( nm, AE )
59cdf0e10cSrcweir
60cdf0e10cSrcweir
61cdf0e10cSrcweir
62cdf0e10cSrcweir
63cdf0e10cSrcweir SV_IMPL_PTRARR_SORT( CommunicationLinkList, CommunicationLink* );
64cdf0e10cSrcweir
65cdf0e10cSrcweir vos::OMutex *pMPostUserEvent=NULL; // Notwendig, da nicht threadfest
66cdf0e10cSrcweir
CommunicationLinkViaSocket(CommunicationManager * pMan,vos::OStreamSocket * pSocket)67cdf0e10cSrcweir CommunicationLinkViaSocket::CommunicationLinkViaSocket( CommunicationManager *pMan, vos::OStreamSocket *pSocket )
68cdf0e10cSrcweir : SimpleCommunicationLinkViaSocket( pMan, pSocket )
69cdf0e10cSrcweir , nConnectionClosedEventId( 0 )
70cdf0e10cSrcweir , nDataReceivedEventId( 0 )
71cdf0e10cSrcweir , bShutdownStarted( sal_False )
72cdf0e10cSrcweir , bDestroying( sal_False )
73cdf0e10cSrcweir {
74cdf0e10cSrcweir SetPutDataReceivedHdl(LINK( this, CommunicationLinkViaSocket, PutDataReceivedHdl ));
75cdf0e10cSrcweir if ( !pMPostUserEvent )
76cdf0e10cSrcweir pMPostUserEvent = new vos::OMutex;
77cdf0e10cSrcweir // this is necassary to prevent the running thread from sending the close event
78cdf0e10cSrcweir // before the open event has been sent.
79cdf0e10cSrcweir StartCallback();
80cdf0e10cSrcweir
81cdf0e10cSrcweir create();
82cdf0e10cSrcweir }
83cdf0e10cSrcweir
~CommunicationLinkViaSocket()84cdf0e10cSrcweir CommunicationLinkViaSocket::~CommunicationLinkViaSocket()
85cdf0e10cSrcweir {
86cdf0e10cSrcweir bDestroying = sal_True;
87cdf0e10cSrcweir StopCommunication();
88cdf0e10cSrcweir while ( nConnectionClosedEventId || nDataReceivedEventId )
89cdf0e10cSrcweir GetpApp()->Yield();
90cdf0e10cSrcweir {
91cdf0e10cSrcweir vos::OGuard aGuard( aMConnectionClosed );
92cdf0e10cSrcweir if ( nConnectionClosedEventId )
93cdf0e10cSrcweir {
94cdf0e10cSrcweir GetpApp()->RemoveUserEvent( nConnectionClosedEventId );
95cdf0e10cSrcweir nConnectionClosedEventId = 0;
96cdf0e10cSrcweir INFO_MSG( CByteString("Event gel�scht"),
97cdf0e10cSrcweir CByteString( "ConnectionClosedEvent aus Queue gel�scht"),
98cdf0e10cSrcweir CM_MISC, NULL );
99cdf0e10cSrcweir }
100cdf0e10cSrcweir }
101cdf0e10cSrcweir {
102cdf0e10cSrcweir vos::OGuard aGuard( aMDataReceived );
103cdf0e10cSrcweir if ( nDataReceivedEventId )
104cdf0e10cSrcweir {
105cdf0e10cSrcweir GetpApp()->RemoveUserEvent( nDataReceivedEventId );
106cdf0e10cSrcweir nDataReceivedEventId = 0;
107cdf0e10cSrcweir delete GetServiceData();
108cdf0e10cSrcweir INFO_MSG( CByteString("Event gel�scht"),
109cdf0e10cSrcweir CByteString( "DataReceivedEvent aus Queue gel�scht"),
110cdf0e10cSrcweir CM_MISC, NULL );
111cdf0e10cSrcweir }
112cdf0e10cSrcweir }
113cdf0e10cSrcweir }
114cdf0e10cSrcweir
ShutdownCommunication()115cdf0e10cSrcweir sal_Bool CommunicationLinkViaSocket::ShutdownCommunication()
116cdf0e10cSrcweir {
117cdf0e10cSrcweir if ( isRunning() )
118cdf0e10cSrcweir {
119cdf0e10cSrcweir
120cdf0e10cSrcweir terminate();
121cdf0e10cSrcweir if ( GetStreamSocket() )
122cdf0e10cSrcweir GetStreamSocket()->shutdown();
123cdf0e10cSrcweir
124cdf0e10cSrcweir if ( GetStreamSocket() ) // Mal wieder nach oben verschoben, da sonst nicht vom Read runtergesprungen wird.
125cdf0e10cSrcweir GetStreamSocket()->close();
126cdf0e10cSrcweir
127cdf0e10cSrcweir resume(); // So da� das run auch die Schleife verlassen kann
128cdf0e10cSrcweir
129cdf0e10cSrcweir join();
130cdf0e10cSrcweir
131cdf0e10cSrcweir vos::OStreamSocket *pTempSocket = GetStreamSocket();
132cdf0e10cSrcweir SetStreamSocket( NULL );
133cdf0e10cSrcweir delete pTempSocket;
134cdf0e10cSrcweir
135cdf0e10cSrcweir // ConnectionClosed(); Wird am Ende des Thread gerufen
136cdf0e10cSrcweir
137cdf0e10cSrcweir }
138cdf0e10cSrcweir else
139cdf0e10cSrcweir {
140cdf0e10cSrcweir join();
141cdf0e10cSrcweir }
142cdf0e10cSrcweir
143cdf0e10cSrcweir return sal_True;
144cdf0e10cSrcweir }
145cdf0e10cSrcweir
StopCommunication()146cdf0e10cSrcweir sal_Bool CommunicationLinkViaSocket::StopCommunication()
147cdf0e10cSrcweir {
148cdf0e10cSrcweir if ( !bShutdownStarted )
149cdf0e10cSrcweir {
150cdf0e10cSrcweir return SimpleCommunicationLinkViaSocket::StopCommunication();
151cdf0e10cSrcweir }
152cdf0e10cSrcweir else
153cdf0e10cSrcweir {
154cdf0e10cSrcweir WaitForShutdown();
155cdf0e10cSrcweir return sal_True;
156cdf0e10cSrcweir }
157cdf0e10cSrcweir }
158cdf0e10cSrcweir
159cdf0e10cSrcweir
IMPL_LINK(CommunicationLinkViaSocket,ShutdownLink,void *,EMPTYARG)160cdf0e10cSrcweir IMPL_LINK( CommunicationLinkViaSocket, ShutdownLink, void*, EMPTYARG )
161cdf0e10cSrcweir {
162cdf0e10cSrcweir if ( !IsCommunicationError() )
163cdf0e10cSrcweir ShutdownCommunication();
164cdf0e10cSrcweir return 0;
165cdf0e10cSrcweir }
166cdf0e10cSrcweir
167cdf0e10cSrcweir
WaitForShutdown()168cdf0e10cSrcweir void CommunicationLinkViaSocket::WaitForShutdown()
169cdf0e10cSrcweir {
170cdf0e10cSrcweir if ( !bShutdownStarted )
171cdf0e10cSrcweir {
172cdf0e10cSrcweir aShutdownTimer.SetTimeout( 30000 ); // Should be 30 Seconds
173cdf0e10cSrcweir aShutdownTimer.SetTimeoutHdl( LINK( this, CommunicationLinkViaSocket, ShutdownLink ) );
174cdf0e10cSrcweir aShutdownTimer.Start();
175cdf0e10cSrcweir bShutdownStarted = sal_True;
176cdf0e10cSrcweir }
177cdf0e10cSrcweir if ( bDestroying )
178cdf0e10cSrcweir {
179cdf0e10cSrcweir while ( pMyManager && aShutdownTimer.IsActive() )
180cdf0e10cSrcweir {
181cdf0e10cSrcweir if ( IsCommunicationError() )
182cdf0e10cSrcweir return;
183cdf0e10cSrcweir GetpApp()->Yield();
184cdf0e10cSrcweir }
185cdf0e10cSrcweir ShutdownCommunication();
186cdf0e10cSrcweir }
187cdf0e10cSrcweir }
188cdf0e10cSrcweir
IsCommunicationError()189cdf0e10cSrcweir sal_Bool CommunicationLinkViaSocket::IsCommunicationError()
190cdf0e10cSrcweir {
191cdf0e10cSrcweir return !isRunning() || SimpleCommunicationLinkViaSocket::IsCommunicationError();
192cdf0e10cSrcweir }
193cdf0e10cSrcweir
run()194cdf0e10cSrcweir void CommunicationLinkViaSocket::run()
195cdf0e10cSrcweir {
196cdf0e10cSrcweir sal_Bool bWasError = sal_False;
197cdf0e10cSrcweir while ( schedule() && !bWasError && GetStreamSocket() )
198cdf0e10cSrcweir {
199*b82e1ef8SHerbert Dürr bWasError |= !DoReceiveDataStream();
200*b82e1ef8SHerbert Dürr if( bWasError)
201cdf0e10cSrcweir continue;
202cdf0e10cSrcweir
203cdf0e10cSrcweir TimeValue sNochEins = {0, 1000000};
204cdf0e10cSrcweir while ( schedule() && bIsInsideCallback ) // solange der letzte Callback nicht beendet ist
205cdf0e10cSrcweir sleep( sNochEins );
206cdf0e10cSrcweir SetNewPacketAsCurrent();
207cdf0e10cSrcweir StartCallback();
208cdf0e10cSrcweir {
209cdf0e10cSrcweir vos::OGuard aGuard( aMDataReceived );
210cdf0e10cSrcweir vos::OGuard aGuard2( *pMPostUserEvent );
211cdf0e10cSrcweir mlPutDataReceived.Call(this);
212cdf0e10cSrcweir }
213cdf0e10cSrcweir }
214cdf0e10cSrcweir TimeValue sNochEins = {0, 1000000};
215cdf0e10cSrcweir while ( schedule() && bIsInsideCallback ) // solange der letzte Callback nicht beendet ist
216cdf0e10cSrcweir sleep( sNochEins );
217cdf0e10cSrcweir
218cdf0e10cSrcweir StartCallback();
219cdf0e10cSrcweir {
220cdf0e10cSrcweir vos::OGuard aGuard( aMConnectionClosed );
221cdf0e10cSrcweir vos::OGuard aGuard2( *pMPostUserEvent );
222cdf0e10cSrcweir nConnectionClosedEventId = GetpApp()->PostUserEvent( LINK( this, CommunicationLinkViaSocket, ConnectionClosed ) );
223cdf0e10cSrcweir }
224cdf0e10cSrcweir }
225cdf0e10cSrcweir
DoTransferDataStream(SvStream * pDataStream,CMProtocol nProtocol)226cdf0e10cSrcweir sal_Bool CommunicationLinkViaSocket::DoTransferDataStream( SvStream *pDataStream, CMProtocol nProtocol )
227cdf0e10cSrcweir {
228cdf0e10cSrcweir if ( !isRunning() )
229cdf0e10cSrcweir return sal_False;
230cdf0e10cSrcweir
231cdf0e10cSrcweir return SimpleCommunicationLinkViaSocket::DoTransferDataStream( pDataStream, nProtocol );
232cdf0e10cSrcweir }
233cdf0e10cSrcweir
234cdf0e10cSrcweir /// Dies ist ein virtueller Link!!!
ConnectionClosed(void * EMPTYARG)235cdf0e10cSrcweir long CommunicationLinkViaSocket::ConnectionClosed( void* EMPTYARG )
236cdf0e10cSrcweir {
237cdf0e10cSrcweir {
238cdf0e10cSrcweir vos::OGuard aGuard( aMConnectionClosed );
239cdf0e10cSrcweir nConnectionClosedEventId = 0; // Achtung!! alles andere mu� oben gemacht werden.
240cdf0e10cSrcweir }
241cdf0e10cSrcweir ShutdownCommunication();
242cdf0e10cSrcweir return CommunicationLink::ConnectionClosed( );
243cdf0e10cSrcweir }
244cdf0e10cSrcweir
245cdf0e10cSrcweir /// Dies ist ein virtueller Link!!!
DataReceived(void * EMPTYARG)246cdf0e10cSrcweir long CommunicationLinkViaSocket::DataReceived( void* EMPTYARG )
247cdf0e10cSrcweir {
248cdf0e10cSrcweir {
249cdf0e10cSrcweir vos::OGuard aGuard( aMDataReceived );
250cdf0e10cSrcweir nDataReceivedEventId = 0; // Achtung!! alles andere mu� oben gemacht werden.
251cdf0e10cSrcweir }
252cdf0e10cSrcweir return CommunicationLink::DataReceived( );
253cdf0e10cSrcweir }
254cdf0e10cSrcweir
IMPL_LINK(CommunicationLinkViaSocket,PutDataReceivedHdl,CommunicationLinkViaSocket *,EMPTYARG)255cdf0e10cSrcweir IMPL_LINK( CommunicationLinkViaSocket, PutDataReceivedHdl, CommunicationLinkViaSocket*, EMPTYARG )
256cdf0e10cSrcweir {
257cdf0e10cSrcweir nDataReceivedEventId = GetpApp()->PostUserEvent( LINK( this, CommunicationLink, DataReceived ) );
258cdf0e10cSrcweir return 0;
259cdf0e10cSrcweir }
260cdf0e10cSrcweir
261cdf0e10cSrcweir
262cdf0e10cSrcweir
MultiCommunicationManager(sal_Bool bUseMultiChannel)263cdf0e10cSrcweir MultiCommunicationManager::MultiCommunicationManager( sal_Bool bUseMultiChannel )
264cdf0e10cSrcweir : CommunicationManager( bUseMultiChannel )
265cdf0e10cSrcweir , bGracefullShutdown( sal_True )
266cdf0e10cSrcweir {
267cdf0e10cSrcweir ActiveLinks = new CommunicationLinkList;
268cdf0e10cSrcweir InactiveLinks = new CommunicationLinkList;
269cdf0e10cSrcweir }
270cdf0e10cSrcweir
~MultiCommunicationManager()271cdf0e10cSrcweir MultiCommunicationManager::~MultiCommunicationManager()
272cdf0e10cSrcweir {
273cdf0e10cSrcweir StopCommunication();
274cdf0e10cSrcweir
275cdf0e10cSrcweir if ( bGracefullShutdown ) // first try to collect all callbacks for closing channels
276cdf0e10cSrcweir {
277cdf0e10cSrcweir Timer aTimeout;
278cdf0e10cSrcweir aTimeout.SetTimeout( 40000 );
279cdf0e10cSrcweir aTimeout.Start();
280cdf0e10cSrcweir sal_uInt16 nLinkCount = 0;
281cdf0e10cSrcweir sal_uInt16 nNewLinkCount = 0;
282cdf0e10cSrcweir while ( aTimeout.IsActive() )
283cdf0e10cSrcweir {
284cdf0e10cSrcweir GetpApp()->Yield();
285cdf0e10cSrcweir nNewLinkCount = GetCommunicationLinkCount();
286cdf0e10cSrcweir if ( nNewLinkCount == 0 )
287cdf0e10cSrcweir aTimeout.Stop();
288cdf0e10cSrcweir if ( nNewLinkCount != nLinkCount )
289cdf0e10cSrcweir {
290cdf0e10cSrcweir aTimeout.Start();
291cdf0e10cSrcweir nLinkCount = nNewLinkCount;
292cdf0e10cSrcweir }
293cdf0e10cSrcweir }
294cdf0e10cSrcweir }
295cdf0e10cSrcweir
296cdf0e10cSrcweir // Alles weghauen, was nicht rechtzeitig auf die B�ume gekommen ist
297cdf0e10cSrcweir // Was bei StopCommunication �brig geblieben ist, da es sich asynchron austragen wollte
298cdf0e10cSrcweir sal_uInt16 i = ActiveLinks->Count();
299cdf0e10cSrcweir while ( i-- )
300cdf0e10cSrcweir {
301cdf0e10cSrcweir CommunicationLinkRef rTempLink = ActiveLinks->GetObject( i );
302cdf0e10cSrcweir ActiveLinks->Remove( i );
303cdf0e10cSrcweir rTempLink->InvalidateManager();
304cdf0e10cSrcweir rTempLink->ReleaseReference();
305cdf0e10cSrcweir }
306cdf0e10cSrcweir delete ActiveLinks;
307cdf0e10cSrcweir
308cdf0e10cSrcweir /// Die Links zwischen ConnectionClosed und Destruktor.
309cdf0e10cSrcweir /// Hier NICHT gerefcounted, da sie sich sonst im Kreis festhaten w�rden,
310cdf0e10cSrcweir /// da die Links sich erst in ihrem Destruktor austragen
311cdf0e10cSrcweir i = InactiveLinks->Count();
312cdf0e10cSrcweir while ( i-- )
313cdf0e10cSrcweir {
314cdf0e10cSrcweir CommunicationLinkRef rTempLink = InactiveLinks->GetObject( i );
315cdf0e10cSrcweir InactiveLinks->Remove( i );
316cdf0e10cSrcweir rTempLink->InvalidateManager();
317cdf0e10cSrcweir }
318cdf0e10cSrcweir delete InactiveLinks;
319cdf0e10cSrcweir }
320cdf0e10cSrcweir
StopCommunication()321cdf0e10cSrcweir sal_Bool MultiCommunicationManager::StopCommunication()
322cdf0e10cSrcweir {
323cdf0e10cSrcweir // Alle Verbindungen abbrechen
324cdf0e10cSrcweir // ConnectionClosed entfernt die Links aus der Liste. Je nach Implementation syncron
325cdf0e10cSrcweir // oder asyncron. Daher Von oben nach unten Abr�umen, so da� sich nichts verschiebt.
326cdf0e10cSrcweir sal_uInt16 i = ActiveLinks->Count();
327cdf0e10cSrcweir int nFail = 0;
328cdf0e10cSrcweir while ( i )
329cdf0e10cSrcweir {
330cdf0e10cSrcweir if ( !ActiveLinks->GetObject(i-1)->StopCommunication() )
331cdf0e10cSrcweir nFail++; // Hochz�hlen, da Verbindung sich nicht (sofort) beenden l�sst.
332cdf0e10cSrcweir i--;
333cdf0e10cSrcweir }
334cdf0e10cSrcweir
335cdf0e10cSrcweir return nFail == 0;
336cdf0e10cSrcweir }
337cdf0e10cSrcweir
IsLinkValid(CommunicationLink * pCL)338cdf0e10cSrcweir sal_Bool MultiCommunicationManager::IsLinkValid( CommunicationLink* pCL )
339cdf0e10cSrcweir {
340cdf0e10cSrcweir if ( ActiveLinks->Seek_Entry( pCL ) )
341cdf0e10cSrcweir return sal_True;
342cdf0e10cSrcweir else
343cdf0e10cSrcweir return sal_False;
344cdf0e10cSrcweir }
345cdf0e10cSrcweir
GetCommunicationLinkCount()346cdf0e10cSrcweir sal_uInt16 MultiCommunicationManager::GetCommunicationLinkCount()
347cdf0e10cSrcweir {
348cdf0e10cSrcweir return ActiveLinks->Count();
349cdf0e10cSrcweir }
350cdf0e10cSrcweir
GetCommunicationLink(sal_uInt16 nNr)351cdf0e10cSrcweir CommunicationLinkRef MultiCommunicationManager::GetCommunicationLink( sal_uInt16 nNr )
352cdf0e10cSrcweir {
353cdf0e10cSrcweir return ActiveLinks->GetObject( nNr );
354cdf0e10cSrcweir }
355cdf0e10cSrcweir
CallConnectionOpened(CommunicationLink * pCL)356cdf0e10cSrcweir void MultiCommunicationManager::CallConnectionOpened( CommunicationLink* pCL )
357cdf0e10cSrcweir {
358cdf0e10cSrcweir CommunicationLinkRef rHold(pCL); // H�lt den Zeiger bis zum Ende des calls
359cdf0e10cSrcweir ActiveLinks->C40_PTR_INSERT(CommunicationLink, pCL);
360cdf0e10cSrcweir rHold->AddRef();
361cdf0e10cSrcweir
362cdf0e10cSrcweir CommunicationManager::CallConnectionOpened( pCL );
363cdf0e10cSrcweir }
364cdf0e10cSrcweir
CallConnectionClosed(CommunicationLink * pCL)365cdf0e10cSrcweir void MultiCommunicationManager::CallConnectionClosed( CommunicationLink* pCL )
366cdf0e10cSrcweir {
367cdf0e10cSrcweir CommunicationLinkRef rHold(pCL); // H�lt denm Zeiger bis zum Ende des calls
368cdf0e10cSrcweir
369cdf0e10cSrcweir CommunicationManager::CallConnectionClosed( pCL );
370cdf0e10cSrcweir
371cdf0e10cSrcweir sal_uInt16 nPos;
372cdf0e10cSrcweir if ( ActiveLinks->Seek_Entry( pCL, &nPos ) )
373cdf0e10cSrcweir {
374cdf0e10cSrcweir InactiveLinks->C40_PTR_INSERT(CommunicationLink, pCL); // Ohne Reference
375cdf0e10cSrcweir ActiveLinks->Remove( nPos );
376cdf0e10cSrcweir }
377cdf0e10cSrcweir pCL->ReleaseReference();
378cdf0e10cSrcweir
379cdf0e10cSrcweir bIsCommunicationRunning = ActiveLinks->Count() > 0;
380cdf0e10cSrcweir // delete pCL;
381cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
382cdf0e10cSrcweir rHold->bFlag = sal_True;
383cdf0e10cSrcweir #endif
384cdf0e10cSrcweir }
385cdf0e10cSrcweir
DestroyingLink(CommunicationLink * pCL)386cdf0e10cSrcweir void MultiCommunicationManager::DestroyingLink( CommunicationLink *pCL )
387cdf0e10cSrcweir {
388cdf0e10cSrcweir sal_uInt16 nPos;
389cdf0e10cSrcweir if ( InactiveLinks->Seek_Entry( pCL, &nPos ) )
390cdf0e10cSrcweir InactiveLinks->Remove( nPos );
391cdf0e10cSrcweir pCL->InvalidateManager();
392cdf0e10cSrcweir }
393cdf0e10cSrcweir
394cdf0e10cSrcweir
395cdf0e10cSrcweir
CommunicationManagerClient(sal_Bool bUseMultiChannel)396cdf0e10cSrcweir CommunicationManagerClient::CommunicationManagerClient( sal_Bool bUseMultiChannel )
397cdf0e10cSrcweir : MultiCommunicationManager( bUseMultiChannel )
398cdf0e10cSrcweir {
399cdf0e10cSrcweir ByteString aApplication("Something inside ");
400cdf0e10cSrcweir aApplication.Append( ByteString( DirEntry( Application::GetAppFileName() ).GetName(), gsl_getSystemTextEncoding() ) );
401cdf0e10cSrcweir SetApplication( aApplication );
402cdf0e10cSrcweir }
403cdf0e10cSrcweir
404cdf0e10cSrcweir
405cdf0e10cSrcweir
CommunicationManagerServerViaSocket(sal_uLong nPort,sal_uInt16 nMaxCon,sal_Bool bUseMultiChannel)406cdf0e10cSrcweir CommunicationManagerServerViaSocket::CommunicationManagerServerViaSocket( sal_uLong nPort, sal_uInt16 nMaxCon, sal_Bool bUseMultiChannel )
407cdf0e10cSrcweir : CommunicationManagerServer( bUseMultiChannel )
408cdf0e10cSrcweir , nPortToListen( nPort )
409cdf0e10cSrcweir , nMaxConnections( nMaxCon )
410cdf0e10cSrcweir , pAcceptThread( NULL )
411cdf0e10cSrcweir {
412cdf0e10cSrcweir }
413cdf0e10cSrcweir
~CommunicationManagerServerViaSocket()414cdf0e10cSrcweir CommunicationManagerServerViaSocket::~CommunicationManagerServerViaSocket()
415cdf0e10cSrcweir {
416cdf0e10cSrcweir StopCommunication();
417cdf0e10cSrcweir }
418cdf0e10cSrcweir
StartCommunication()419cdf0e10cSrcweir sal_Bool CommunicationManagerServerViaSocket::StartCommunication()
420cdf0e10cSrcweir {
421cdf0e10cSrcweir if ( !pAcceptThread )
422cdf0e10cSrcweir pAcceptThread = new CommunicationManagerServerAcceptThread( this, nPortToListen, nMaxConnections );
423cdf0e10cSrcweir return sal_True;
424cdf0e10cSrcweir }
425cdf0e10cSrcweir
426cdf0e10cSrcweir
StopCommunication()427cdf0e10cSrcweir sal_Bool CommunicationManagerServerViaSocket::StopCommunication()
428cdf0e10cSrcweir {
429cdf0e10cSrcweir // Erst den Acceptor anhalten
430cdf0e10cSrcweir delete pAcceptThread;
431cdf0e10cSrcweir pAcceptThread = NULL;
432cdf0e10cSrcweir
433cdf0e10cSrcweir // Dann alle Verbindungen kappen
434cdf0e10cSrcweir return CommunicationManagerServer::StopCommunication();
435cdf0e10cSrcweir }
436cdf0e10cSrcweir
437cdf0e10cSrcweir
AddConnection(CommunicationLink * pNewConnection)438cdf0e10cSrcweir void CommunicationManagerServerViaSocket::AddConnection( CommunicationLink *pNewConnection )
439cdf0e10cSrcweir {
440cdf0e10cSrcweir CallConnectionOpened( pNewConnection );
441cdf0e10cSrcweir }
442cdf0e10cSrcweir
443cdf0e10cSrcweir
CommunicationManagerServerAcceptThread(CommunicationManagerServerViaSocket * pServer,sal_uLong nPort,sal_uInt16 nMaxCon)444cdf0e10cSrcweir CommunicationManagerServerAcceptThread::CommunicationManagerServerAcceptThread( CommunicationManagerServerViaSocket* pServer, sal_uLong nPort, sal_uInt16 nMaxCon )
445cdf0e10cSrcweir : pMyServer( pServer )
446cdf0e10cSrcweir , pAcceptorSocket( NULL )
447cdf0e10cSrcweir , nPortToListen( nPort )
448cdf0e10cSrcweir , nMaxConnections( nMaxCon )
449cdf0e10cSrcweir , nAddConnectionEventId( 0 )
450cdf0e10cSrcweir , xmNewConnection( NULL )
451cdf0e10cSrcweir {
452cdf0e10cSrcweir if ( !pMPostUserEvent )
453cdf0e10cSrcweir pMPostUserEvent = new vos::OMutex;
454cdf0e10cSrcweir create();
455cdf0e10cSrcweir }
456cdf0e10cSrcweir
457cdf0e10cSrcweir
~CommunicationManagerServerAcceptThread()458cdf0e10cSrcweir CommunicationManagerServerAcceptThread::~CommunicationManagerServerAcceptThread()
459cdf0e10cSrcweir {
460cdf0e10cSrcweir #ifndef aUNX // Weil das Accept nicht abgebrochen werden kann, so terminiert wenigstens das Prog
461cdf0e10cSrcweir // #62855# pl: gilt auch bei anderen Unixen
462cdf0e10cSrcweir // die richtige Loesung waere natuerlich, etwas auf die pipe zu schreiben,
463cdf0e10cSrcweir // was der thread als Abbruchbedingung erkennt
464cdf0e10cSrcweir // oder wenigstens ein kill anstatt join
465cdf0e10cSrcweir terminate();
466cdf0e10cSrcweir if ( pAcceptorSocket )
467cdf0e10cSrcweir pAcceptorSocket->close(); // Dann das Accept unterbrechen
468cdf0e10cSrcweir
469cdf0e10cSrcweir join(); // Warten bis fertig
470cdf0e10cSrcweir
471cdf0e10cSrcweir if ( pAcceptorSocket )
472cdf0e10cSrcweir {
473cdf0e10cSrcweir delete pAcceptorSocket;
474cdf0e10cSrcweir pAcceptorSocket = NULL;
475cdf0e10cSrcweir }
476cdf0e10cSrcweir #else
477cdf0e10cSrcweir DEBUGPRINTF ("Destructor CommunicationManagerServerAcceptThread �bersprungen!!!! (wegen Solaris BUG)\n");
478cdf0e10cSrcweir #endif
479cdf0e10cSrcweir {
480cdf0e10cSrcweir vos::OGuard aGuard( aMAddConnection );
481cdf0e10cSrcweir if ( nAddConnectionEventId )
482cdf0e10cSrcweir {
483cdf0e10cSrcweir GetpApp()->RemoveUserEvent( nAddConnectionEventId );
484cdf0e10cSrcweir nAddConnectionEventId = 0;
485cdf0e10cSrcweir CommunicationLinkRef xNewConnection = GetNewConnection();
486cdf0e10cSrcweir INFO_MSG( CByteString("Event gel�scht"),
487cdf0e10cSrcweir CByteString( "AddConnectionEvent aus Queue gel�scht"),
488cdf0e10cSrcweir CM_MISC, xNewConnection );
489cdf0e10cSrcweir xNewConnection->InvalidateManager();
490cdf0e10cSrcweir xNewConnection.Clear(); // sollte das Objekt hier l�schen
491cdf0e10cSrcweir }
492cdf0e10cSrcweir }
493cdf0e10cSrcweir }
494cdf0e10cSrcweir
run()495cdf0e10cSrcweir void CommunicationManagerServerAcceptThread::run()
496cdf0e10cSrcweir {
497cdf0e10cSrcweir if ( !nPortToListen )
498cdf0e10cSrcweir return;
499cdf0e10cSrcweir
500cdf0e10cSrcweir pAcceptorSocket = new vos::OAcceptorSocket();
501cdf0e10cSrcweir vos::OInetSocketAddr Addr;
502cdf0e10cSrcweir Addr.setPort( nPortToListen );
503cdf0e10cSrcweir pAcceptorSocket->setReuseAddr( 1 );
504cdf0e10cSrcweir if ( !pAcceptorSocket->bind( Addr ) )
505cdf0e10cSrcweir {
506cdf0e10cSrcweir return;
507cdf0e10cSrcweir }
508cdf0e10cSrcweir if ( !pAcceptorSocket->listen( nMaxConnections ) )
509cdf0e10cSrcweir {
510cdf0e10cSrcweir return;
511cdf0e10cSrcweir }
512cdf0e10cSrcweir
513cdf0e10cSrcweir
514cdf0e10cSrcweir vos::OStreamSocket *pStreamSocket = NULL;
515cdf0e10cSrcweir
516cdf0e10cSrcweir while ( schedule() )
517cdf0e10cSrcweir {
518cdf0e10cSrcweir pStreamSocket = new vos::OStreamSocket;
519cdf0e10cSrcweir switch ( pAcceptorSocket->acceptConnection( *pStreamSocket ) )
520cdf0e10cSrcweir {
521cdf0e10cSrcweir case vos::ISocketTypes::TResult_Ok:
522cdf0e10cSrcweir {
523cdf0e10cSrcweir pStreamSocket->setTcpNoDelay( 1 );
524cdf0e10cSrcweir
525cdf0e10cSrcweir TimeValue sNochEins = {0, 100};
526cdf0e10cSrcweir while ( schedule() && xmNewConnection.Is() ) // Solange die letzte Connection nicht abgeholt wurde warten wir
527cdf0e10cSrcweir sleep( sNochEins );
528cdf0e10cSrcweir xmNewConnection = new CommunicationLinkViaSocket( pMyServer, pStreamSocket );
529cdf0e10cSrcweir xmNewConnection->StartCallback();
530cdf0e10cSrcweir {
531cdf0e10cSrcweir vos::OGuard aGuard( aMAddConnection );
532cdf0e10cSrcweir vos::OGuard aGuard2( *pMPostUserEvent );
533cdf0e10cSrcweir nAddConnectionEventId = GetpApp()->PostUserEvent( LINK( this, CommunicationManagerServerAcceptThread, AddConnection ) );
534cdf0e10cSrcweir }
535cdf0e10cSrcweir }
536cdf0e10cSrcweir break;
537cdf0e10cSrcweir case vos::ISocketTypes::TResult_TimedOut:
538cdf0e10cSrcweir delete pStreamSocket;
539cdf0e10cSrcweir pStreamSocket = NULL;
540cdf0e10cSrcweir break;
541cdf0e10cSrcweir case vos::ISocketTypes::TResult_Error:
542cdf0e10cSrcweir delete pStreamSocket;
543cdf0e10cSrcweir pStreamSocket = NULL;
544cdf0e10cSrcweir break;
545cdf0e10cSrcweir
546cdf0e10cSrcweir case vos::ISocketTypes::TResult_Interrupted:
547cdf0e10cSrcweir case vos::ISocketTypes::TResult_InProgress:
548cdf0e10cSrcweir break; // -Wall not handled...
549cdf0e10cSrcweir }
550cdf0e10cSrcweir }
551cdf0e10cSrcweir }
552cdf0e10cSrcweir
553cdf0e10cSrcweir
IMPL_LINK(CommunicationManagerServerAcceptThread,AddConnection,void *,EMPTYARG)554cdf0e10cSrcweir IMPL_LINK( CommunicationManagerServerAcceptThread, AddConnection, void*, EMPTYARG )
555cdf0e10cSrcweir {
556cdf0e10cSrcweir {
557cdf0e10cSrcweir vos::OGuard aGuard( aMAddConnection );
558cdf0e10cSrcweir nAddConnectionEventId = 0;
559cdf0e10cSrcweir }
560cdf0e10cSrcweir pMyServer->AddConnection( xmNewConnection );
561cdf0e10cSrcweir xmNewConnection.Clear();
562cdf0e10cSrcweir return 1;
563cdf0e10cSrcweir }
564cdf0e10cSrcweir
565cdf0e10cSrcweir
566cdf0e10cSrcweir #define GETSET(aVar, KeyName, Dafault) \
567cdf0e10cSrcweir aVar = aConf.ReadKey(KeyName,"No Entry"); \
568cdf0e10cSrcweir if ( aVar == "No Entry" ) \
569cdf0e10cSrcweir { \
570cdf0e10cSrcweir aVar = Dafault; \
571cdf0e10cSrcweir aConf.WriteKey(KeyName, aVar); \
572cdf0e10cSrcweir }
573cdf0e10cSrcweir
574cdf0e10cSrcweir
CommunicationManagerClientViaSocket(ByteString aHost,sal_uLong nPort,sal_Bool bUseMultiChannel)575cdf0e10cSrcweir CommunicationManagerClientViaSocket::CommunicationManagerClientViaSocket( ByteString aHost, sal_uLong nPort, sal_Bool bUseMultiChannel )
576cdf0e10cSrcweir : CommunicationManagerClient( bUseMultiChannel )
577cdf0e10cSrcweir , aHostToTalk( aHost )
578cdf0e10cSrcweir , nPortToTalk( nPort )
579cdf0e10cSrcweir {
580cdf0e10cSrcweir }
581cdf0e10cSrcweir
CommunicationManagerClientViaSocket(sal_Bool bUseMultiChannel)582cdf0e10cSrcweir CommunicationManagerClientViaSocket::CommunicationManagerClientViaSocket( sal_Bool bUseMultiChannel )
583cdf0e10cSrcweir : CommunicationManagerClient( bUseMultiChannel )
584cdf0e10cSrcweir , aHostToTalk( "" )
585cdf0e10cSrcweir , nPortToTalk( 0 )
586cdf0e10cSrcweir {
587cdf0e10cSrcweir }
588cdf0e10cSrcweir
~CommunicationManagerClientViaSocket()589cdf0e10cSrcweir CommunicationManagerClientViaSocket::~CommunicationManagerClientViaSocket()
590cdf0e10cSrcweir {
591cdf0e10cSrcweir }
592cdf0e10cSrcweir
593cdf0e10cSrcweir
594