Bug 1036977: Convert Bluedroid Socket's Listen method to asynchronous design (under bluetooth2/), r=btian
authorThomas Zimmermann <tdz@users.sourceforge.net>
Wed, 16 Jul 2014 10:23:52 +0200
changeset 216352 13fce7913cc4a5e2ade4712cbf8ebd7465651b0c
parent 216351 50fe2ac159dfc7e991cb01dbbc07385801a6484c
child 216353 1f9016933323f33b2d2216b651f1e4a9edac711e
push id515
push userraliiev@mozilla.com
push dateMon, 06 Oct 2014 12:51:51 +0000
treeherdermozilla-release@267c7a481bef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbtian
bugs1036977
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 1036977: Convert Bluedroid Socket's Listen method to asynchronous design (under bluetooth2/), r=btian
dom/bluetooth2/bluedroid/BluetoothInterface.cpp
dom/bluetooth2/bluedroid/BluetoothInterface.h
dom/bluetooth2/bluedroid/BluetoothSocket.cpp
--- a/dom/bluetooth2/bluedroid/BluetoothInterface.cpp
+++ b/dom/bluetooth2/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/bluetooth2/bluedroid/BluetoothInterface.h
+++ b/dom/bluetooth2/bluedroid/BluetoothInterface.h
@@ -42,19 +42,19 @@ public:
 
 class BluetoothSocketInterface
 {
 public:
   friend 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/bluetooth2/bluedroid/BluetoothSocket.cpp
+++ b/dom/bluetooth2/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);