xref: /AOO41X/main/automation/source/communi/communi.cxx (revision 9d1279ece119b840266617e54d20d4d5fa7aea95)
1*9d1279ecSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*9d1279ecSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*9d1279ecSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*9d1279ecSAndrew Rist  * distributed with this work for additional information
6*9d1279ecSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*9d1279ecSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*9d1279ecSAndrew Rist  * "License"); you may not use this file except in compliance
9*9d1279ecSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*9d1279ecSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*9d1279ecSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*9d1279ecSAndrew Rist  * software distributed under the License is distributed on an
15*9d1279ecSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*9d1279ecSAndrew Rist  * KIND, either express or implied.  See the License for the
17*9d1279ecSAndrew Rist  * specific language governing permissions and limitations
18*9d1279ecSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*9d1279ecSAndrew Rist  *************************************************************/
21*9d1279ecSAndrew Rist 
22*9d1279ecSAndrew 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 
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 
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 
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 
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 
160cdf0e10cSrcweir IMPL_LINK( CommunicationLinkViaSocket, ShutdownLink, void*, EMPTYARG )
161cdf0e10cSrcweir {
162cdf0e10cSrcweir 	if ( !IsCommunicationError() )
163cdf0e10cSrcweir     	ShutdownCommunication();
164cdf0e10cSrcweir     return 0;
165cdf0e10cSrcweir }
166cdf0e10cSrcweir 
167cdf0e10cSrcweir 
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 
189cdf0e10cSrcweir sal_Bool CommunicationLinkViaSocket::IsCommunicationError()
190cdf0e10cSrcweir {
191cdf0e10cSrcweir 	return !isRunning() || SimpleCommunicationLinkViaSocket::IsCommunicationError();
192cdf0e10cSrcweir }
193cdf0e10cSrcweir 
194cdf0e10cSrcweir void CommunicationLinkViaSocket::run()
195cdf0e10cSrcweir {
196cdf0e10cSrcweir 	sal_Bool bWasError = sal_False;
197cdf0e10cSrcweir     while ( schedule() && !bWasError && GetStreamSocket() )
198cdf0e10cSrcweir 	{
199cdf0e10cSrcweir 		if ( bWasError |= !DoReceiveDataStream() )
200cdf0e10cSrcweir 			continue;
201cdf0e10cSrcweir 
202cdf0e10cSrcweir 		TimeValue sNochEins = {0, 1000000};
203cdf0e10cSrcweir 		while ( schedule() && bIsInsideCallback )	// solange der letzte Callback nicht beendet ist
204cdf0e10cSrcweir 			sleep( sNochEins );
205cdf0e10cSrcweir 		SetNewPacketAsCurrent();
206cdf0e10cSrcweir 		StartCallback();
207cdf0e10cSrcweir 		{
208cdf0e10cSrcweir 			vos::OGuard aGuard( aMDataReceived );
209cdf0e10cSrcweir             vos::OGuard aGuard2( *pMPostUserEvent );
210cdf0e10cSrcweir             mlPutDataReceived.Call(this);
211cdf0e10cSrcweir 		}
212cdf0e10cSrcweir 	}
213cdf0e10cSrcweir 	TimeValue sNochEins = {0, 1000000};
214cdf0e10cSrcweir 	while ( schedule() && bIsInsideCallback )	// solange der letzte Callback nicht beendet ist
215cdf0e10cSrcweir 		sleep( sNochEins );
216cdf0e10cSrcweir 
217cdf0e10cSrcweir     StartCallback();
218cdf0e10cSrcweir 	{
219cdf0e10cSrcweir 		vos::OGuard aGuard( aMConnectionClosed );
220cdf0e10cSrcweir         vos::OGuard aGuard2( *pMPostUserEvent );
221cdf0e10cSrcweir 		nConnectionClosedEventId = GetpApp()->PostUserEvent( LINK( this, CommunicationLinkViaSocket, ConnectionClosed ) );
222cdf0e10cSrcweir 	}
223cdf0e10cSrcweir }
224cdf0e10cSrcweir 
225cdf0e10cSrcweir sal_Bool CommunicationLinkViaSocket::DoTransferDataStream( SvStream *pDataStream, CMProtocol nProtocol )
226cdf0e10cSrcweir {
227cdf0e10cSrcweir 	if ( !isRunning() )
228cdf0e10cSrcweir 		return sal_False;
229cdf0e10cSrcweir 
230cdf0e10cSrcweir 	return SimpleCommunicationLinkViaSocket::DoTransferDataStream( pDataStream, nProtocol );
231cdf0e10cSrcweir }
232cdf0e10cSrcweir 
233cdf0e10cSrcweir /// Dies ist ein virtueller Link!!!
234cdf0e10cSrcweir long CommunicationLinkViaSocket::ConnectionClosed( void* EMPTYARG )
235cdf0e10cSrcweir {
236cdf0e10cSrcweir 	{
237cdf0e10cSrcweir 		vos::OGuard aGuard( aMConnectionClosed );
238cdf0e10cSrcweir 		nConnectionClosedEventId = 0;	// Achtung!! alles andere mu� oben gemacht werden.
239cdf0e10cSrcweir 	}
240cdf0e10cSrcweir 	ShutdownCommunication();
241cdf0e10cSrcweir 	return CommunicationLink::ConnectionClosed( );
242cdf0e10cSrcweir }
243cdf0e10cSrcweir 
244cdf0e10cSrcweir /// Dies ist ein virtueller Link!!!
245cdf0e10cSrcweir long CommunicationLinkViaSocket::DataReceived( void* EMPTYARG )
246cdf0e10cSrcweir {
247cdf0e10cSrcweir 	{
248cdf0e10cSrcweir 		vos::OGuard aGuard( aMDataReceived );
249cdf0e10cSrcweir 		nDataReceivedEventId = 0;	// Achtung!! alles andere mu� oben gemacht werden.
250cdf0e10cSrcweir 	}
251cdf0e10cSrcweir 	return CommunicationLink::DataReceived( );
252cdf0e10cSrcweir }
253cdf0e10cSrcweir 
254cdf0e10cSrcweir IMPL_LINK( CommunicationLinkViaSocket, PutDataReceivedHdl, CommunicationLinkViaSocket*, EMPTYARG )
255cdf0e10cSrcweir {
256cdf0e10cSrcweir     nDataReceivedEventId = GetpApp()->PostUserEvent( LINK( this, CommunicationLink, DataReceived ) );
257cdf0e10cSrcweir     return 0;
258cdf0e10cSrcweir }
259cdf0e10cSrcweir 
260cdf0e10cSrcweir 
261cdf0e10cSrcweir 
262cdf0e10cSrcweir MultiCommunicationManager::MultiCommunicationManager( sal_Bool bUseMultiChannel )
263cdf0e10cSrcweir : CommunicationManager( bUseMultiChannel )
264cdf0e10cSrcweir , bGracefullShutdown( sal_True )
265cdf0e10cSrcweir {
266cdf0e10cSrcweir 	ActiveLinks = new CommunicationLinkList;
267cdf0e10cSrcweir 	InactiveLinks = new CommunicationLinkList;
268cdf0e10cSrcweir }
269cdf0e10cSrcweir 
270cdf0e10cSrcweir MultiCommunicationManager::~MultiCommunicationManager()
271cdf0e10cSrcweir {
272cdf0e10cSrcweir 	StopCommunication();
273cdf0e10cSrcweir 
274cdf0e10cSrcweir     if ( bGracefullShutdown )   // first try to collect all callbacks for closing channels
275cdf0e10cSrcweir     {
276cdf0e10cSrcweir         Timer aTimeout;
277cdf0e10cSrcweir         aTimeout.SetTimeout( 40000 );
278cdf0e10cSrcweir         aTimeout.Start();
279cdf0e10cSrcweir         sal_uInt16 nLinkCount = 0;
280cdf0e10cSrcweir         sal_uInt16 nNewLinkCount = 0;
281cdf0e10cSrcweir         while ( aTimeout.IsActive() )
282cdf0e10cSrcweir         {
283cdf0e10cSrcweir             GetpApp()->Yield();
284cdf0e10cSrcweir             nNewLinkCount = GetCommunicationLinkCount();
285cdf0e10cSrcweir             if ( nNewLinkCount == 0 )
286cdf0e10cSrcweir                 aTimeout.Stop();
287cdf0e10cSrcweir             if ( nNewLinkCount != nLinkCount )
288cdf0e10cSrcweir             {
289cdf0e10cSrcweir                 aTimeout.Start();
290cdf0e10cSrcweir                 nLinkCount = nNewLinkCount;
291cdf0e10cSrcweir             }
292cdf0e10cSrcweir         }
293cdf0e10cSrcweir     }
294cdf0e10cSrcweir 
295cdf0e10cSrcweir 	// Alles weghauen, was nicht rechtzeitig auf die B�ume gekommen ist
296cdf0e10cSrcweir 	// Was bei StopCommunication �brig geblieben ist, da es sich asynchron austragen wollte
297cdf0e10cSrcweir 	sal_uInt16 i = ActiveLinks->Count();
298cdf0e10cSrcweir 	while ( i-- )
299cdf0e10cSrcweir 	{
300cdf0e10cSrcweir 		CommunicationLinkRef rTempLink = ActiveLinks->GetObject( i );
301cdf0e10cSrcweir 		ActiveLinks->Remove( i );
302cdf0e10cSrcweir 		rTempLink->InvalidateManager();
303cdf0e10cSrcweir 		rTempLink->ReleaseReference();
304cdf0e10cSrcweir 	}
305cdf0e10cSrcweir 	delete ActiveLinks;
306cdf0e10cSrcweir 
307cdf0e10cSrcweir 	/// Die Links zwischen ConnectionClosed und Destruktor.
308cdf0e10cSrcweir 	/// Hier NICHT gerefcounted, da sie sich sonst im Kreis festhaten w�rden,
309cdf0e10cSrcweir 	/// da die Links sich erst in ihrem Destruktor austragen
310cdf0e10cSrcweir 	i = InactiveLinks->Count();
311cdf0e10cSrcweir 	while ( i-- )
312cdf0e10cSrcweir 	{
313cdf0e10cSrcweir 		CommunicationLinkRef rTempLink = InactiveLinks->GetObject( i );
314cdf0e10cSrcweir 		InactiveLinks->Remove( i );
315cdf0e10cSrcweir 		rTempLink->InvalidateManager();
316cdf0e10cSrcweir 	}
317cdf0e10cSrcweir 	delete InactiveLinks;
318cdf0e10cSrcweir }
319cdf0e10cSrcweir 
320cdf0e10cSrcweir sal_Bool MultiCommunicationManager::StopCommunication()
321cdf0e10cSrcweir {
322cdf0e10cSrcweir 	// Alle Verbindungen abbrechen
323cdf0e10cSrcweir 	// ConnectionClosed entfernt die Links aus der Liste. Je nach Implementation syncron
324cdf0e10cSrcweir 	// oder asyncron. Daher Von oben nach unten Abr�umen, so da� sich nichts verschiebt.
325cdf0e10cSrcweir 	sal_uInt16 i = ActiveLinks->Count();
326cdf0e10cSrcweir 	int nFail = 0;
327cdf0e10cSrcweir 	while ( i )
328cdf0e10cSrcweir 	{
329cdf0e10cSrcweir 		if ( !ActiveLinks->GetObject(i-1)->StopCommunication() )
330cdf0e10cSrcweir             nFail++;    // Hochz�hlen, da Verbindung sich nicht (sofort) beenden l�sst.
331cdf0e10cSrcweir 		i--;
332cdf0e10cSrcweir 	}
333cdf0e10cSrcweir 
334cdf0e10cSrcweir 	return nFail == 0;
335cdf0e10cSrcweir }
336cdf0e10cSrcweir 
337cdf0e10cSrcweir sal_Bool MultiCommunicationManager::IsLinkValid( CommunicationLink* pCL )
338cdf0e10cSrcweir {
339cdf0e10cSrcweir 	if ( ActiveLinks->Seek_Entry( pCL ) )
340cdf0e10cSrcweir 		return sal_True;
341cdf0e10cSrcweir 	else
342cdf0e10cSrcweir 		return sal_False;
343cdf0e10cSrcweir }
344cdf0e10cSrcweir 
345cdf0e10cSrcweir sal_uInt16 MultiCommunicationManager::GetCommunicationLinkCount()
346cdf0e10cSrcweir {
347cdf0e10cSrcweir 	return ActiveLinks->Count();
348cdf0e10cSrcweir }
349cdf0e10cSrcweir 
350cdf0e10cSrcweir CommunicationLinkRef MultiCommunicationManager::GetCommunicationLink( sal_uInt16 nNr )
351cdf0e10cSrcweir {
352cdf0e10cSrcweir 	return ActiveLinks->GetObject( nNr );
353cdf0e10cSrcweir }
354cdf0e10cSrcweir 
355cdf0e10cSrcweir void MultiCommunicationManager::CallConnectionOpened( CommunicationLink* pCL )
356cdf0e10cSrcweir {
357cdf0e10cSrcweir 	CommunicationLinkRef rHold(pCL);	// H�lt den Zeiger bis zum Ende des calls
358cdf0e10cSrcweir 	ActiveLinks->C40_PTR_INSERT(CommunicationLink, pCL);
359cdf0e10cSrcweir 	rHold->AddRef();
360cdf0e10cSrcweir 
361cdf0e10cSrcweir 	CommunicationManager::CallConnectionOpened( pCL );
362cdf0e10cSrcweir }
363cdf0e10cSrcweir 
364cdf0e10cSrcweir void MultiCommunicationManager::CallConnectionClosed( CommunicationLink* pCL )
365cdf0e10cSrcweir {
366cdf0e10cSrcweir 	CommunicationLinkRef rHold(pCL);	// H�lt denm Zeiger bis zum Ende des calls
367cdf0e10cSrcweir 
368cdf0e10cSrcweir 	CommunicationManager::CallConnectionClosed( pCL );
369cdf0e10cSrcweir 
370cdf0e10cSrcweir 	sal_uInt16 nPos;
371cdf0e10cSrcweir 	if ( ActiveLinks->Seek_Entry( pCL, &nPos ) )
372cdf0e10cSrcweir 	{
373cdf0e10cSrcweir 		InactiveLinks->C40_PTR_INSERT(CommunicationLink, pCL);	// Ohne Reference
374cdf0e10cSrcweir 		ActiveLinks->Remove( nPos );
375cdf0e10cSrcweir 	}
376cdf0e10cSrcweir 	pCL->ReleaseReference();
377cdf0e10cSrcweir 
378cdf0e10cSrcweir 	bIsCommunicationRunning = ActiveLinks->Count() > 0;
379cdf0e10cSrcweir //	delete pCL;
380cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
381cdf0e10cSrcweir         rHold->bFlag = sal_True;
382cdf0e10cSrcweir #endif
383cdf0e10cSrcweir }
384cdf0e10cSrcweir 
385cdf0e10cSrcweir void MultiCommunicationManager::DestroyingLink( CommunicationLink *pCL )
386cdf0e10cSrcweir {
387cdf0e10cSrcweir 	sal_uInt16 nPos;
388cdf0e10cSrcweir 	if ( InactiveLinks->Seek_Entry( pCL, &nPos ) )
389cdf0e10cSrcweir 		InactiveLinks->Remove( nPos );
390cdf0e10cSrcweir 	pCL->InvalidateManager();
391cdf0e10cSrcweir }
392cdf0e10cSrcweir 
393cdf0e10cSrcweir 
394cdf0e10cSrcweir 
395cdf0e10cSrcweir CommunicationManagerClient::CommunicationManagerClient( sal_Bool bUseMultiChannel )
396cdf0e10cSrcweir : MultiCommunicationManager( bUseMultiChannel )
397cdf0e10cSrcweir {
398cdf0e10cSrcweir 	ByteString aApplication("Something inside ");
399cdf0e10cSrcweir 	aApplication.Append( ByteString( DirEntry( Application::GetAppFileName() ).GetName(), gsl_getSystemTextEncoding() ) );
400cdf0e10cSrcweir     SetApplication( aApplication );
401cdf0e10cSrcweir }
402cdf0e10cSrcweir 
403cdf0e10cSrcweir 
404cdf0e10cSrcweir 
405cdf0e10cSrcweir CommunicationManagerServerViaSocket::CommunicationManagerServerViaSocket( sal_uLong nPort, sal_uInt16 nMaxCon, sal_Bool bUseMultiChannel )
406cdf0e10cSrcweir : CommunicationManagerServer( bUseMultiChannel )
407cdf0e10cSrcweir , nPortToListen( nPort )
408cdf0e10cSrcweir , nMaxConnections( nMaxCon )
409cdf0e10cSrcweir , pAcceptThread( NULL )
410cdf0e10cSrcweir {
411cdf0e10cSrcweir }
412cdf0e10cSrcweir 
413cdf0e10cSrcweir CommunicationManagerServerViaSocket::~CommunicationManagerServerViaSocket()
414cdf0e10cSrcweir {
415cdf0e10cSrcweir 	StopCommunication();
416cdf0e10cSrcweir }
417cdf0e10cSrcweir 
418cdf0e10cSrcweir sal_Bool CommunicationManagerServerViaSocket::StartCommunication()
419cdf0e10cSrcweir {
420cdf0e10cSrcweir 	if ( !pAcceptThread )
421cdf0e10cSrcweir 		pAcceptThread = new CommunicationManagerServerAcceptThread( this, nPortToListen, nMaxConnections );
422cdf0e10cSrcweir 	return sal_True;
423cdf0e10cSrcweir }
424cdf0e10cSrcweir 
425cdf0e10cSrcweir 
426cdf0e10cSrcweir sal_Bool CommunicationManagerServerViaSocket::StopCommunication()
427cdf0e10cSrcweir {
428cdf0e10cSrcweir 	// Erst den Acceptor anhalten
429cdf0e10cSrcweir 	delete pAcceptThread;
430cdf0e10cSrcweir 	pAcceptThread = NULL;
431cdf0e10cSrcweir 
432cdf0e10cSrcweir 	// Dann alle Verbindungen kappen
433cdf0e10cSrcweir 	return CommunicationManagerServer::StopCommunication();
434cdf0e10cSrcweir }
435cdf0e10cSrcweir 
436cdf0e10cSrcweir 
437cdf0e10cSrcweir void CommunicationManagerServerViaSocket::AddConnection( CommunicationLink *pNewConnection )
438cdf0e10cSrcweir {
439cdf0e10cSrcweir 	CallConnectionOpened( pNewConnection );
440cdf0e10cSrcweir }
441cdf0e10cSrcweir 
442cdf0e10cSrcweir 
443cdf0e10cSrcweir CommunicationManagerServerAcceptThread::CommunicationManagerServerAcceptThread( CommunicationManagerServerViaSocket* pServer, sal_uLong nPort, sal_uInt16 nMaxCon )
444cdf0e10cSrcweir : pMyServer( pServer )
445cdf0e10cSrcweir , pAcceptorSocket( NULL )
446cdf0e10cSrcweir , nPortToListen( nPort )
447cdf0e10cSrcweir , nMaxConnections( nMaxCon )
448cdf0e10cSrcweir , nAddConnectionEventId( 0 )
449cdf0e10cSrcweir , xmNewConnection( NULL )
450cdf0e10cSrcweir {
451cdf0e10cSrcweir     if ( !pMPostUserEvent )
452cdf0e10cSrcweir         pMPostUserEvent = new vos::OMutex;
453cdf0e10cSrcweir 	create();
454cdf0e10cSrcweir }
455cdf0e10cSrcweir 
456cdf0e10cSrcweir 
457cdf0e10cSrcweir CommunicationManagerServerAcceptThread::~CommunicationManagerServerAcceptThread()
458cdf0e10cSrcweir {
459cdf0e10cSrcweir #ifndef aUNX		// Weil das Accept nicht abgebrochen werden kann, so terminiert wenigstens das Prog
460cdf0e10cSrcweir 	// #62855# pl: gilt auch bei anderen Unixen
461cdf0e10cSrcweir 	// die richtige Loesung waere natuerlich, etwas auf die pipe zu schreiben,
462cdf0e10cSrcweir 	// was der thread als Abbruchbedingung erkennt
463cdf0e10cSrcweir 	// oder wenigstens ein kill anstatt join
464cdf0e10cSrcweir 	terminate();
465cdf0e10cSrcweir 	if ( pAcceptorSocket )
466cdf0e10cSrcweir 		pAcceptorSocket->close();	// Dann das Accept unterbrechen
467cdf0e10cSrcweir 
468cdf0e10cSrcweir 	join();		// Warten bis fertig
469cdf0e10cSrcweir 
470cdf0e10cSrcweir 	if ( pAcceptorSocket )
471cdf0e10cSrcweir 	{
472cdf0e10cSrcweir 		delete pAcceptorSocket;
473cdf0e10cSrcweir 		pAcceptorSocket = NULL;
474cdf0e10cSrcweir 	}
475cdf0e10cSrcweir #else
476cdf0e10cSrcweir 	DEBUGPRINTF ("Destructor CommunicationManagerServerAcceptThread �bersprungen!!!! (wegen Solaris BUG)\n");
477cdf0e10cSrcweir #endif
478cdf0e10cSrcweir 	{
479cdf0e10cSrcweir 		vos::OGuard aGuard( aMAddConnection );
480cdf0e10cSrcweir 		if ( nAddConnectionEventId )
481cdf0e10cSrcweir 		{
482cdf0e10cSrcweir 			GetpApp()->RemoveUserEvent( nAddConnectionEventId );
483cdf0e10cSrcweir 			nAddConnectionEventId = 0;
484cdf0e10cSrcweir 			CommunicationLinkRef xNewConnection = GetNewConnection();
485cdf0e10cSrcweir 			INFO_MSG( CByteString("Event gel�scht"),
486cdf0e10cSrcweir 				CByteString( "AddConnectionEvent aus Queue gel�scht"),
487cdf0e10cSrcweir 				CM_MISC, xNewConnection );
488cdf0e10cSrcweir 			xNewConnection->InvalidateManager();
489cdf0e10cSrcweir 			xNewConnection.Clear();	// sollte das Objekt hier l�schen
490cdf0e10cSrcweir 		}
491cdf0e10cSrcweir 	}
492cdf0e10cSrcweir }
493cdf0e10cSrcweir 
494cdf0e10cSrcweir void CommunicationManagerServerAcceptThread::run()
495cdf0e10cSrcweir {
496cdf0e10cSrcweir 	if ( !nPortToListen )
497cdf0e10cSrcweir 		return;
498cdf0e10cSrcweir 
499cdf0e10cSrcweir 	pAcceptorSocket = new vos::OAcceptorSocket();
500cdf0e10cSrcweir 	vos::OInetSocketAddr Addr;
501cdf0e10cSrcweir 	Addr.setPort( nPortToListen );
502cdf0e10cSrcweir 	pAcceptorSocket->setReuseAddr( 1 );
503cdf0e10cSrcweir 	if ( !pAcceptorSocket->bind( Addr ) )
504cdf0e10cSrcweir 	{
505cdf0e10cSrcweir 		return;
506cdf0e10cSrcweir 	}
507cdf0e10cSrcweir 	if ( !pAcceptorSocket->listen( nMaxConnections ) )
508cdf0e10cSrcweir 	{
509cdf0e10cSrcweir 		return;
510cdf0e10cSrcweir 	}
511cdf0e10cSrcweir 
512cdf0e10cSrcweir 
513cdf0e10cSrcweir 	vos::OStreamSocket *pStreamSocket = NULL;
514cdf0e10cSrcweir 
515cdf0e10cSrcweir 	while ( schedule() )
516cdf0e10cSrcweir 	{
517cdf0e10cSrcweir 		pStreamSocket = new vos::OStreamSocket;
518cdf0e10cSrcweir 		switch ( pAcceptorSocket->acceptConnection( *pStreamSocket ) )
519cdf0e10cSrcweir 		{
520cdf0e10cSrcweir 		case vos::ISocketTypes::TResult_Ok:
521cdf0e10cSrcweir 			{
522cdf0e10cSrcweir 				pStreamSocket->setTcpNoDelay( 1 );
523cdf0e10cSrcweir 
524cdf0e10cSrcweir 				TimeValue sNochEins = {0, 100};
525cdf0e10cSrcweir 				while ( schedule() && xmNewConnection.Is() )	// Solange die letzte Connection nicht abgeholt wurde warten wir
526cdf0e10cSrcweir 					sleep( sNochEins );
527cdf0e10cSrcweir 				xmNewConnection = new CommunicationLinkViaSocket( pMyServer, pStreamSocket );
528cdf0e10cSrcweir 				xmNewConnection->StartCallback();
529cdf0e10cSrcweir 				{
530cdf0e10cSrcweir 					vos::OGuard aGuard( aMAddConnection );
531cdf0e10cSrcweir                     vos::OGuard aGuard2( *pMPostUserEvent );
532cdf0e10cSrcweir 					nAddConnectionEventId = GetpApp()->PostUserEvent( LINK( this, CommunicationManagerServerAcceptThread, AddConnection ) );
533cdf0e10cSrcweir 				}
534cdf0e10cSrcweir 			}
535cdf0e10cSrcweir 			break;
536cdf0e10cSrcweir 		case vos::ISocketTypes::TResult_TimedOut:
537cdf0e10cSrcweir 			delete pStreamSocket;
538cdf0e10cSrcweir 			pStreamSocket = NULL;
539cdf0e10cSrcweir 			break;
540cdf0e10cSrcweir 		case vos::ISocketTypes::TResult_Error:
541cdf0e10cSrcweir 			delete pStreamSocket;
542cdf0e10cSrcweir 			pStreamSocket = NULL;
543cdf0e10cSrcweir 			break;
544cdf0e10cSrcweir 
545cdf0e10cSrcweir 		case vos::ISocketTypes::TResult_Interrupted:
546cdf0e10cSrcweir 		case vos::ISocketTypes::TResult_InProgress:
547cdf0e10cSrcweir 			break;  // -Wall not handled...
548cdf0e10cSrcweir 		}
549cdf0e10cSrcweir 	}
550cdf0e10cSrcweir }
551cdf0e10cSrcweir 
552cdf0e10cSrcweir 
553cdf0e10cSrcweir IMPL_LINK( CommunicationManagerServerAcceptThread, AddConnection, void*, EMPTYARG )
554cdf0e10cSrcweir {
555cdf0e10cSrcweir 	{
556cdf0e10cSrcweir 		vos::OGuard aGuard( aMAddConnection );
557cdf0e10cSrcweir 		nAddConnectionEventId = 0;
558cdf0e10cSrcweir 	}
559cdf0e10cSrcweir 	pMyServer->AddConnection( xmNewConnection );
560cdf0e10cSrcweir 	xmNewConnection.Clear();
561cdf0e10cSrcweir 	return 1;
562cdf0e10cSrcweir }
563cdf0e10cSrcweir 
564cdf0e10cSrcweir 
565cdf0e10cSrcweir #define GETSET(aVar, KeyName, Dafault)                 \
566cdf0e10cSrcweir 	aVar = aConf.ReadKey(KeyName,"No Entry");          \
567cdf0e10cSrcweir 	if ( aVar == "No Entry" )                          \
568cdf0e10cSrcweir 	{                                                  \
569cdf0e10cSrcweir 		aVar = Dafault;                                \
570cdf0e10cSrcweir 		aConf.WriteKey(KeyName, aVar);                 \
571cdf0e10cSrcweir 	}
572cdf0e10cSrcweir 
573cdf0e10cSrcweir 
574cdf0e10cSrcweir CommunicationManagerClientViaSocket::CommunicationManagerClientViaSocket( ByteString aHost, sal_uLong nPort, sal_Bool bUseMultiChannel )
575cdf0e10cSrcweir : CommunicationManagerClient( bUseMultiChannel )
576cdf0e10cSrcweir , aHostToTalk( aHost )
577cdf0e10cSrcweir , nPortToTalk( nPort )
578cdf0e10cSrcweir {
579cdf0e10cSrcweir }
580cdf0e10cSrcweir 
581cdf0e10cSrcweir CommunicationManagerClientViaSocket::CommunicationManagerClientViaSocket( sal_Bool bUseMultiChannel )
582cdf0e10cSrcweir : CommunicationManagerClient( bUseMultiChannel )
583cdf0e10cSrcweir , aHostToTalk( "" )
584cdf0e10cSrcweir , nPortToTalk( 0 )
585cdf0e10cSrcweir {
586cdf0e10cSrcweir }
587cdf0e10cSrcweir 
588cdf0e10cSrcweir CommunicationManagerClientViaSocket::~CommunicationManagerClientViaSocket()
589cdf0e10cSrcweir {
590cdf0e10cSrcweir }
591cdf0e10cSrcweir 
592cdf0e10cSrcweir 
593