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