Kaydet (Commit) 033a2c71 authored tarafından Michael Meeks's avatar Michael Meeks

sdremote: switch to a non-blocking socket, and polling glib mainloop.

Change-Id: I84c0a522fe16fbc8fc86a8e4bccb84aec0a1acd1
üst f45ea703
...@@ -15,10 +15,15 @@ ...@@ -15,10 +15,15 @@
#include <sal/log.hxx> #include <sal/log.hxx>
#if (defined(LINUX) && !defined(__FreeBSD_kernel__)) && defined(ENABLE_DBUS) #if (defined(LINUX) && !defined(__FreeBSD_kernel__)) && defined(ENABLE_DBUS)
# define LINUX_BLUETOOTH
#endif
#ifdef LINUX_BLUETOOTH
#include <glib.h> #include <glib.h>
#include <dbus/dbus.h> #include <dbus/dbus.h>
#include <dbus/dbus-glib.h> #include <dbus/dbus-glib.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <sys/unistd.h> #include <sys/unistd.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <bluetooth/bluetooth.h> #include <bluetooth/bluetooth.h>
...@@ -68,7 +73,13 @@ ...@@ -68,7 +73,13 @@
using namespace sd; 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 { struct DBusObject {
OString maBusName; OString maBusName;
...@@ -223,6 +234,13 @@ bluezCreateListeningSocket() ...@@ -223,6 +234,13 @@ bluezCreateListeningSocket()
return -1; return -1;
} }
// set non-blocking behaviour ...
if( fcntl( nSocket, F_SETFL, O_NONBLOCK) < 0 )
{
close( nSocket );
return -1;
}
return nSocket; return nSocket;
} }
...@@ -379,8 +397,15 @@ void incomingCallback( void *userRefCon, ...@@ -379,8 +397,15 @@ void incomingCallback( void *userRefCon,
BluetoothServer::BluetoothServer( std::vector<Communicator*>* pCommunicators ) BluetoothServer::BluetoothServer( std::vector<Communicator*>* pCommunicators )
: meWasDiscoverable( UNKNOWN ), : meWasDiscoverable( UNKNOWN ),
mpImpl( NULL ),
mpCommunicators( pCommunicators ) mpCommunicators( pCommunicators )
{ {
#ifdef LINUX_BLUETOOTH
g_type_init();
mpImpl = new BluetoothServerImpl();
mpImpl->mpContext = g_main_context_new();
mpImpl->mbExitMainloop = false;
#endif
} }
BluetoothServer::~BluetoothServer() BluetoothServer::~BluetoothServer()
...@@ -563,9 +588,8 @@ void BluetoothServer::addCommunicator( Communicator* pCommunicator ) ...@@ -563,9 +588,8 @@ void BluetoothServer::addCommunicator( Communicator* pCommunicator )
void SAL_CALL BluetoothServer::run() void SAL_CALL BluetoothServer::run()
{ {
SAL_INFO( "sdremote.bluetooth", "BluetoothServer::run called" ); 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(); DBusConnection *pConnection = dbusConnectToNameOnBus();
if( !pConnection ) if( !pConnection )
return; return;
...@@ -580,8 +604,8 @@ void SAL_CALL BluetoothServer::run() ...@@ -580,8 +604,8 @@ void SAL_CALL BluetoothServer::run()
if( !bluezRegisterServiceRecord( pConnection, pService, bluetooth_service_record ) ) if( !bluezRegisterServiceRecord( pConnection, pService, bluetooth_service_record ) )
return; return;
int aSocket = bluezCreateListeningSocket(); int nSocket = bluezCreateListeningSocket();
if( aSocket < 0 ) if( nSocket < 0 )
return; return;
// ---------------- Socket code ---------------- // ---------------- Socket code ----------------
...@@ -589,23 +613,51 @@ void SAL_CALL BluetoothServer::run() ...@@ -589,23 +613,51 @@ void SAL_CALL BluetoothServer::run()
sockaddr_rc aRemoteAddr; sockaddr_rc aRemoteAddr;
socklen_t aRemoteAddrLen = sizeof(aRemoteAddr); socklen_t aRemoteAddrLen = sizeof(aRemoteAddr);
// FIXME: use a glib main-loop [!] ... // Avoid using GSources where we can
// FIXME: fixme ! ...
while ( true ) // 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; aDBusFD.fd = fd;
SAL_INFO( "sdremote.bluetooth", "waiting on accept" ); aDBusFD.events = G_IO_IN | G_IO_PRI;
if ( (bSocket = accept(aSocket, (sockaddr*) &aRemoteAddr, &aRemoteAddrLen)) < 0 ) 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; int nClient;
SAL_WARN( "sdremote.bluetooth", "accept failed with errno " << err ); SAL_INFO( "sdremote.bluetooth", "performing accept" );
close( aSocket ); if ( ( nClient = accept( nSocket, (sockaddr*) &aRemoteAddr, &aRemoteAddrLen)) < 0 &&
return; errno != EAGAIN )
} else { {
SAL_INFO( "sdremote.bluetooth", "connection accepted" ); SAL_WARN( "sdremote.bluetooth", "accept failed with errno " << errno );
Communicator* pCommunicator = new Communicator( new BufferedStreamSocket( bSocket ) ); } else {
mpCommunicators->push_back( pCommunicator ); SAL_INFO( "sdremote.bluetooth", "connection accepted " << nClient );
pCommunicator->launch(); Communicator* pCommunicator = new Communicator( new BufferedStreamSocket( nClient ) );
mpCommunicators->push_back( pCommunicator );
pCommunicator->launch();
}
} }
} }
......
...@@ -16,6 +16,7 @@ namespace sd ...@@ -16,6 +16,7 @@ namespace sd
{ {
class Communicator; class Communicator;
struct BluetoothServerImpl;
class BluetoothServer: class BluetoothServer:
public osl::Thread public osl::Thread
{ {
...@@ -39,7 +40,9 @@ namespace sd ...@@ -39,7 +40,9 @@ namespace sd
enum { UNKNOWN, DISCOVERABLE, NOT_DISCOVERABLE } meWasDiscoverable; enum { UNKNOWN, DISCOVERABLE, NOT_DISCOVERABLE } meWasDiscoverable;
static BluetoothServer *spServer; static BluetoothServer *spServer;
BluetoothServerImpl *mpImpl;
virtual void SAL_CALL run(); virtual void SAL_CALL run();
std::vector<Communicator*>* mpCommunicators; std::vector<Communicator*>* mpCommunicators;
}; };
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment