diff options
author | Michael Meeks <michael.meeks@suse.com> | 2013-02-18 11:30:54 +0000 |
---|---|---|
committer | Thorsten Behrens <tbehrens@suse.com> | 2013-02-19 13:00:19 +0100 |
commit | 7848b97462a088521986ba200ee2fd55982667bb (patch) | |
tree | 64fd42b9f275560c808a0935c1833c8464e8cd44 /sd | |
parent | 84f1c87936fa13ea937cd02ec79a3b29ed26c5d1 (diff) |
sdremote: switch to a non-blocking socket, and polling glib mainloop.
Conflicts:
sd/source/ui/remotecontrol/BluetoothServer.cxx
Change-Id: I84c0a522fe16fbc8fc86a8e4bccb84aec0a1acd1
(cherry picked from commit 0d89d814055d5c267a2cc57e302a23e9f0b521e3)
Signed-off-by: Thorsten Behrens <tbehrens@suse.com>
Diffstat (limited to 'sd')
-rw-r--r-- | sd/source/ui/remotecontrol/BluetoothServer.cxx | 94 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/BluetoothServer.hxx | 3 |
2 files changed, 77 insertions, 20 deletions
diff --git a/sd/source/ui/remotecontrol/BluetoothServer.cxx b/sd/source/ui/remotecontrol/BluetoothServer.cxx index 2ccfc8738195..5229e9d56723 100644 --- a/sd/source/ui/remotecontrol/BluetoothServer.cxx +++ b/sd/source/ui/remotecontrol/BluetoothServer.cxx @@ -15,9 +15,15 @@ #include <sal/log.hxx> #if (defined(LINUX) && !defined(__FreeBSD_kernel__)) && defined(ENABLE_DBUS) +# define LINUX_BLUETOOTH +#endif + +#ifdef LINUX_BLUETOOTH #include <glib.h> #include <dbus/dbus.h> #include <dbus/dbus-glib.h> + #include <errno.h> + #include <fcntl.h> #include <sys/unistd.h> #include <sys/socket.h> #include <bluetooth/bluetooth.h> @@ -75,7 +81,13 @@ using namespace sd; -#if (defined(LINUX) && !defined(__FreeBSD_kernel__)) && defined(ENABLE_DBUS) +#ifdef LINUX_BLUETOOTH + +struct sd::BluetoothServerImpl { + // the glib mainloop running in the thread + GMainContext *mpContext; + volatile bool mbExitMainloop; +}; struct DBusObject { OString maBusName; @@ -230,6 +242,13 @@ bluezCreateListeningSocket() return -1; } + // set non-blocking behaviour ... + if( fcntl( nSocket, F_SETFL, O_NONBLOCK) < 0 ) + { + close( nSocket ); + return -1; + } + return nSocket; } @@ -386,8 +405,15 @@ void incomingCallback( void *userRefCon, BluetoothServer::BluetoothServer( std::vector<Communicator*>* pCommunicators ) : meWasDiscoverable( UNKNOWN ), + mpImpl( NULL ), mpCommunicators( pCommunicators ) { +#ifdef LINUX_BLUETOOTH + g_type_init(); + mpImpl = new BluetoothServerImpl(); + mpImpl->mpContext = g_main_context_new(); + mpImpl->mbExitMainloop = false; +#endif } BluetoothServer::~BluetoothServer() @@ -569,10 +595,9 @@ void BluetoothServer::addCommunicator( Communicator* pCommunicator ) void SAL_CALL BluetoothServer::run() { - SAL_INFO( "sdremote.bluetooth", "BluetoothServer::execute called" ); -#if (defined(LINUX) && !defined(__FreeBSD_kernel__)) && defined(ENABLE_DBUS) - g_type_init(); + SAL_INFO( "sdremote.bluetooth", "BluetoothServer::run called" ); +#ifdef LINUX_BLUETOOTH DBusConnection *pConnection = dbusConnectToNameOnBus(); if( !pConnection ) return; @@ -587,8 +612,8 @@ void SAL_CALL BluetoothServer::run() if( !bluezRegisterServiceRecord( pConnection, pService, bluetooth_service_record ) ) return; - int aSocket = bluezCreateListeningSocket(); - if( aSocket < 0 ) + int nSocket = bluezCreateListeningSocket(); + if( nSocket < 0 ) return; // ---------------- Socket code ---------------- @@ -596,22 +621,51 @@ void SAL_CALL BluetoothServer::run() sockaddr_rc aRemoteAddr; socklen_t aRemoteAddrLen = sizeof(aRemoteAddr); - // FIXME: use a glib main-loop [!] ... - // FIXME: fixme ! ... - while ( true ) + // Avoid using GSources where we can + + // poll on our socket + GPollFD aSocketFD; + aSocketFD.fd = nSocket; + aSocketFD.events = G_IO_IN | G_IO_PRI; + g_main_context_add_poll( mpImpl->mpContext, &aSocketFD, G_PRIORITY_DEFAULT ); + + // also poll on our dbus connection + int fd = -1; + GPollFD aDBusFD; + if( dbus_connection_get_unix_fd( pConnection, &fd ) && fd >= 0 ) { - int bSocket; - SAL_INFO( "sdremote.bluetooth", "waiting on accept" ); - if ( (bSocket = accept(aSocket, (sockaddr*) &aRemoteAddr, &aRemoteAddrLen)) < 0 ) + aDBusFD.fd = fd; + aDBusFD.events = G_IO_IN | G_IO_PRI; + g_main_context_add_poll( mpImpl->mpContext, &aDBusFD, G_PRIORITY_DEFAULT ); + } + else + SAL_WARN( "sdremote.bluetooth", "failed to poll for incoming dbus signals" ); + + while( !mpImpl->mbExitMainloop ) + { + aDBusFD.revents = 0; + aSocketFD.revents = 0; + g_main_context_iteration( mpImpl->mpContext, TRUE ); + + SAL_INFO( "sdremote.bluetooth", "main-loop spin " + << aDBusFD.revents << " " << aSocketFD.revents ); + if( aDBusFD.revents ) + dbus_connection_read_write_dispatch( pConnection, 0 ); + + if( aSocketFD.revents ) { - SAL_WARN( "sdremote.bluetooth", "accept failed with error" << bSocket ); - close( aSocket ); - return; - } else { - SAL_INFO( "sdremote.bluetooth", "connection accepted" ); - Communicator* pCommunicator = new Communicator( new BufferedStreamSocket( bSocket) ); - mpCommunicators->push_back( pCommunicator ); - pCommunicator->launch(); + int nClient; + SAL_INFO( "sdremote.bluetooth", "performing accept" ); + if ( ( nClient = accept( nSocket, (sockaddr*) &aRemoteAddr, &aRemoteAddrLen)) < 0 && + errno != EAGAIN ) + { + SAL_WARN( "sdremote.bluetooth", "accept failed with errno " << errno ); + } else { + SAL_INFO( "sdremote.bluetooth", "connection accepted " << nClient ); + Communicator* pCommunicator = new Communicator( new BufferedStreamSocket( nClient ) ); + mpCommunicators->push_back( pCommunicator ); + pCommunicator->launch(); + } } } diff --git a/sd/source/ui/remotecontrol/BluetoothServer.hxx b/sd/source/ui/remotecontrol/BluetoothServer.hxx index 5b986fae210c..b922d6094901 100644 --- a/sd/source/ui/remotecontrol/BluetoothServer.hxx +++ b/sd/source/ui/remotecontrol/BluetoothServer.hxx @@ -16,6 +16,7 @@ namespace sd { class Communicator; + struct BluetoothServerImpl; class BluetoothServer: public osl::Thread { @@ -39,7 +40,9 @@ namespace sd enum { UNKNOWN, DISCOVERABLE, NOT_DISCOVERABLE } meWasDiscoverable; static BluetoothServer *spServer; + BluetoothServerImpl *mpImpl; virtual void SAL_CALL run(); + std::vector<Communicator*>* mpCommunicators; }; } |