summaryrefslogtreecommitdiffstats
path: root/camera/libcameraservice
diff options
context:
space:
mode:
authorDave Sparks <davidsparks@android.com>2009-11-06 11:47:13 -0800
committerDave Sparks <davidsparks@android.com>2009-11-06 11:47:13 -0800
commitc8093c11286e3c65fb6de686db17b87b0efb1e56 (patch)
tree68f24cfe8ea87bf8b1e228c9b4afab420c8986d5 /camera/libcameraservice
parent8b1243e5e4930598e8e78ebd18e7b6cd6fb0445f (diff)
downloadframeworks_base-c8093c11286e3c65fb6de686db17b87b0efb1e56.zip
frameworks_base-c8093c11286e3c65fb6de686db17b87b0efb1e56.tar.gz
frameworks_base-c8093c11286e3c65fb6de686db17b87b0efb1e56.tar.bz2
Hold a lock while we access the preview heap.
copyFrameAndPostCopiedFrame was not holding a lock while it accessed the preview heap. If the client process is torn down while the heap is accessed, the memcpy could access memory that was deallocated. This patch creates a local sp reference to the preview heap while holding the lock, then releases the lock. This should prevent the heap from being pulled out from underneath us.
Diffstat (limited to 'camera/libcameraservice')
-rw-r--r--camera/libcameraservice/CameraService.cpp21
1 files changed, 14 insertions, 7 deletions
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index 29531ca..e548524 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -1215,20 +1215,27 @@ void CameraService::Client::copyFrameAndPostCopiedFrame(const sp<ICameraClient>&
// the callback. For efficiency, reuse the same MemoryHeapBase
// provided it's big enough. Don't allocate the memory or
// perform the copy if there's no callback.
- if (mPreviewBuffer == 0) {
- mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
- } else if (size > mPreviewBuffer->virtualSize()) {
- mPreviewBuffer.clear();
- mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
+
+ // hold the lock while we grab a reference to the preview buffer
+ sp<MemoryHeapBase> previewBuffer;
+ {
+ Mutex::Autolock lock(mLock);
+ if (mPreviewBuffer == 0) {
+ mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
+ } else if (size > mPreviewBuffer->virtualSize()) {
+ mPreviewBuffer.clear();
+ mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
+ }
if (mPreviewBuffer == 0) {
LOGE("failed to allocate space for preview buffer");
return;
}
+ previewBuffer = mPreviewBuffer;
}
- memcpy(mPreviewBuffer->base(),
+ memcpy(previewBuffer->base(),
(uint8_t *)heap->base() + offset, size);
- sp<MemoryBase> frame = new MemoryBase(mPreviewBuffer, 0, size);
+ sp<MemoryBase> frame = new MemoryBase(previewBuffer, 0, size);
if (frame == 0) {
LOGE("failed to allocate space for frame callback");
return;