Bug 1159709: Inherit |BluetoothDaemonConnection| from |DataSocket|, r=kmachulis
authorThomas Zimmermann <tdz@users.sourceforge.net>
Thu, 30 Apr 2015 12:55:37 +0200
changeset 273047 38d4b09aef8f0e2c949cba5e35153687d99d60e7
parent 273046 0ab34a4a4b2fa952802baf1b3951038f8a1d8b66
child 273048 895d14811245aa5bc5b4b856bddc2c9da1ad5098
push id863
push userraliiev@mozilla.com
push dateMon, 03 Aug 2015 13:22:43 +0000
treeherdermozilla-release@f6321b14228d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskmachulis
bugs1159709
milestone40.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1159709: Inherit |BluetoothDaemonConnection| from |DataSocket|, r=kmachulis |BluetoothDaemonConnection| sends and receives data. With this patch it inherits from |DataSocket|, which provides the respective abstract interfaces.
dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
ipc/bluetooth/BluetoothDaemonConnection.cpp
ipc/bluetooth/BluetoothDaemonConnection.h
--- a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
@@ -1505,17 +1505,19 @@ nsresult
 BluetoothDaemonProtocol::Send(BluetoothDaemonPDU* aPDU, void* aUserData)
 {
   MOZ_ASSERT(mConnection);
   MOZ_ASSERT(aPDU);
 
   aPDU->SetConsumer(this);
   aPDU->SetUserData(aUserData);
   aPDU->UpdateHeader();
-  return mConnection->Send(aPDU); // Forward PDU to command channel
+  mConnection->SendSocketData(aPDU); // Forward PDU to command channel
+
+  return NS_OK;
 }
 
 void
 BluetoothDaemonProtocol::HandleSetupSvc(
   const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
   void* aUserData)
 {
   BluetoothDaemonSetupModule::HandleSvc(aHeader, aPDU, aUserData);
--- a/ipc/bluetooth/BluetoothDaemonConnection.cpp
+++ b/ipc/bluetooth/BluetoothDaemonConnection.cpp
@@ -195,148 +195,82 @@ BluetoothDaemonPDUConsumer::BluetoothDae
 BluetoothDaemonPDUConsumer::~BluetoothDaemonPDUConsumer()
 { }
 
 //
 // BluetoothDaemonConnectionIO
 //
 
 class BluetoothDaemonConnectionIO final : public UnixSocketWatcher
-                                        , public SocketIOBase
+                                        , public DataSocketIO
                                         , public ConnectionOrientedSocketIO
 {
 public:
   BluetoothDaemonConnectionIO(MessageLoop* aIOLoop, int aFd,
                               ConnectionStatus aConnectionStatus,
                               BluetoothDaemonConnection* aConnection,
                               BluetoothDaemonPDUConsumer* aConsumer);
 
-  SocketBase* GetSocketBase();
-
-  // StreamSocketIOBase
-  //
-
-  nsresult Accept(int aFd,
-                  const union sockaddr_any* aAddr, socklen_t aAddrLen);
-
-  // Shutdown state
-  //
-
-  bool IsShutdownOnMainThread() const;
-  void ShutdownOnMainThread();
-
-  bool IsShutdownOnIOThread() const;
-  void ShutdownOnIOThread();
-
   // Task callback methods
   //
 
   void Connect(const char* aSocketName);
 
-  void Send(BluetoothDaemonPDU* aPDU);
-  void EnqueueData(BluetoothDaemonPDU* aPDU);
-  bool HasPendingData() const;
-
-  nsresult Receive(struct msghdr& msg);
+  void Send(UnixSocketIOBuffer* aBuffer);
 
   void OnSocketCanReceiveWithoutBlocking() override;
   void OnSocketCanSendWithoutBlocking() override;
 
   void OnConnected() override;
   void OnError(const char* aFunction, int aErrno) override;
 
+  // Methods for |ConnectionOrientedSocketIO|
+  //
+
+  nsresult Accept(int aFd,
+                  const union sockaddr_any* aAddr,
+                  socklen_t aAddrLen) override;
+
+  // Methods for |DataSocketIO|
+  //
+
+  nsresult QueryReceiveBuffer(UnixSocketIOBuffer** aBuffer) override;
+  void ConsumeBuffer() override;
+  void DiscardBuffer() override;
+
+  // Methods for |SocketIOBase|
+  //
+
+  SocketBase* GetSocketBase() override;
+
+  bool IsShutdownOnMainThread() const override;
+  bool IsShutdownOnIOThread() const override;
+
+  void ShutdownOnMainThread() override;
+  void ShutdownOnIOThread() override;
+
 private:
-  ssize_t  ReceiveData(int aFd);
-  nsresult SendPendingData(int aFd);
-
   BluetoothDaemonConnection* mConnection;
   BluetoothDaemonPDUConsumer* mConsumer;
   nsAutoPtr<BluetoothDaemonPDU> mPDU;
-  nsTArray<BluetoothDaemonPDU*> mOutgoingQ;
   bool mShuttingDownOnIOThread;
 };
 
 BluetoothDaemonConnectionIO::BluetoothDaemonConnectionIO(
   MessageLoop* aIOLoop, int aFd,
   ConnectionStatus aConnectionStatus,
   BluetoothDaemonConnection* aConnection,
   BluetoothDaemonPDUConsumer* aConsumer)
 : UnixSocketWatcher(aIOLoop, aFd, aConnectionStatus)
 , mConnection(aConnection)
 , mConsumer(aConsumer)
 , mShuttingDownOnIOThread(false)
 {
   MOZ_ASSERT(mConnection);
   MOZ_ASSERT(mConsumer);
-
-  /* There's only one PDU for receiving, which we reuse everytime */
-  mPDU = new BluetoothDaemonPDU(BluetoothDaemonPDU::MAX_PAYLOAD_LENGTH);
-}
-
-SocketBase*
-BluetoothDaemonConnectionIO::GetSocketBase()
-{
-  return mConnection;
-}
-
-bool
-BluetoothDaemonConnectionIO::IsShutdownOnMainThread() const
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  return mConnection == nullptr;
-}
-
-void
-BluetoothDaemonConnectionIO::ShutdownOnMainThread()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(!IsShutdownOnMainThread());
-
-  mConnection = nullptr;
-}
-
-bool
-BluetoothDaemonConnectionIO::IsShutdownOnIOThread() const
-{
-  return mShuttingDownOnIOThread;
-}
-
-void
-BluetoothDaemonConnectionIO::ShutdownOnIOThread()
-{
-  MOZ_ASSERT(!NS_IsMainThread());
-  MOZ_ASSERT(!mShuttingDownOnIOThread);
-
-  Close(); // will also remove fd from I/O loop
-  mShuttingDownOnIOThread = true;
-}
-
-nsresult
-BluetoothDaemonConnectionIO::Accept(int aFd,
-                                    const union sockaddr_any* aAddr,
-                                    socklen_t aAddrLen)
-{
-  MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
-  MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTING);
-
-  // File-descriptor setup
-
-  if (TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, O_NONBLOCK)) < 0) {
-    OnError("fcntl", errno);
-    ScopedClose cleanupFd(aFd);
-    return NS_ERROR_FAILURE;
-  }
-
-  SetSocket(aFd, SOCKET_IS_CONNECTED);
-
-  // Signal success
-  OnConnected();
-
-  return NS_OK;
 }
 
 void
 BluetoothDaemonConnectionIO::Connect(const char* aSocketName)
 {
   static const size_t sNameOffset = 1;
 
   MOZ_ASSERT(aSocketName);
@@ -374,101 +308,37 @@ BluetoothDaemonConnectionIO::Connect(con
   // Connect socket to address; calls OnConnected()
   // on success, or OnError() otherwise
   nsresult rv = UnixSocketWatcher::Connect(
     reinterpret_cast<struct sockaddr*>(&addr), socklen);
   NS_WARN_IF(NS_FAILED(rv));
 }
 
 void
-BluetoothDaemonConnectionIO::Send(BluetoothDaemonPDU* aPDU)
-{
-  MOZ_ASSERT(mConsumer);
-  MOZ_ASSERT(aPDU);
-
-  EnqueueData(aPDU);
-  AddWatchers(WRITE_WATCHER, false);
-}
-
-void
-BluetoothDaemonConnectionIO::EnqueueData(BluetoothDaemonPDU* aPDU)
-{
-  MOZ_ASSERT(aPDU);
-
-  mOutgoingQ.AppendElement(aPDU);
-}
-
-bool
-BluetoothDaemonConnectionIO::HasPendingData() const
+BluetoothDaemonConnectionIO::Send(UnixSocketIOBuffer* aBuffer)
 {
-  return !mOutgoingQ.IsEmpty();
-}
-
-ssize_t
-BluetoothDaemonConnectionIO::ReceiveData(int aFd)
-{
-  MOZ_ASSERT(aFd >= 0);
+  MOZ_ASSERT(aBuffer);
 
-  ssize_t res = mPDU->Receive(aFd);
-  if (res < 0) {
-    /* an I/O error occured */
-    NS_DispatchToMainThread(new SocketIORequestClosingRunnable(this));
-    return -1;
-  } else if (!res) {
-    /* EOF or peer shut down sending */
-    NS_DispatchToMainThread(new SocketIORequestClosingRunnable(this));
-    return 0;
-  }
-
-  mConsumer->Handle(*mPDU);
-
-  return res;
+  EnqueueData(aBuffer);
+  AddWatchers(WRITE_WATCHER, false);
 }
 
 void
 BluetoothDaemonConnectionIO::OnSocketCanReceiveWithoutBlocking()
 {
-  MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
-  MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED);
-  MOZ_ASSERT(!IsShutdownOnIOThread());
-
   ssize_t res = ReceiveData(GetFd());
   if (res < 0) {
     /* I/O error */
     RemoveWatchers(READ_WATCHER|WRITE_WATCHER);
   } else if (!res) {
     /* EOF or peer shutdown */
     RemoveWatchers(READ_WATCHER);
   }
 }
 
-nsresult
-BluetoothDaemonConnectionIO::SendPendingData(int aFd)
-{
-  while (HasPendingData()) {
-    BluetoothDaemonPDU* outgoing = mOutgoingQ.ElementAt(0);
-    MOZ_ASSERT(outgoing);
-
-    ssize_t res = outgoing->Send(aFd);
-    if (res < 0) {
-      /* an I/O error occured */
-      return NS_ERROR_FAILURE;
-    } else if (!res) {
-      /* I/O is currently blocked; try again later */
-      return NS_OK;
-    }
-
-    MOZ_ASSERT(!outgoing->GetSize());
-    mOutgoingQ.RemoveElementAt(0);
-    delete outgoing;
-  }
-
-  return NS_OK;
-}
-
 void
 BluetoothDaemonConnectionIO::OnSocketCanSendWithoutBlocking()
 {
   MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
   MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED);
   MOZ_ASSERT(!IsShutdownOnIOThread());
 
   if (NS_WARN_IF(NS_FAILED(SendPendingData(GetFd())))) {
@@ -501,16 +371,113 @@ BluetoothDaemonConnectionIO::OnError(con
   // Clean up watchers, status, fd
   Close();
 
   // Tell the main thread we've errored
   NS_DispatchToMainThread(
     new SocketIOEventRunnable(this, SocketIOEventRunnable::CONNECT_ERROR));
 }
 
+// |ConnectionOrientedSocketIO|
+
+nsresult
+BluetoothDaemonConnectionIO::Accept(int aFd,
+                                    const union sockaddr_any* aAddr,
+                                    socklen_t aAddrLen)
+{
+  MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
+  MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTING);
+
+  // File-descriptor setup
+
+  if (TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, O_NONBLOCK)) < 0) {
+    OnError("fcntl", errno);
+    ScopedClose cleanupFd(aFd);
+    return NS_ERROR_FAILURE;
+  }
+
+  SetSocket(aFd, SOCKET_IS_CONNECTED);
+
+  // Signal success
+  OnConnected();
+
+  return NS_OK;
+}
+
+// |DataSocketIO|
+
+nsresult
+BluetoothDaemonConnectionIO::QueryReceiveBuffer(UnixSocketIOBuffer** aBuffer)
+{
+  MOZ_ASSERT(aBuffer);
+
+  if (!mPDU) {
+    /* There's only one PDU for receiving. We reuse it every time. */
+    mPDU = new BluetoothDaemonPDU(BluetoothDaemonPDU::MAX_PAYLOAD_LENGTH);
+  }
+  *aBuffer = mPDU.get();
+
+  return NS_OK;
+}
+
+void
+BluetoothDaemonConnectionIO::ConsumeBuffer()
+{
+  MOZ_ASSERT(mConsumer);
+
+  mConsumer->Handle(*mPDU);
+}
+
+void
+BluetoothDaemonConnectionIO::DiscardBuffer()
+{
+  // Nothing to do.
+}
+
+// |SocketIOBase|
+
+SocketBase*
+BluetoothDaemonConnectionIO::GetSocketBase()
+{
+  return mConnection;
+}
+
+bool
+BluetoothDaemonConnectionIO::IsShutdownOnMainThread() const
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  return mConnection == nullptr;
+}
+
+bool
+BluetoothDaemonConnectionIO::IsShutdownOnIOThread() const
+{
+  return mShuttingDownOnIOThread;
+}
+
+void
+BluetoothDaemonConnectionIO::ShutdownOnMainThread()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(!IsShutdownOnMainThread());
+
+  mConnection = nullptr;
+}
+
+void
+BluetoothDaemonConnectionIO::ShutdownOnIOThread()
+{
+  MOZ_ASSERT(!NS_IsMainThread());
+  MOZ_ASSERT(!mShuttingDownOnIOThread);
+
+  Close(); // will also remove fd from I/O loop
+  mShuttingDownOnIOThread = true;
+}
+
 //
 // I/O helper tasks
 //
 
 class BluetoothDaemonConnectTask final
   : public SocketIOTask<BluetoothDaemonConnectionIO>
 {
 public:
@@ -527,17 +494,17 @@ public:
   }
 };
 
 //
 // BluetoothDaemonConnection
 //
 
 BluetoothDaemonConnection::BluetoothDaemonConnection()
-: mIO(nullptr)
+  : mIO(nullptr)
 { }
 
 BluetoothDaemonConnection::~BluetoothDaemonConnection()
 { }
 
 nsresult
 BluetoothDaemonConnection::ConnectSocket(BluetoothDaemonPDUConsumer* aConsumer)
 {
@@ -553,16 +520,59 @@ BluetoothDaemonConnection::ConnectSocket
   MessageLoop* ioLoop = XRE_GetIOMessageLoop();
   mIO = new BluetoothDaemonConnectionIO(
     ioLoop, -1, UnixSocketWatcher::SOCKET_IS_CONNECTING, this, aConsumer);
   ioLoop->PostTask(FROM_HERE, new BluetoothDaemonConnectTask(mIO));
 
   return NS_OK;
 }
 
+ConnectionOrientedSocketIO*
+BluetoothDaemonConnection::PrepareAccept(BluetoothDaemonPDUConsumer* aConsumer)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(!mIO);
+  MOZ_ASSERT(aConsumer);
+
+  SetConnectionStatus(SOCKET_CONNECTING);
+
+  mIO = new BluetoothDaemonConnectionIO(
+    XRE_GetIOMessageLoop(), -1, UnixSocketWatcher::SOCKET_IS_CONNECTING,
+    this, aConsumer);
+
+  return mIO;
+}
+
+// |ConnectionOrientedSocket|
+
+ConnectionOrientedSocketIO*
+BluetoothDaemonConnection::GetIO()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(mIO); // Call |PrepareAccept| before listening for connections
+
+  return mIO;
+}
+
+// |DataSocket|
+
+void
+BluetoothDaemonConnection::SendSocketData(UnixSocketIOBuffer* aBuffer)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(mIO);
+
+  XRE_GetIOMessageLoop()->PostTask(
+    FROM_HERE,
+    new SocketIOSendTask<BluetoothDaemonConnectionIO,
+                         UnixSocketIOBuffer>(mIO, aBuffer));
+}
+
+// |SocketBase|
+
 void
 BluetoothDaemonConnection::CloseSocket()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (!mIO) {
     CHROMIUM_LOG("Bluetooth daemon already disconnected!");
     return;
@@ -570,52 +580,10 @@ BluetoothDaemonConnection::CloseSocket()
 
   XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new SocketIOShutdownTask(mIO));
 
   mIO = nullptr;
 
   NotifyDisconnect();
 }
 
-nsresult
-BluetoothDaemonConnection::Send(BluetoothDaemonPDU* aPDU)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (!mIO) {
-    CHROMIUM_LOG("Bluetooth daemon already connecting/connected!");
-    return NS_ERROR_FAILURE;
-  }
-
-  XRE_GetIOMessageLoop()->PostTask(
-    FROM_HERE,
-    new SocketIOSendTask<BluetoothDaemonConnectionIO,
-                         BluetoothDaemonPDU>(mIO, aPDU));
-  return NS_OK;
-}
-
-ConnectionOrientedSocketIO*
-BluetoothDaemonConnection::GetIO()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mIO); // Call |PrepareAccept| before listening for connections
-
-  return mIO;
-}
-
-ConnectionOrientedSocketIO*
-BluetoothDaemonConnection::PrepareAccept(BluetoothDaemonPDUConsumer* aConsumer)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(!mIO);
-  MOZ_ASSERT(aConsumer);
-
-  SetConnectionStatus(SOCKET_CONNECTING);
-
-  mIO = new BluetoothDaemonConnectionIO(
-    XRE_GetIOMessageLoop(), -1, UnixSocketWatcher::SOCKET_IS_CONNECTING,
-    this, aConsumer);
-
-  return mIO;
-}
-
 }
 }
--- a/ipc/bluetooth/BluetoothDaemonConnection.h
+++ b/ipc/bluetooth/BluetoothDaemonConnection.h
@@ -5,17 +5,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_ipc_bluetooth_BluetoothDaemonConnection_h
 #define mozilla_ipc_bluetooth_BluetoothDaemonConnection_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/FileUtils.h"
 #include "mozilla/ipc/ConnectionOrientedSocket.h"
-#include "mozilla/ipc/SocketBase.h"
+#include "mozilla/ipc/DataSocket.h"
 #include "nsError.h"
 #include "nsAutoPtr.h"
 
 namespace mozilla {
 namespace ipc {
 
 class BluetoothDaemonConnectionIO;
 class BluetoothDaemonPDUConsumer;
@@ -107,36 +107,40 @@ protected:
   BluetoothDaemonPDUConsumer();
 };
 
 /*
  * |BluetoothDaemonConnection| represents the socket to connect to the
  * Bluetooth daemon. It offers connection establishment and sending
  * PDUs. PDU receiving is performed by |BluetoothDaemonPDUConsumer|.
  */
-class BluetoothDaemonConnection : public SocketBase
+class BluetoothDaemonConnection : public DataSocket
                                 , public ConnectionOrientedSocket
 {
 public:
   BluetoothDaemonConnection();
   virtual ~BluetoothDaemonConnection();
 
-  // SocketBase
-  //
+  nsresult ConnectSocket(BluetoothDaemonPDUConsumer* aConsumer);
 
-  nsresult ConnectSocket(BluetoothDaemonPDUConsumer* aConsumer);
-  void     CloseSocket();
-
-  nsresult Send(BluetoothDaemonPDU* aPDU);
-
-  // ConnectionOrientedSocket
+  // Methods for |ConnectionOrientedSocket|
   //
 
   virtual ConnectionOrientedSocketIO* GetIO() override;
 
+  // Methods for |DataSocket|
+  //
+
+  void SendSocketData(UnixSocketIOBuffer* aBuffer) override;
+
+  // Methods for |SocketBase|
+  //
+
+  void CloseSocket() override;
+
 protected:
 
   // Prepares an instance of |BluetoothDaemonConnection| in DISCONNECTED
   // state for accepting a connection. Subclasses implementing |GetIO|
   // need to call this method.
   ConnectionOrientedSocketIO*
     PrepareAccept(BluetoothDaemonPDUConsumer* aConsumer);