Bug 811683 - Changed UnixSocketRawData to take variable sizes up to 64k, r=cjones
authorKyle Machulis <kyle@nonpolynomial.com>
Thu, 20 Dec 2012 18:36:55 +0800
changeset 125720 216d556025d1a009f0189f9d2b6370ba25bc41e2
parent 125719 40adf72fd612c2e7bc939403c3bc011fe32e7924
child 125721 14a7b73eb421e8b382b12756d4d507358b7d5176
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscjones
bugs811683
milestone20.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 811683 - Changed UnixSocketRawData to take variable sizes up to 64k, r=cjones
dom/bluetooth/BluetoothHfpManager.cpp
ipc/unixsocket/UnixSocket.cpp
ipc/unixsocket/UnixSocket.h
--- a/dom/bluetooth/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/BluetoothHfpManager.cpp
@@ -591,17 +591,17 @@ BluetoothHfpManager::HandleShutdown()
 // Virtual function of class SocketConsumer
 void
 BluetoothHfpManager::ReceiveSocketData(UnixSocketRawData* aMessage)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   int currentCallState = mCurrentCallStateArray[mCurrentCallIndex];
 
-  nsAutoCString msg((const char*)aMessage->mData);
+  nsAutoCString msg((const char*)aMessage->mData.get());
   msg.StripWhitespace();
 
   nsTArray<nsCString> atCommandValues;
 
   // For more information, please refer to 4.34.1 "Bluetooth Defined AT
   // Capabilities" in Bluetooth hands-free profile 1.6
   if (msg.Find("AT+BRSF=") != -1) {
     SendCommand("+BRSF: ", 23);
--- a/ipc/unixsocket/UnixSocket.cpp
+++ b/ipc/unixsocket/UnixSocket.cpp
@@ -19,16 +19,18 @@
 #include "mozilla/Monitor.h"
 #include "mozilla/Util.h"
 #include "mozilla/FileUtils.h"
 #include "nsString.h"
 #include "nsThreadUtils.h"
 #include "nsTArray.h"
 #include "nsXULAppAPI.h"
 
+static const size_t MAX_READ_SIZE = 1 << 16;
+
 #undef LOG
 #if defined(MOZ_WIDGET_GONK)
 #include <android/log.h>
 #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "GonkDBus", args);
 #else
 #define BTDEBUG true
 #define LOG(args...) if (BTDEBUG) printf(args);
 #endif
@@ -580,17 +582,17 @@ UnixSocketConsumer::SendSocketData(UnixS
 
 bool
 UnixSocketConsumer::SendSocketData(const nsACString& aStr)
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (!mImpl) {
     return false;
   }
-  if (aStr.Length() > UnixSocketRawData::MAX_DATA_SIZE) {
+  if (aStr.Length() > MAX_READ_SIZE) {
     return false;
   }
   nsCString str(aStr);
   UnixSocketRawData* d = new UnixSocketRawData(aStr.Length());
   memcpy(d->mData, str.get(), aStr.Length());
   XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
                                    new SocketSendTask(this, mImpl, d));
   return true;
@@ -624,47 +626,45 @@ UnixSocketImpl::OnFileCanReadWithoutBloc
   //   - mIncoming is completely read
   //     If so, sConsumer->MessageReceived(mIncoming.forget())
   //
   //   - mIncoming isn't completely read, but there's no more
   //     data available on the socket
   //     If so, break;
   while (true) {
     if (!mIncoming) {
-      mIncoming = new UnixSocketRawData();
-      ssize_t ret = read(aFd, mIncoming->mData, UnixSocketRawData::MAX_DATA_SIZE);
+      uint8_t data[MAX_READ_SIZE];
+      ssize_t ret = read(aFd, data, MAX_READ_SIZE);
       if (ret <= 0) {
         if (ret == -1) {
           if (errno == EINTR) {
             continue; // retry system call when interrupted
           }
           else if (errno == EAGAIN || errno == EWOULDBLOCK) {
-            mIncoming.forget();
             return; // no data available: return and re-poll
           }
           // else fall through to error handling on other errno's
         }
 #ifdef DEBUG
         NS_WARNING("Cannot read from network");
 #endif
         // At this point, assume that we can't actually access
         // the socket anymore
-        mIncoming.forget();
         mReadWatcher.StopWatchingFileDescriptor();
         mWriteWatcher.StopWatchingFileDescriptor();
         nsRefPtr<SocketCloseTask> t = new SocketCloseTask(this);
         NS_DispatchToMainThread(t);
         return;
       }
-      mIncoming->mData[ret] = 0;
-      mIncoming->mSize = ret;
+      mIncoming = new UnixSocketRawData(ret);
+      memcpy(mIncoming->mData, data, ret);
       nsRefPtr<SocketReceiveTask> t =
         new SocketReceiveTask(this, mIncoming.forget());
       NS_DispatchToMainThread(t);
-      if (ret < ssize_t(UnixSocketRawData::MAX_DATA_SIZE)) {
+      if (ret < ssize_t(MAX_READ_SIZE)) {
         return;
       }
     }
   }
 }
 
 void
 UnixSocketImpl::OnFileCanWriteWithoutBlocking(int aFd)
--- a/ipc/unixsocket/UnixSocket.h
+++ b/ipc/unixsocket/UnixSocket.h
@@ -11,47 +11,38 @@
 #include <stdlib.h>
 #include "nsString.h"
 #include "nsAutoPtr.h"
 #include "mozilla/RefPtr.h"
 
 namespace mozilla {
 namespace ipc {
 
-struct UnixSocketRawData
+class UnixSocketRawData
 {
-  static const size_t MAX_DATA_SIZE = 1024;
-  uint8_t mData[MAX_DATA_SIZE];
+public:
+  nsAutoArrayPtr<uint8_t> mData;
 
   // Number of octets in mData.
   size_t mSize;
   size_t mCurrentWriteOffset;
 
   /**
-   * Constructor for situations where size is not known beforehand. (for
-   * example, when reading a packet)
-   *
-   */
-  UnixSocketRawData() :
-    mSize(0),
-    mCurrentWriteOffset(0)
-  {
-  }
-
-  /**
    * Constructor for situations where size is known beforehand (for example,
    * when being assigned strings)
    *
    */
   UnixSocketRawData(int aSize) :
     mSize(aSize),
     mCurrentWriteOffset(0)
   {
+    mData = new uint8_t[aSize];
   }
-
+private:
+  UnixSocketRawData() {}
 };
 
 class UnixSocketImpl;
 
 /**
  * UnixSocketConnector defines the socket creation and connection/listening
  * functions for a UnixSocketConsumer. Due to the fact that socket setup can
  * vary between protocols (unix sockets, tcp sockets, bluetooth sockets, etc),