summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2012-06-22 15:27:47 +0200
committerStephan Bergmann <sbergman@redhat.com>2012-06-22 15:29:01 +0200
commit2a5fc950439d484d1227a736bea6566e86e73b7c (patch)
tree596ba68c0359513be251b5477092e0e875bad566
parent4cffdb68196d6c23e5134a57018648af5d1f4111 (diff)
Some further clean-up of X Session Management code
Change-Id: I0cc47b152835d69e90226f42609eabe5291f55f3
-rw-r--r--vcl/inc/unx/sm.hxx12
-rw-r--r--vcl/unx/generic/app/sm.cxx472
2 files changed, 247 insertions, 237 deletions
diff --git a/vcl/inc/unx/sm.hxx b/vcl/inc/unx/sm.hxx
index 13291d1f305d..d2c56ce047b3 100644
--- a/vcl/inc/unx/sm.hxx
+++ b/vcl/inc/unx/sm.hxx
@@ -32,21 +32,25 @@
32 32
33#include <X11/SM/SMlib.h> 33#include <X11/SM/SMlib.h>
34 34
35#include "boost/scoped_ptr.hpp"
35#include "tools/link.hxx" 36#include "tools/link.hxx"
37
36#include "vclpluginapi.h" 38#include "vclpluginapi.h"
37 39
38namespace rtl { 40namespace rtl {
39 class OString; 41 class OString;
40 class OUString; 42 class OUString;
41} 43}
44class ICEConnectionObserver;
42class SalSession; 45class SalSession;
43 46
44class SessionManagerClient 47class SessionManagerClient
45{ 48{
46 static SalSession * m_pSession; 49 static SalSession * m_pSession;
47 static SmcConn aSmcConnection; 50 static boost::scoped_ptr< ICEConnectionObserver > m_pICEConnectionObserver;
51 static SmcConn m_pSmcConnection;
48 static rtl::OString m_aClientID; 52 static rtl::OString m_aClientID;
49 static bool bDocSaveDone; 53 static bool m_bDocSaveDone;
50 54
51 static void SaveYourselfProc( SmcConn connection, 55 static void SaveYourselfProc( SmcConn connection,
52 SmPointer client_data, 56 SmPointer client_data,
@@ -63,7 +67,7 @@ class SessionManagerClient
63 static void InteractProc( SmcConn connection, 67 static void InteractProc( SmcConn connection,
64 SmPointer clientData ); 68 SmPointer clientData );
65 69
66 static const rtl::OString& getPreviousSessionID(); 70 static rtl::OString getPreviousSessionID();
67 71
68 DECL_STATIC_LINK( SessionManagerClient, ShutDownHdl, void* ); 72 DECL_STATIC_LINK( SessionManagerClient, ShutDownHdl, void* );
69 DECL_STATIC_LINK( SessionManagerClient, ShutDownCancelHdl, void* ); 73 DECL_STATIC_LINK( SessionManagerClient, ShutDownCancelHdl, void* );
@@ -79,7 +83,7 @@ public:
79 static void interactionDone( bool bCancelShutdown ); 83 static void interactionDone( bool bCancelShutdown );
80 84
81 static rtl::OUString getExecName(); 85 static rtl::OUString getExecName();
82 static VCLPLUG_GEN_PUBLIC const rtl::OString& getSessionID(); 86 static VCLPLUG_GEN_PUBLIC rtl::OString getSessionID();
83}; 87};
84 88
85#endif 89#endif
diff --git a/vcl/unx/generic/app/sm.cxx b/vcl/unx/generic/app/sm.cxx
index e0bbdb918ed0..0122038a40fb 100644
--- a/vcl/unx/generic/app/sm.cxx
+++ b/vcl/unx/generic/app/sm.cxx
@@ -39,7 +39,7 @@
39 39
40#include <rtl/strbuf.hxx> 40#include <rtl/strbuf.hxx>
41 41
42#include <osl/process.h> 42#include <rtl/process.h>
43#include <osl/security.h> 43#include <osl/security.h>
44#include <osl/conditn.h> 44#include <osl/conditn.h>
45 45
@@ -108,58 +108,60 @@ bool IceSalSession::cancelShutdown()
108 return false; 108 return false;
109} 109}
110 110
111extern "C" void SAL_CALL ICEConnectionWorker( void* ); 111extern "C" void ICEWatchProc(
112 IceConn ice_conn, IcePointer client_data, Bool opening,
113 IcePointer * watch_data);
114
115extern "C" void SAL_CALL ICEConnectionWorker(void * data);
112 116
113class ICEConnectionObserver 117class ICEConnectionObserver
114{ 118{
115 friend void SAL_CALL ICEConnectionWorker(void*); 119 friend void ICEWatchProc(IceConn, IcePointer, Bool, IcePointer *);
116 static sal_Bool bIsWatching; 120
117 static void ICEWatchProc( IceConn connection, IcePointer client_data, 121 friend void ICEConnectionWorker(void *);
118 Bool opening, IcePointer* watch_data ); 122
119 123 struct pollfd* m_pFilehandles;
120 static struct pollfd* pFilehandles; 124 int m_nConnections;
121 static IceConn* pConnections; 125 IceConn* m_pConnections;
122 static int nConnections; 126 int m_nWakeupFiles[2];
123 static int nWakeupFiles[2]; 127 oslThread m_ICEThread;
124 static oslMutex ICEMutex; 128 IceIOErrorHandler m_origIOErrorHandler;
125 static oslThread ICEThread; 129 IceErrorHandler m_origErrorHandler;
126 static IceIOErrorHandler origIOErrorHandler; 130
127 static IceErrorHandler origErrorHandler; 131 void wakeup();
132
128public: 133public:
134 osl::Mutex m_ICEMutex;
129 135
130 static void activate(); 136 ICEConnectionObserver():
131 static void deactivate(); 137 m_pFilehandles(NULL), m_nConnections(0), m_pConnections(NULL),
132 static void lock(); 138 m_ICEThread(NULL)
133 static void unlock(); 139 { m_nWakeupFiles[0] = m_nWakeupFiles[1] = 0; }
134 static void wakeup();
135};
136 140
141 void activate();
142 void deactivate();
143 void terminate(oslThread iceThread);
144};
137 145
138SalSession * SessionManagerClient::m_pSession = 0; 146SalSession * SessionManagerClient::m_pSession = NULL;
139SmcConn SessionManagerClient::aSmcConnection = NULL; 147boost::scoped_ptr< ICEConnectionObserver >
148SessionManagerClient::m_pICEConnectionObserver;
149SmcConn SessionManagerClient::m_pSmcConnection = NULL;
140rtl::OString SessionManagerClient::m_aClientID; 150rtl::OString SessionManagerClient::m_aClientID;
141sal_Bool ICEConnectionObserver::bIsWatching = sal_False; 151bool SessionManagerClient::m_bDocSaveDone = false; // HACK
142struct pollfd* ICEConnectionObserver::pFilehandles = NULL;
143IceConn* ICEConnectionObserver::pConnections = NULL;
144int ICEConnectionObserver::nConnections = 0;
145oslMutex ICEConnectionObserver::ICEMutex = NULL;
146oslThread ICEConnectionObserver::ICEThread = NULL;
147int ICEConnectionObserver::nWakeupFiles[2] = { 0, 0 };
148 152
149IceIOErrorHandler ICEConnectionObserver::origIOErrorHandler = NULL; 153extern "C" {
150IceErrorHandler ICEConnectionObserver::origErrorHandler = NULL;
151 154
152static void IgnoreIceErrors(IceConn, Bool, int, unsigned long, int, int, IcePointer) 155static void IgnoreIceErrors(
153{ 156 SAL_UNUSED_PARAMETER IceConn, SAL_UNUSED_PARAMETER Bool,
154} 157 SAL_UNUSED_PARAMETER int, SAL_UNUSED_PARAMETER unsigned long,
155 158 SAL_UNUSED_PARAMETER int, SAL_UNUSED_PARAMETER int,
156static void IgnoreIceIOErrors(IceConn) 159 SAL_UNUSED_PARAMETER IcePointer)
157{ 160{}
158}
159 161
160// HACK 162static void IgnoreIceIOErrors(SAL_UNUSED_PARAMETER IceConn) {}
161bool SessionManagerClient::bDocSaveDone = false;
162 163
164}
163 165
164static SmProp* pSmProps = NULL; 166static SmProp* pSmProps = NULL;
165static SmProp** ppSmProps = NULL; 167static SmProp** ppSmProps = NULL;
@@ -239,7 +241,7 @@ static void BuildSmPropertyList()
239 241
240bool SessionManagerClient::checkDocumentsSaved() 242bool SessionManagerClient::checkDocumentsSaved()
241{ 243{
242 return bDocSaveDone; 244 return m_bDocSaveDone;
243} 245}
244 246
245IMPL_STATIC_LINK_NOINSTANCE( SessionManagerClient, SaveYourselfHdl, void*, pStateVal ) 247IMPL_STATIC_LINK_NOINSTANCE( SessionManagerClient, SaveYourselfHdl, void*, pStateVal )
@@ -329,7 +331,7 @@ void SessionManagerClient::SaveYourselfProc(
329 " SmInteractStyleErrors: " << (interact_style == SmInteractStyleErrors) << 331 " SmInteractStyleErrors: " << (interact_style == SmInteractStyleErrors) <<
330 " SmInteractStyleErrors: " << (interact_style == SmInteractStyleAny)); 332 " SmInteractStyleErrors: " << (interact_style == SmInteractStyleAny));
331 BuildSmPropertyList(); 333 BuildSmPropertyList();
332 bDocSaveDone = false; 334 m_bDocSaveDone = false;
333 /* #i49875# some session managers send a "die" message if the 335 /* #i49875# some session managers send a "die" message if the
334 * saveDone does not come early enough for their convenience 336 * saveDone does not come early enough for their convenience
335 * this can occasionally happen on startup, especially the first 337 * this can occasionally happen on startup, especially the first
@@ -368,7 +370,7 @@ void SessionManagerClient::DieProc(
368 ) 370 )
369{ 371{
370 SAL_INFO("vcl.sm", "Session: die"); 372 SAL_INFO("vcl.sm", "Session: die");
371 if( connection == aSmcConnection ) 373 if( connection == m_pSmcConnection )
372 { 374 {
373 Application::PostUserEvent( STATIC_LINK( NULL, SessionManagerClient, ShutDownHdl ) ); 375 Application::PostUserEvent( STATIC_LINK( NULL, SessionManagerClient, ShutDownHdl ) );
374 SAL_INFO("vcl.sm", "waiting for shutdown event to be processed" ); 376 SAL_INFO("vcl.sm", "waiting for shutdown event to be processed" );
@@ -388,7 +390,7 @@ void SessionManagerClient::ShutdownCanceledProc(
388 SmPointer ) 390 SmPointer )
389{ 391{
390 SAL_INFO("vcl.sm", "Session: shutdown canceled" ); 392 SAL_INFO("vcl.sm", "Session: shutdown canceled" );
391 if( connection == aSmcConnection ) 393 if( connection == m_pSmcConnection )
392 Application::PostUserEvent( STATIC_LINK( NULL, SessionManagerClient, ShutDownCancelHdl ) ); 394 Application::PostUserEvent( STATIC_LINK( NULL, SessionManagerClient, ShutDownCancelHdl ) );
393} 395}
394 396
@@ -397,70 +399,71 @@ void SessionManagerClient::InteractProc(
397 SmPointer ) 399 SmPointer )
398{ 400{
399 SAL_INFO("vcl.sm", "Session: interaction request completed" ); 401 SAL_INFO("vcl.sm", "Session: interaction request completed" );
400 if( connection == aSmcConnection ) 402 if( connection == m_pSmcConnection )
401 Application::PostUserEvent( STATIC_LINK( NULL, SessionManagerClient, InteractionHdl ) ); 403 Application::PostUserEvent( STATIC_LINK( NULL, SessionManagerClient, InteractionHdl ) );
402} 404}
403 405
404void SessionManagerClient::saveDone() 406void SessionManagerClient::saveDone()
405{ 407{
406 if( aSmcConnection ) 408 if( m_pSmcConnection )
407 { 409 {
408 ICEConnectionObserver::lock(); 410 assert(m_pICEConnectionObserver);
409 SmcSetProperties( aSmcConnection, nSmProps, ppSmProps ); 411 osl::MutexGuard g(m_pICEConnectionObserver->m_ICEMutex);
410 SmcSaveYourselfDone( aSmcConnection, True ); 412 SmcSetProperties( m_pSmcConnection, nSmProps, ppSmProps );
413 SmcSaveYourselfDone( m_pSmcConnection, True );
411 SAL_INFO("vcl.sm", "sent SaveYourselfDone SmRestartHint of " << *pSmRestartHint ); 414 SAL_INFO("vcl.sm", "sent SaveYourselfDone SmRestartHint of " << *pSmRestartHint );
412 bDocSaveDone = true; 415 m_bDocSaveDone = true;
413 ICEConnectionObserver::unlock();
414 } 416 }
415} 417}
416 418
417 419
418void SessionManagerClient::open(SalSession * pSession) 420void SessionManagerClient::open(SalSession * pSession)
419{ 421{
420 assert(!m_pSession); 422 assert(!m_pSession && !m_pICEConnectionObserver && !m_pSmcConnection);
423 // must only be called once
421 m_pSession = pSession; 424 m_pSession = pSession;
422 425 // This is the way Xt does it, so we can too:
423 static SmcCallbacks aCallbacks; 426 if( getenv( "SESSION_MANAGER" ) )
424
425 // this is the way Xt does it, so we can too
426 if( ! aSmcConnection && getenv( "SESSION_MANAGER" ) )
427 { 427 {
428 char aErrBuf[1024]; 428 m_pICEConnectionObserver.reset(new ICEConnectionObserver);
429 ICEConnectionObserver::activate(); 429 m_pICEConnectionObserver->activate();
430 ICEConnectionObserver::lock(); 430
431 431 {
432 char* pClientID = NULL; 432 osl::MutexGuard g(m_pICEConnectionObserver->m_ICEMutex);
433 const rtl::OString& rPrevId(getPreviousSessionID()); 433
434 434 static SmcCallbacks aCallbacks; // does this need to be static?
435 aCallbacks.save_yourself.callback = SaveYourselfProc; 435 aCallbacks.save_yourself.callback = SaveYourselfProc;
436 aCallbacks.save_yourself.client_data = NULL; 436 aCallbacks.save_yourself.client_data = NULL;
437 aCallbacks.die.callback = DieProc; 437 aCallbacks.die.callback = DieProc;
438 aCallbacks.die.client_data = NULL; 438 aCallbacks.die.client_data = NULL;
439 aCallbacks.save_complete.callback = SaveCompleteProc; 439 aCallbacks.save_complete.callback = SaveCompleteProc;
440 aCallbacks.save_complete.client_data = NULL; 440 aCallbacks.save_complete.client_data = NULL;
441 aCallbacks.shutdown_cancelled.callback = ShutdownCanceledProc; 441 aCallbacks.shutdown_cancelled.callback = ShutdownCanceledProc;
442 aCallbacks.shutdown_cancelled.client_data = NULL; 442 aCallbacks.shutdown_cancelled.client_data = NULL;
443 aSmcConnection = SmcOpenConnection( NULL, 443 rtl::OString aPrevId(getPreviousSessionID());
444 NULL, 444 char* pClientID = NULL;
445 SmProtoMajor, 445 char aErrBuf[1024];
446 SmProtoMinor, 446 m_pSmcConnection = SmcOpenConnection( NULL,
447 SmcSaveYourselfProcMask | 447 NULL,
448 SmcDieProcMask | 448 SmProtoMajor,
449 SmcSaveCompleteProcMask | 449 SmProtoMinor,
450 SmcShutdownCancelledProcMask , 450 SmcSaveYourselfProcMask |
451 &aCallbacks, 451 SmcDieProcMask |
452 rPrevId.isEmpty() ? NULL : const_cast<char*>(rPrevId.getStr()), 452 SmcSaveCompleteProcMask |
453 &pClientID, 453 SmcShutdownCancelledProcMask ,
454 sizeof( aErrBuf ), 454 &aCallbacks,
455 aErrBuf ); 455 aPrevId.isEmpty() ? NULL : const_cast<char*>(aPrevId.getStr()),
456 if( ! aSmcConnection ) 456 &pClientID,
457 SAL_INFO("vcl.sm", "SmcOpenConnection failed: " << aErrBuf); 457 sizeof( aErrBuf ),
458 else 458 aErrBuf );
459 SAL_INFO("vcl.sm", "SmcOpenConnection succeeded, client ID is " << pClientID ); 459 if( !m_pSmcConnection )
460 m_aClientID = rtl::OString(pClientID); 460 SAL_INFO("vcl.sm", "SmcOpenConnection failed: " << aErrBuf);
461 free( pClientID ); 461 else
462 pClientID = NULL; 462 SAL_INFO("vcl.sm", "SmcOpenConnection succeeded, client ID is " << pClientID );
463 ICEConnectionObserver::unlock(); 463 m_aClientID = rtl::OString(pClientID);
464 free( pClientID );
465 pClientID = NULL;
466 }
464 467
465 SalDisplay* pDisp = GetGenericData()->GetSalDisplay(); 468 SalDisplay* pDisp = GetGenericData()->GetSalDisplay();
466 if( pDisp->GetDrawable(pDisp->GetDefaultXScreen()) && !m_aClientID.isEmpty() ) 469 if( pDisp->GetDrawable(pDisp->GetDefaultXScreen()) && !m_aClientID.isEmpty() )
@@ -476,49 +479,54 @@ void SessionManagerClient::open(SalSession * pSession)
476 ); 479 );
477 } 480 }
478 } 481 }
479 else if( ! aSmcConnection ) 482 else
483 {
480 SAL_INFO("vcl.sm", "no SESSION_MANAGER"); 484 SAL_INFO("vcl.sm", "no SESSION_MANAGER");
485 }
481} 486}
482 487
483const rtl::OString& SessionManagerClient::getSessionID() 488rtl::OString SessionManagerClient::getSessionID()
484{ 489{
485 return m_aClientID; 490 return m_aClientID;
486} 491}
487 492
488void SessionManagerClient::close() 493void SessionManagerClient::close()
489{ 494{
490 if( aSmcConnection ) 495 if( m_pSmcConnection )
491 { 496 {
492 ICEConnectionObserver::lock(); 497 assert(m_pICEConnectionObserver);
493 SAL_INFO("vcl.sm", "attempting SmcCloseConnection"); 498 {
494 SmcCloseConnection( aSmcConnection, 0, NULL ); 499 osl::MutexGuard g(m_pICEConnectionObserver->m_ICEMutex);
495 SAL_INFO("vcl.sm", "SmcConnection closed"); 500 SAL_INFO("vcl.sm", "attempting SmcCloseConnection");
496 ICEConnectionObserver::unlock(); 501 SmcCloseConnection( m_pSmcConnection, 0, NULL );
497 ICEConnectionObserver::deactivate(); 502 SAL_INFO("vcl.sm", "SmcConnection closed");
498 aSmcConnection = NULL; 503 }
504 m_pICEConnectionObserver->deactivate();
505 m_pICEConnectionObserver.reset();
506 m_pSmcConnection = NULL;
499 } 507 }
500} 508}
501 509
502bool SessionManagerClient::queryInteraction() 510bool SessionManagerClient::queryInteraction()
503{ 511{
504 bool bRet = false; 512 bool bRet = false;
505 if( aSmcConnection ) 513 if( m_pSmcConnection )
506 { 514 {
507 ICEConnectionObserver::lock(); 515 assert(m_pICEConnectionObserver);
508 if( SmcInteractRequest( aSmcConnection, SmDialogNormal, InteractProc, NULL ) ) 516 osl::MutexGuard g(m_pICEConnectionObserver->m_ICEMutex);
517 if( SmcInteractRequest( m_pSmcConnection, SmDialogNormal, InteractProc, NULL ) )
509 bRet = true; 518 bRet = true;
510 ICEConnectionObserver::unlock();
511 } 519 }
512 return bRet; 520 return bRet;
513} 521}
514 522
515void SessionManagerClient::interactionDone( bool bCancelShutdown ) 523void SessionManagerClient::interactionDone( bool bCancelShutdown )
516{ 524{
517 if( aSmcConnection ) 525 if( m_pSmcConnection )
518 { 526 {
519 ICEConnectionObserver::lock(); 527 assert(m_pICEConnectionObserver);
520 SmcInteractDone( aSmcConnection, bCancelShutdown ? True : False ); 528 osl::MutexGuard g(m_pICEConnectionObserver->m_ICEMutex);
521 ICEConnectionObserver::unlock(); 529 SmcInteractDone( m_pSmcConnection, bCancelShutdown ? True : False );
522 } 530 }
523} 531}
524 532
@@ -535,16 +543,16 @@ rtl::OUString SessionManagerClient::getExecName()
535} 543}
536 544
537 545
538const rtl::OString& SessionManagerClient::getPreviousSessionID() 546rtl::OString SessionManagerClient::getPreviousSessionID()
539{ 547{
540 static rtl::OString aPrevId; 548 rtl::OString aPrevId;
541 549
542 int nCommands = osl_getCommandArgCount(); 550 sal_uInt32 n = rtl_getAppCommandArgCount();
543 for (int i = 0; i < nCommands; ++i) 551 for (sal_uInt32 i = 0; i != n; ++i)
544 { 552 {
545 ::rtl::OUString aArg; 553 ::rtl::OUString aArg;
546 osl_getCommandArg( i, &aArg.pData ); 554 rtl_getAppCommandArg( i, &aArg.pData );
547 if(aArg.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("--session="))) 555 if(aArg.match("--session="))
548 { 556 {
549 aPrevId = rtl::OUStringToOString( 557 aPrevId = rtl::OUStringToOString(
550 aArg.copy(RTL_CONSTASCII_LENGTH("--session=")), 558 aArg.copy(RTL_CONSTASCII_LENGTH("--session=")),
@@ -557,78 +565,80 @@ const rtl::OString& SessionManagerClient::getPreviousSessionID()
557 return aPrevId; 565 return aPrevId;
558} 566}
559 567
560void ICEConnectionObserver::lock()
561{
562 osl_acquireMutex( ICEMutex );
563}
564
565void ICEConnectionObserver::unlock()
566{
567 osl_releaseMutex( ICEMutex );
568}
569
570void ICEConnectionObserver::activate() 568void ICEConnectionObserver::activate()
571{ 569{
572 if( ! bIsWatching ) 570 /*
573 { 571 * Default handlers call exit, we don't care that strongly if something
574 nWakeupFiles[0] = nWakeupFiles[1] = 0; 572 * happens to fail
575 ICEMutex = osl_createMutex(); 573 */
576 bIsWatching = sal_True; 574 m_origIOErrorHandler = IceSetIOErrorHandler( IgnoreIceIOErrors );
577 /* 575 m_origErrorHandler = IceSetErrorHandler( IgnoreIceErrors );
578 * Default handlers call exit, we don't care that strongly if something 576 IceAddConnectionWatch( ICEWatchProc, this );
579 * happens to fail
580 */
581 origIOErrorHandler = IceSetIOErrorHandler( IgnoreIceIOErrors );
582 origErrorHandler = IceSetErrorHandler( IgnoreIceErrors );
583 IceAddConnectionWatch( ICEWatchProc, NULL );
584 }
585} 577}
586 578
587void ICEConnectionObserver::deactivate() 579void ICEConnectionObserver::deactivate()
588{ 580{
589 if( bIsWatching ) 581 oslThread t;
590 { 582 {
591 lock(); 583 osl::MutexGuard g(m_ICEMutex);
592 bIsWatching = sal_False; 584 IceRemoveConnectionWatch( ICEWatchProc, this );
593 IceRemoveConnectionWatch( ICEWatchProc, NULL ); 585 IceSetErrorHandler( m_origErrorHandler );
594 IceSetErrorHandler( origErrorHandler ); 586 IceSetIOErrorHandler( m_origIOErrorHandler );
595 IceSetIOErrorHandler( origIOErrorHandler ); 587 m_nConnections = 0;
596 nConnections = 0; 588 t = m_ICEThread;
597 if( ICEThread ) 589 m_ICEThread = NULL;
598 { 590 }
599 osl_terminateThread( ICEThread ); 591 if (t)
600 wakeup(); 592 {
601 } 593 terminate(t);
602 unlock();
603 if( ICEThread )
604 {
605 osl_joinWithThread( ICEThread );
606 osl_destroyThread( ICEThread );
607 close( nWakeupFiles[1] );
608 close( nWakeupFiles[0] );
609 ICEThread = NULL;
610 }
611 osl_destroyMutex( ICEMutex );
612 ICEMutex = NULL;
613 } 594 }
614} 595}
615 596
616void ICEConnectionObserver::wakeup() 597void ICEConnectionObserver::wakeup()
617{ 598{
618 char cChar = 'w'; 599 char cChar = 'w';
619 OSL_VERIFY(write( nWakeupFiles[1], &cChar, 1 ) == 1); 600 OSL_VERIFY(write(m_nWakeupFiles[1], &cChar, 1) == 1);
601}
602
603void ICEConnectionObserver::terminate(oslThread iceThread)
604{
605 osl_terminateThread(iceThread);
606 wakeup();
607 osl_joinWithThread(iceThread);
608 osl_destroyThread(iceThread);
609 close(m_nWakeupFiles[1]);
610 close(m_nWakeupFiles[0]);
620} 611}
621 612
622void ICEConnectionWorker( void* ) 613void ICEConnectionWorker(void * data)
623{ 614{
624 while( osl_scheduleThread(ICEConnectionObserver::ICEThread) && ICEConnectionObserver::nConnections ) 615 ICEConnectionObserver * pThis = static_cast< ICEConnectionObserver * >(
616 data);
617 for (;;)
625 { 618 {
626 ICEConnectionObserver::lock(); 619 oslThread t;
627 int nConnectionsBefore = ICEConnectionObserver::nConnections; 620 {
628 int nBytes = sizeof( struct pollfd )*(nConnectionsBefore+1); 621 osl::MutexGuard g(pThis->m_ICEMutex);
629 struct pollfd* pLocalFD = (struct pollfd*)rtl_allocateMemory( nBytes ); 622 if (pThis->m_ICEThread == NULL || pThis->m_nConnections == 0)
630 rtl_copyMemory( pLocalFD, ICEConnectionObserver::pFilehandles, nBytes ); 623 {
631 ICEConnectionObserver::unlock(); 624 break;
625 }
626 t = pThis->m_ICEThread;
627 }
628 if (!osl_scheduleThread(t))
629 {
630 break;
631 }
632
633 int nConnectionsBefore;
634 struct pollfd* pLocalFD;
635 {
636 osl::MutexGuard g(pThis->m_ICEMutex);
637 nConnectionsBefore = pThis->m_nConnections;
638 int nBytes = sizeof( struct pollfd )*(nConnectionsBefore+1);
639 pLocalFD = (struct pollfd*)rtl_allocateMemory( nBytes );
640 rtl_copyMemory( pLocalFD, pThis->m_pFilehandles, nBytes );
641 }
632 642
633 int nRet = poll( pLocalFD,nConnectionsBefore+1,-1 ); 643 int nRet = poll( pLocalFD,nConnectionsBefore+1,-1 );
634 bool bWakeup = (pLocalFD[0].revents & POLLIN); 644 bool bWakeup = (pLocalFD[0].revents & POLLIN);
@@ -641,7 +651,7 @@ void ICEConnectionWorker( void* )
641 if( bWakeup ) 651 if( bWakeup )
642 { 652 {
643 char buf[4]; 653 char buf[4];
644 while( read( ICEConnectionObserver::nWakeupFiles[0], buf, sizeof( buf ) ) > 0 ) 654 while( read( pThis->m_nWakeupFiles[0], buf, sizeof( buf ) ) > 0 )
645 ; 655 ;
646 SAL_INFO("vcl.sm", "file handles active in wakeup: " << nRet); 656 SAL_INFO("vcl.sm", "file handles active in wakeup: " << nRet);
647 if( nRet == 1 ) 657 if( nRet == 1 )
@@ -649,113 +659,109 @@ void ICEConnectionWorker( void* )
649 } 659 }
650 660
651 // check fd's after we obtained the lock 661 // check fd's after we obtained the lock
652 ICEConnectionObserver::lock(); 662 osl::MutexGuard g(pThis->m_ICEMutex);
653 if( ICEConnectionObserver::nConnections > 0 && ICEConnectionObserver::nConnections == nConnectionsBefore ) 663 if( pThis->m_nConnections > 0 && pThis->m_nConnections == nConnectionsBefore )
654 { 664 {
655 nRet = poll( ICEConnectionObserver::pFilehandles+1, ICEConnectionObserver::nConnections, 0 ); 665 nRet = poll( pThis->m_pFilehandles+1, pThis->m_nConnections, 0 );
656 if( nRet > 0 ) 666 if( nRet > 0 )
657 { 667 {
658 SAL_INFO("vcl.sm", "IceProcessMessages"); 668 SAL_INFO("vcl.sm", "IceProcessMessages");
659 Bool bReply; 669 Bool bReply;
660 for( int i = 0; i < ICEConnectionObserver::nConnections; i++ ) 670 for( int i = 0; i < pThis->m_nConnections; i++ )
661 if( ICEConnectionObserver::pFilehandles[i+1].revents & POLLIN ) 671 if( pThis->m_pFilehandles[i+1].revents & POLLIN )
662 IceProcessMessages( ICEConnectionObserver::pConnections[i], NULL, &bReply ); 672 IceProcessMessages( pThis->m_pConnections[i], NULL, &bReply );
663 } 673 }
664 } 674 }
665 ICEConnectionObserver::unlock();
666 } 675 }
667 SAL_INFO("vcl.sm", "shutting donw ICE dispatch thread"); 676 SAL_INFO("vcl.sm", "shutting down ICE dispatch thread");
668} 677}
669 678
670void ICEConnectionObserver::ICEWatchProc( 679void ICEWatchProc(
671 IceConn connection, 680 IceConn ice_conn, IcePointer client_data, Bool opening,
672 IcePointer, 681 SAL_UNUSED_PARAMETER IcePointer *)
673 Bool opening,
674 IcePointer*
675 )
676{ 682{
677 // note: this is a callback function for ICE 683 // Note: This is a callback function for ICE; this implicitly means that a
678 // this implicitly means that a call into ICE lib is calling this 684 // call into ICE lib is calling this, so the m_ICEMutex MUST already be
679 // so the ICEMutex MUST already be locked by the caller 685 // locked by the caller.
680 686 ICEConnectionObserver * pThis = static_cast< ICEConnectionObserver * >(
687 client_data);
681 if( opening ) 688 if( opening )
682 { 689 {
683 int fd = IceConnectionNumber( connection ); 690 int fd = IceConnectionNumber( ice_conn );
684 nConnections++; 691 pThis->m_nConnections++;
685 pConnections = (IceConn*)rtl_reallocateMemory( pConnections, sizeof( IceConn )*nConnections ); 692 pThis->m_pConnections = (IceConn*)rtl_reallocateMemory( pThis->m_pConnections, sizeof( IceConn )*pThis->m_nConnections );
686 pFilehandles = (struct pollfd*)rtl_reallocateMemory( pFilehandles, sizeof( struct pollfd )*(nConnections+1) ); 693 pThis->m_pFilehandles = (struct pollfd*)rtl_reallocateMemory( pThis->m_pFilehandles, sizeof( struct pollfd )*(pThis->m_nConnections+1) );
687 pConnections[ nConnections-1 ] = connection; 694 pThis->m_pConnections[ pThis->m_nConnections-1 ] = ice_conn;
688 pFilehandles[ nConnections ].fd = fd; 695 pThis->m_pFilehandles[ pThis->m_nConnections ].fd = fd;
689 pFilehandles[ nConnections ].events = POLLIN; 696 pThis->m_pFilehandles[ pThis->m_nConnections ].events = POLLIN;
690 if( nConnections == 1 ) 697 if( pThis->m_nConnections == 1 )
691 { 698 {
692 if( ! pipe( nWakeupFiles ) ) 699 if (!pipe(pThis->m_nWakeupFiles))
693 { 700 {
694 int flags; 701 int flags;
695 pFilehandles[0].fd = nWakeupFiles[0]; 702 pThis->m_pFilehandles[0].fd = pThis->m_nWakeupFiles[0];
696 pFilehandles[0].events = POLLIN; 703 pThis->m_pFilehandles[0].events = POLLIN;
697 // set close-on-exec and nonblock descriptor flag. 704 // set close-on-exec and nonblock descriptor flag.
698 if ((flags = fcntl (nWakeupFiles[0], F_GETFD)) != -1) 705 if ((flags = fcntl(pThis->m_nWakeupFiles[0], F_GETFD)) != -1)
699 { 706 {
700 flags |= FD_CLOEXEC; 707 flags |= FD_CLOEXEC;
701 fcntl (nWakeupFiles[0], F_SETFD, flags); 708 fcntl(pThis->m_nWakeupFiles[0], F_SETFD, flags);
702 } 709 }
703 if ((flags = fcntl (nWakeupFiles[0], F_GETFL)) != -1) 710 if ((flags = fcntl(pThis->m_nWakeupFiles[0], F_GETFL)) != -1)
704 { 711 {
705 flags |= O_NONBLOCK; 712 flags |= O_NONBLOCK;
706 fcntl (nWakeupFiles[0], F_SETFL, flags); 713 fcntl(pThis->m_nWakeupFiles[0], F_SETFL, flags);
707 } 714 }
708 // set close-on-exec and nonblock descriptor flag. 715 // set close-on-exec and nonblock descriptor flag.
709 if ((flags = fcntl (nWakeupFiles[1], F_GETFD)) != -1) 716 if ((flags = fcntl(pThis->m_nWakeupFiles[1], F_GETFD)) != -1)
710 { 717 {
711 flags |= FD_CLOEXEC; 718 flags |= FD_CLOEXEC;
712 fcntl (nWakeupFiles[1], F_SETFD, flags); 719 fcntl(pThis->m_nWakeupFiles[1], F_SETFD, flags);
713 } 720 }
714 if ((flags = fcntl (nWakeupFiles[1], F_GETFL)) != -1) 721 if ((flags = fcntl(pThis->m_nWakeupFiles[1], F_GETFL)) != -1)
715 { 722 {
716 flags |= O_NONBLOCK; 723 flags |= O_NONBLOCK;
717 fcntl (nWakeupFiles[1], F_SETFL, flags); 724 fcntl(pThis->m_nWakeupFiles[1], F_SETFL, flags);
718 } 725 }
719 ICEThread = osl_createSuspendedThread( ICEConnectionWorker, NULL ); 726 pThis->m_ICEThread = osl_createThread(
720 osl_resumeThread( ICEThread ); 727 ICEConnectionWorker, pThis);
721 } 728 }
722 } 729 }
723 } 730 }
724 else 731 else // closing
725 { 732 {
726 for( int i = 0; i < nConnections; i++ ) 733 for( int i = 0; i < pThis->m_nConnections; i++ )
727 { 734 {
728 if( pConnections[i] == connection ) 735 if( pThis->m_pConnections[i] == ice_conn )
729 { 736 {
730 if( i < nConnections-1 ) 737 if( i < pThis->m_nConnections-1 )
731 { 738 {
732 rtl_moveMemory( pConnections+i, pConnections+i+1, sizeof( IceConn )*(nConnections-i-1) ); 739 rtl_moveMemory( pThis->m_pConnections+i, pThis->m_pConnections+i+1, sizeof( IceConn )*(pThis->m_nConnections-i-1) );
733 rtl_moveMemory( pFilehandles+i+1, pFilehandles+i+2, sizeof( struct pollfd )*(nConnections-i-1) ); 740 rtl_moveMemory( pThis->m_pFilehandles+i+1, pThis->m_pFilehandles+i+2, sizeof( struct pollfd )*(pThis->m_nConnections-i-1) );
734 } 741 }
735 nConnections--; 742 pThis->m_nConnections--;
736 pConnections = (IceConn*)rtl_reallocateMemory( pConnections, sizeof( IceConn )*nConnections ); 743 pThis->m_pConnections = (IceConn*)rtl_reallocateMemory( pThis->m_pConnections, sizeof( IceConn )*pThis->m_nConnections );
737 pFilehandles = (struct pollfd*)rtl_reallocateMemory( pFilehandles, sizeof( struct pollfd )*(nConnections+1) ); 744 pThis->m_pFilehandles = (struct pollfd*)rtl_reallocateMemory( pThis->m_pFilehandles, sizeof( struct pollfd )*(pThis->m_nConnections+1) );
738 break; 745 break;
739 } 746 }
740 } 747 }
741 if( nConnections == 0 && ICEThread ) 748 if( pThis->m_nConnections == 0 && pThis->m_ICEThread )
742 { 749 {
743 SAL_INFO("vcl.sm", "terminating ICEThread"); 750 SAL_INFO("vcl.sm", "terminating ICEThread");
744 osl_terminateThread( ICEThread ); 751 oslThread t = pThis->m_ICEThread;
745 wakeup(); 752 pThis->m_ICEThread = NULL;
753
746 // must release the mutex here 754 // must release the mutex here
747 osl_releaseMutex( ICEMutex ); 755 pThis->m_ICEMutex.release();
748 osl_joinWithThread( ICEThread ); 756
749 osl_destroyThread( ICEThread ); 757 pThis->terminate(t);
750 close( nWakeupFiles[1] ); 758
751 close( nWakeupFiles[0] );
752 ICEThread = NULL;
753 // acquire the mutex again, because the caller does not expect 759 // acquire the mutex again, because the caller does not expect
754 // it to be released when calling into SM 760 // it to be released when calling into SM
755 osl_acquireMutex( ICEMutex ); 761 pThis->m_ICEMutex.acquire();
756 } 762 }
757 } 763 }
758 SAL_INFO( "vcl.sm", "ICE connection on " << IceConnectionNumber( connection ) << " " << (opening ? "inserted" : "removed")); 764 SAL_INFO( "vcl.sm", "ICE connection on " << IceConnectionNumber( ice_conn ) << " " << (opening ? "inserted" : "removed"));
759 SAL_INFO( "vcl.sm", "Display connection is " << ConnectionNumber( GetGenericData()->GetSalDisplay()->GetDisplay() ) ); 765 SAL_INFO( "vcl.sm", "Display connection is " << ConnectionNumber( GetGenericData()->GetSalDisplay()->GetDisplay() ) );
760} 766}
761 767