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 10cdf0e10cSrcweir * 119d1279ecSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 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. 19cdf0e10cSrcweir * 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 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 { 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 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!!! 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!!! 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 255cdf0e10cSrcweir IMPL_LINK( CommunicationLinkViaSocket, PutDataReceivedHdl, CommunicationLinkViaSocket*, EMPTYARG ) 256cdf0e10cSrcweir { 257cdf0e10cSrcweir nDataReceivedEventId = GetpApp()->PostUserEvent( LINK( this, CommunicationLink, DataReceived ) ); 258cdf0e10cSrcweir return 0; 259cdf0e10cSrcweir } 260cdf0e10cSrcweir 261cdf0e10cSrcweir 262cdf0e10cSrcweir 263cdf0e10cSrcweir MultiCommunicationManager::MultiCommunicationManager( sal_Bool bUseMultiChannel ) 264cdf0e10cSrcweir : CommunicationManager( bUseMultiChannel ) 265cdf0e10cSrcweir , bGracefullShutdown( sal_True ) 266cdf0e10cSrcweir { 267cdf0e10cSrcweir ActiveLinks = new CommunicationLinkList; 268cdf0e10cSrcweir InactiveLinks = new CommunicationLinkList; 269cdf0e10cSrcweir } 270cdf0e10cSrcweir 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 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 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 346cdf0e10cSrcweir sal_uInt16 MultiCommunicationManager::GetCommunicationLinkCount() 347cdf0e10cSrcweir { 348cdf0e10cSrcweir return ActiveLinks->Count(); 349cdf0e10cSrcweir } 350cdf0e10cSrcweir 351cdf0e10cSrcweir CommunicationLinkRef MultiCommunicationManager::GetCommunicationLink( sal_uInt16 nNr ) 352cdf0e10cSrcweir { 353cdf0e10cSrcweir return ActiveLinks->GetObject( nNr ); 354cdf0e10cSrcweir } 355cdf0e10cSrcweir 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 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 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 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 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 414cdf0e10cSrcweir CommunicationManagerServerViaSocket::~CommunicationManagerServerViaSocket() 415cdf0e10cSrcweir { 416cdf0e10cSrcweir StopCommunication(); 417cdf0e10cSrcweir } 418cdf0e10cSrcweir 419cdf0e10cSrcweir sal_Bool CommunicationManagerServerViaSocket::StartCommunication() 420cdf0e10cSrcweir { 421cdf0e10cSrcweir if ( !pAcceptThread ) 422cdf0e10cSrcweir pAcceptThread = new CommunicationManagerServerAcceptThread( this, nPortToListen, nMaxConnections ); 423cdf0e10cSrcweir return sal_True; 424cdf0e10cSrcweir } 425cdf0e10cSrcweir 426cdf0e10cSrcweir 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 438cdf0e10cSrcweir void CommunicationManagerServerViaSocket::AddConnection( CommunicationLink *pNewConnection ) 439cdf0e10cSrcweir { 440cdf0e10cSrcweir CallConnectionOpened( pNewConnection ); 441cdf0e10cSrcweir } 442cdf0e10cSrcweir 443cdf0e10cSrcweir 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 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 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 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 575cdf0e10cSrcweir CommunicationManagerClientViaSocket::CommunicationManagerClientViaSocket( ByteString aHost, sal_uLong nPort, sal_Bool bUseMultiChannel ) 576cdf0e10cSrcweir : CommunicationManagerClient( bUseMultiChannel ) 577cdf0e10cSrcweir , aHostToTalk( aHost ) 578cdf0e10cSrcweir , nPortToTalk( nPort ) 579cdf0e10cSrcweir { 580cdf0e10cSrcweir } 581cdf0e10cSrcweir 582cdf0e10cSrcweir CommunicationManagerClientViaSocket::CommunicationManagerClientViaSocket( sal_Bool bUseMultiChannel ) 583cdf0e10cSrcweir : CommunicationManagerClient( bUseMultiChannel ) 584cdf0e10cSrcweir , aHostToTalk( "" ) 585cdf0e10cSrcweir , nPortToTalk( 0 ) 586cdf0e10cSrcweir { 587cdf0e10cSrcweir } 588cdf0e10cSrcweir 589cdf0e10cSrcweir CommunicationManagerClientViaSocket::~CommunicationManagerClientViaSocket() 590cdf0e10cSrcweir { 591cdf0e10cSrcweir } 592cdf0e10cSrcweir 593cdf0e10cSrcweir 594