Bug 1034159 - Fix a potential buffer leak caused by a race condition when ending recording a video. r=mikeh
authorAndrew Osmond <aosmond@mozilla.com>
Thu, 03 Jul 2014 10:30:00 +0200
changeset 206175 928ae2f662582694f5ff5e6fa666898837a3a8b7
parent 206174 c7ef22a8382bdfbd0dc54d3013b63b1e2189c8ce
child 206176 745840b2693f805b7dec1bee72cf45173047c7ca
push id6561
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 21:23:20 +0000
treeherdermozilla-aurora@428d4d3c8588 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmikeh
bugs1034159
milestone33.0a1
Bug 1034159 - Fix a potential buffer leak caused by a race condition when ending recording a video. r=mikeh
dom/camera/GonkCameraHwMgr.cpp
dom/camera/GonkCameraListener.h
dom/camera/GonkCameraSource.cpp
--- a/dom/camera/GonkCameraHwMgr.cpp
+++ b/dom/camera/GonkCameraHwMgr.cpp
@@ -127,17 +127,20 @@ GonkCameraHardware::postDataTimestamp(ns
 {
   DOM_CAMERA_LOGI("%s",__func__);
   if (mClosing) {
     return;
   }
 
   if (mListener.get()) {
     DOM_CAMERA_LOGI("Listener registered, posting recording frame!");
-    mListener->postDataTimestamp(aTimestamp, aMsgType, aDataPtr);
+    if (!mListener->postDataTimestamp(aTimestamp, aMsgType, aDataPtr)) {
+      DOM_CAMERA_LOGW("Listener unable to process. Drop a recording frame.");
+      mCamera->releaseRecordingFrame(aDataPtr);
+    }
   } else {
     DOM_CAMERA_LOGW("No listener was set. Drop a recording frame.");
     mCamera->releaseRecordingFrame(aDataPtr);
   }
 }
 
 nsresult
 GonkCameraHardware::Init()
--- a/dom/camera/GonkCameraListener.h
+++ b/dom/camera/GonkCameraListener.h
@@ -22,16 +22,16 @@
 
 namespace android {
 
 // ref-counted object for callbacks
 class GonkCameraListener: virtual public RefBase
 {
 public:
     virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2) = 0;
-    virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr,
+    virtual bool postData(int32_t msgType, const sp<IMemory>& dataPtr,
                           camera_frame_metadata_t *metadata) = 0;
-    virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) = 0;
+    virtual bool postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) = 0;
 };
 
 }; // namespace android
 
 #endif
--- a/dom/camera/GonkCameraSource.cpp
+++ b/dom/camera/GonkCameraSource.cpp
@@ -52,20 +52,20 @@ using namespace mozilla;
 namespace android {
 
 static const int64_t CAMERA_SOURCE_TIMEOUT_NS = 3000000000LL;
 
 struct GonkCameraSourceListener : public GonkCameraListener {
     GonkCameraSourceListener(const sp<GonkCameraSource> &source);
 
     virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2);
-    virtual void postData(int32_t msgType, const sp<IMemory> &dataPtr,
+    virtual bool postData(int32_t msgType, const sp<IMemory> &dataPtr,
                           camera_frame_metadata_t *metadata);
 
-    virtual void postDataTimestamp(
+    virtual bool postDataTimestamp(
             nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
 
 protected:
     virtual ~GonkCameraSourceListener();
 
 private:
     wp<GonkCameraSource> mSource;
 
@@ -79,34 +79,38 @@ GonkCameraSourceListener::GonkCameraSour
 
 GonkCameraSourceListener::~GonkCameraSourceListener() {
 }
 
 void GonkCameraSourceListener::notify(int32_t msgType, int32_t ext1, int32_t ext2) {
     CS_LOGV("notify(%d, %d, %d)", msgType, ext1, ext2);
 }
 
-void GonkCameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr,
+bool GonkCameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr,
                                     camera_frame_metadata_t *metadata) {
     CS_LOGV("postData(%d, ptr:%p, size:%d)",
          msgType, dataPtr->pointer(), dataPtr->size());
 
     sp<GonkCameraSource> source = mSource.promote();
     if (source.get() != NULL) {
         source->dataCallback(msgType, dataPtr);
+        return true;
     }
+    return false;
 }
 
-void GonkCameraSourceListener::postDataTimestamp(
+bool GonkCameraSourceListener::postDataTimestamp(
         nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) {
 
     sp<GonkCameraSource> source = mSource.promote();
     if (source.get() != NULL) {
         source->dataCallbackTimestamp(timestamp/1000, msgType, dataPtr);
+        return true;
     }
+    return false;
 }
 
 static int32_t getColorFormat(const char* colorFormat) {
     return OMX_COLOR_FormatYUV420SemiPlanar; //XXX nsGonkCameraControl uses only YUV420SemiPlanar
 
     if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV420P)) {
        return OMX_COLOR_FormatYUV420Planar;
     }