Bug 1029387: Convert Bluedroid Socket's Listen method to asynchronous design, r=shuang
authorThomas Zimmermann <tdz@users.sourceforge.net>
Thu, 10 Jul 2014 15:10:13 +0200
changeset 193326 ed832ef4e12f1dd608f0f08dedbb7f48c709c498
parent 193325 2a8b6b965dc3c3a874af783976e8cc6bea64f0a9
child 193327 786aa9a4e62deb86f72bad84897191428a0b606f
push id27116
push userryanvm@gmail.com
push dateThu, 10 Jul 2014 22:09:47 +0000
treeherdermozilla-central@0a0348d3f0c8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersshuang
bugs1029387
milestone33.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 1029387: Convert Bluedroid Socket's Listen method to asynchronous design, r=shuang
dom/bluetooth/bluedroid/BluetoothInterface.cpp
dom/bluetooth/bluedroid/BluetoothInterface.h
dom/bluetooth/bluedroid/BluetoothSocket.cpp
--- a/dom/bluetooth/bluedroid/BluetoothInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothInterface.cpp
@@ -109,24 +109,31 @@ DispatchBluetoothSocketResult(BluetoothS
   }
   nsresult rv = NS_DispatchToMainThread(runnable);
   if (NS_FAILED(rv)) {
     BT_WARNING("NS_DispatchToMainThread failed: %X", rv);
   }
   return rv;
 }
 
-bt_status_t
+void
 BluetoothSocketInterface::Listen(btsock_type_t aType,
                                  const char* aServiceName,
-                                 const uint8_t* aServiceUuid, int aChannel,
-                                 int& aSockFd, int aFlags)
+                                 const uint8_t* aServiceUuid,
+                                 int aChannel, int aFlags,
+                                 BluetoothSocketResultHandler* aRes)
 {
-  return mInterface->listen(aType, aServiceName, aServiceUuid, aChannel,
-                           &aSockFd, aFlags);
+  int fd;
+
+  bt_status_t status = mInterface->listen(aType, aServiceName, aServiceUuid,
+                                          aChannel, &fd, aFlags);
+  if (aRes) {
+    DispatchBluetoothSocketResult(aRes, &BluetoothSocketResultHandler::Listen,
+                                  fd, status);
+  }
 }
 
 bt_status_t
 BluetoothSocketInterface::Connect(const bt_bdaddr_t* aBdAddr,
                                   btsock_type_t aType, const uint8_t* aUuid,
                                   int aChannel, int& aSockFd, int aFlags)
 {
   return mInterface->connect(aBdAddr, aType, aUuid, aChannel, &aSockFd,
--- a/dom/bluetooth/bluedroid/BluetoothInterface.h
+++ b/dom/bluetooth/bluedroid/BluetoothInterface.h
@@ -42,19 +42,19 @@ public:
 
 class BluetoothSocketInterface
 {
 public:
   friend class BluetoothInterface;
 
   // Init and Cleanup is handled by BluetoothInterface
 
-  bt_status_t Listen(btsock_type_t aType,
-                     const char* aServiceName, const uint8_t* aServiceUuid,
-                     int aChannel, int& aSockFd, int aFlags);
+  void Listen(btsock_type_t aType,
+              const char* aServiceName, const uint8_t* aServiceUuid,
+              int aChannel, int aFlags, BluetoothSocketResultHandler* aRes);
 
   bt_status_t Connect(const bt_bdaddr_t* aBdAddr, btsock_type_t aType,
                       const uint8_t* aUuid, int aChannel, int& aSockFd,
                       int aFlags);
 
 protected:
   BluetoothSocketInterface(const btsock_interface_t* aInterface);
   ~BluetoothSocketInterface();
--- a/dom/bluetooth/bluedroid/BluetoothSocket.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothSocket.cpp
@@ -155,17 +155,17 @@ public:
     MOZ_ASSERT(!mShuttingDownOnIOThread);
 
     RemoveWatchers(READ_WATCHER | WRITE_WATCHER);
 
     mShuttingDownOnIOThread = true;
   }
 
   void Connect();
-  void Listen();
+  void Listen(int aFd);
 
   void SetUpIO(bool aWrite)
   {
     AddWatchers(READ_WATCHER, true);
     if (aWrite) {
         AddWatchers(WRITE_WATCHER, false);
     }
   }
@@ -402,27 +402,31 @@ public:
     MOZ_ASSERT(!IsCanceled());
     GetDroidSocketImpl()->Connect();
   }
 };
 
 class SocketListenTask : public DroidSocketImplTask
 {
 public:
-  SocketListenTask(DroidSocketImpl* aDroidSocketImpl)
+  SocketListenTask(DroidSocketImpl* aDroidSocketImpl, int aFd)
   : DroidSocketImplTask(aDroidSocketImpl)
+  , mFd(aFd)
   { }
 
   void Run() MOZ_OVERRIDE
   {
     MOZ_ASSERT(!NS_IsMainThread());
     if (!IsCanceled()) {
-      GetDroidSocketImpl()->Listen();
+      GetDroidSocketImpl()->Listen(mFd);
     }
   }
+
+private:
+  int mFd;
 };
 
 class SocketConnectClientFdTask : public Task
 {
   virtual void Run()
   {
     MOZ_ASSERT(!NS_IsMainThread());
     mImpl->ConnectClientFd();
@@ -464,43 +468,29 @@ DroidSocketImpl::Connect()
 
   SetFd(fd);
 
   AddWatchers(READ_WATCHER, true);
   AddWatchers(WRITE_WATCHER, false);
 }
 
 void
-DroidSocketImpl::Listen()
+DroidSocketImpl::Listen(int aFd)
 {
-  MOZ_ASSERT(sBluetoothSocketInterface);
-
-  // TODO: uuid and service name as arguments
+  MOZ_ASSERT(aFd >= 0);
 
-  int fd = -1;
-  bt_status_t status =
-    sBluetoothSocketInterface->Listen(BTSOCK_RFCOMM,
-                                      "OBEX Object Push",
-                                      UUID_OBEX_OBJECT_PUSH,
-                                      mChannel,
-                                      fd,
-                                      (BTSOCK_FLAG_ENCRYPT * mEncrypt) |
-                                      (BTSOCK_FLAG_AUTH * mAuth));
-  NS_ENSURE_TRUE_VOID(status == BT_STATUS_SUCCESS);
-  NS_ENSURE_TRUE_VOID(fd >= 0);
-
-  int flags = TEMP_FAILURE_RETRY(fcntl(fd, F_GETFL));
+  int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL));
   NS_ENSURE_TRUE_VOID(flags >= 0);
 
   if (!(flags & O_NONBLOCK)) {
-    int res = TEMP_FAILURE_RETRY(fcntl(fd, F_SETFL, flags | O_NONBLOCK));
+    int res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags | O_NONBLOCK));
     NS_ENSURE_TRUE_VOID(!res);
   }
 
-  SetFd(fd);
+  SetFd(aFd);
   AddWatchers(READ_WATCHER, true);
 }
 
 ssize_t
 DroidSocketImpl::ReadMsg(int aFd, void *aBuffer, size_t aLength)
 {
   ssize_t ret;
   struct msghdr msg;
@@ -694,27 +684,61 @@ BluetoothSocket::Connect(const nsAString
   mImpl = new DroidSocketImpl(XRE_GetIOMessageLoop(), this, aDeviceAddress,
                               aChannel, mAuth, mEncrypt);
   XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
                                    new SocketConnectTask(mImpl));
 
   return true;
 }
 
+class ListenResultHandler MOZ_FINAL : public BluetoothSocketResultHandler
+{
+public:
+  ListenResultHandler(DroidSocketImpl* aImpl)
+  : mImpl(aImpl)
+  {
+    MOZ_ASSERT(mImpl);
+  }
+
+  void Listen(int aFd) MOZ_OVERRIDE
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+
+    XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
+                                     new SocketListenTask(mImpl, aFd));
+  }
+
+  void OnError(bt_status_t aStatus) MOZ_OVERRIDE
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+
+    BT_WARNING("Listen failed: %d", (int)aStatus);
+  }
+
+private:
+  DroidSocketImpl* mImpl;
+};
+
 bool
 BluetoothSocket::Listen(int aChannel)
 {
   MOZ_ASSERT(NS_IsMainThread());
   NS_ENSURE_FALSE(mImpl, false);
 
   mIsServer = true;
   mImpl = new DroidSocketImpl(XRE_GetIOMessageLoop(), this, aChannel, mAuth,
                               mEncrypt);
-  XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
-                                   new SocketListenTask(mImpl));
+
+  sBluetoothSocketInterface->Listen(BTSOCK_RFCOMM,
+                                    "OBEX Object Push",
+                                    UUID_OBEX_OBJECT_PUSH,
+                                    aChannel,
+                                    (BTSOCK_FLAG_ENCRYPT * mEncrypt) |
+                                    (BTSOCK_FLAG_AUTH * mAuth),
+                                    new ListenResultHandler(mImpl));
   return true;
 }
 
 bool
 BluetoothSocket::SendDroidSocketData(UnixSocketRawData* aData)
 {
   MOZ_ASSERT(NS_IsMainThread());
   NS_ENSURE_TRUE(mImpl, false);