Merge "Fix deadlock in SF." into jb-mr1-dev
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index 0a83ce6..98741c5 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -248,7 +248,7 @@
     // slot and destroy the EGLImage in that slot.  Otherwise it has no effect.
     //
     // This method must be called with mMutex locked.
-    void freeBufferLocked(int slotIndex);
+    virtual void freeBufferLocked(int slotIndex);
 
     // computeCurrentTransformMatrix computes the transform matrix for the
     // current texture.  It uses mCurrentTransform and the current GraphicBuffer
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 451ccc2..0579a3d 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -710,6 +710,7 @@
         eglDestroyImageKHR(mEglDisplay, img);
     }
     mEglSlots[slotIndex].mEglImage = EGL_NO_IMAGE_KHR;
+    ConsumerBase::freeBufferLocked(slotIndex);
 }
 
 void SurfaceTexture::abandonLocked() {
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index 718fe84..18a0c10 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -815,12 +815,16 @@
         ALOGW_IF(res, "failed locking buffer (handle = %p)",
                 backBuffer->handle);
 
-        mLockedBuffer = backBuffer;
-        outBuffer->width  = backBuffer->width;
-        outBuffer->height = backBuffer->height;
-        outBuffer->stride = backBuffer->stride;
-        outBuffer->format = backBuffer->format;
-        outBuffer->bits   = vaddr;
+        if (res != 0) {
+            err = INVALID_OPERATION;
+        } else {
+            mLockedBuffer = backBuffer;
+            outBuffer->width  = backBuffer->width;
+            outBuffer->height = backBuffer->height;
+            outBuffer->stride = backBuffer->stride;
+            outBuffer->format = backBuffer->format;
+            outBuffer->bits   = vaddr;
+        }
     }
     return err;
 }
diff --git a/opengl/libs/EGL/egl_cache.cpp b/opengl/libs/EGL/egl_cache.cpp
index c79fb5f..ed2bef3 100644
--- a/opengl/libs/EGL/egl_cache.cpp
+++ b/opengl/libs/EGL/egl_cache.cpp
@@ -241,19 +241,11 @@
         }
 
         size_t fileSize = headerSize + cacheSize;
-        if (ftruncate(fd, fileSize) == -1) {
-            ALOGE("error setting cache file size: %s (%d)", strerror(errno),
-                    errno);
-            close(fd);
-            unlink(fname);
-            return;
-        }
 
-        uint8_t* buf = reinterpret_cast<uint8_t*>(mmap(NULL, fileSize,
-                PROT_WRITE, MAP_SHARED, fd, 0));
-        if (buf == MAP_FAILED) {
-            ALOGE("error mmaping cache file: %s (%d)", strerror(errno),
-                    errno);
+        uint8_t* buf = new uint8_t [fileSize];
+        if (!buf) {
+            ALOGE("error allocating buffer for cache contents: %s (%d)",
+                    strerror(errno), errno);
             close(fd);
             unlink(fname);
             return;
@@ -264,7 +256,7 @@
         if (err != OK) {
             ALOGE("error writing cache contents: %s (%d)", strerror(-err),
                     -err);
-            munmap(buf, fileSize);
+            delete [] buf;
             close(fd);
             unlink(fname);
             return;
@@ -275,7 +267,16 @@
         uint32_t* crc = reinterpret_cast<uint32_t*>(buf + 4);
         *crc = crc32c(buf + headerSize, cacheSize);
 
-        munmap(buf, fileSize);
+        if (write(fd, buf, fileSize) == -1) {
+            ALOGE("error writing cache file: %s (%d)", strerror(errno),
+                    errno);
+            delete [] buf;
+            close(fd);
+            unlink(fname);
+            return;
+        }
+
+        delete [] buf;
         fchmod(fd, S_IRUSR);
         close(fd);
     }