summaryrefslogtreecommitdiff
path: root/sd/source/ui
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@suse.com>2013-02-18 11:30:54 +0000
committerMichael Meeks <michael.meeks@suse.com>2013-02-19 09:12:10 +0000
commit033a2c71fd9a35481f13fcd9c1e2d0339437baf0 (patch)
tree88f3b974f8300c998ee5ca7af36c9f690680ab97 /sd/source/ui
parentf45ea70357f3995f1316a851dde6e9ee35d57914 (diff)
sdremote: switch to a non-blocking socket, and polling glib mainloop.
Change-Id: I84c0a522fe16fbc8fc86a8e4bccb84aec0a1acd1
Diffstat (limited to 'sd/source/ui')
-rw-r--r--sd/source/ui/remotecontrol/BluetoothServer.cxx92
-rw-r--r--sd/source/ui/remotecontrol/BluetoothServer.hxx3
2 files changed, 75 insertions, 20 deletions
diff --git a/sd/source/ui/remotecontrol/BluetoothServer.cxx b/sd/source/ui/remotecontrol/BluetoothServer.cxx
index e0ca4614da15..29027a519c52 100644
--- a/sd/source/ui/remotecontrol/BluetoothServer.cxx
+++ b/sd/source/ui/remotecontrol/BluetoothServer.cxx
@@ -15,10 +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>
@@ -68,7 +73,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;
@@ -223,6 +234,13 @@ bluezCreateListeningSocket()
return -1;
}
+ // set non-blocking behaviour ...
+ if( fcntl( nSocket, F_SETFL, O_NONBLOCK) < 0 )
+ {
+ close( nSocket );
+ return -1;
+ }
+
return nSocket;
}
@@ -379,8 +397,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()
@@ -563,9 +588,8 @@ void BluetoothServer::addCommunicator( Communicator* pCommunicator )
void SAL_CALL BluetoothServer::run()
{
SAL_INFO( "sdremote.bluetooth", "BluetoothServer::run called" );
-#if (defined(LINUX) && !defined(__FreeBSD_kernel__)) && defined(ENABLE_DBUS)
- g_type_init();
+#ifdef LINUX_BLUETOOTH
DBusConnection *pConnection = dbusConnectToNameOnBus();
if( !pConnection )
return;
@@ -580,8 +604,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 ----------------
@@ -589,23 +613,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 )
{
- int err = errno;
- SAL_WARN( "sdremote.bluetooth", "accept failed with errno " << err );
- 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;
};
}