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