diff options
author | Wei-Ta Chen <weita@google.com> | 2010-08-18 15:40:29 +0800 |
---|---|---|
committer | Wei-Ta Chen <weita@google.com> | 2010-08-19 12:21:44 +0800 |
commit | 291303ba3dbb3a0173bcc82ded595ca75df7b50e (patch) | |
tree | 8df16ec637091c70ce3622e2cfeeaf15f8793afc /core/jni/android/graphics | |
parent | 6ab94608750776bcaaee56696cfcfb16ce29db8a (diff) | |
download | frameworks_base-291303ba3dbb3a0173bcc82ded595ca75df7b50e.zip frameworks_base-291303ba3dbb3a0173bcc82ded595ca75df7b50e.tar.gz frameworks_base-291303ba3dbb3a0173bcc82ded595ca75df7b50e.tar.bz2 |
Fix a bug, where one thread is using JNIEnv associated with another thread.
We see abort messages like this when using JavaPixelAllocator and JavaMemoryUsageReporter.
W/dalvikvm( 680): JNI WARNING: threadid=2 using env from threadid=10
W/dalvikvm( 680): in Landroid/graphics/LargeBitmap;.nativeClean (I)V (CallVoidMethodV)
To fix it, we keep JavaVM, rather than JNIEnv, in JavaPixelAllocator and JavaMemoryUsageReporter,
because JavaVM allows us to get the JNIEnv corresponds to the current thread.
Change-Id: Ibd4b394a53dd3fdccc5a442eeb0dedf836479575
Diffstat (limited to 'core/jni/android/graphics')
-rw-r--r-- | core/jni/android/graphics/Graphics.cpp | 27 | ||||
-rw-r--r-- | core/jni/android/graphics/GraphicsJNI.h | 4 |
2 files changed, 22 insertions, 9 deletions
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp index 204bb74..578de6f 100644 --- a/core/jni/android/graphics/Graphics.cpp +++ b/core/jni/android/graphics/Graphics.cpp @@ -518,35 +518,48 @@ bool GraphicsJNI::setJavaPixelRef(JNIEnv* env, SkBitmap* bitmap, /////////////////////////////////////////////////////////////////////////////// JavaPixelAllocator::JavaPixelAllocator(JNIEnv* env, bool reportSizeToVM) - : fEnv(env), fReportSizeToVM(reportSizeToVM) {} + : fReportSizeToVM(reportSizeToVM) { + if (env->GetJavaVM(&fVM) != JNI_OK) { + SkDebugf("------ [%p] env->GetJavaVM failed\n", env); + sk_throw(); + } +} bool JavaPixelAllocator::allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) { - return GraphicsJNI::setJavaPixelRef(fEnv, bitmap, ctable, fReportSizeToVM); + JNIEnv* env = vm2env(fVM); + return GraphicsJNI::setJavaPixelRef(env, bitmap, ctable, fReportSizeToVM); } //////////////////////////////////////////////////////////////////////////////// JavaMemoryUsageReporter::JavaMemoryUsageReporter(JNIEnv* env) - : fEnv(env), fTotalSize(0) {} + : fTotalSize(0) { + if (env->GetJavaVM(&fVM) != JNI_OK) { + SkDebugf("------ [%p] env->GetJavaVM failed\n", env); + sk_throw(); + } +} JavaMemoryUsageReporter::~JavaMemoryUsageReporter() { + JNIEnv* env = vm2env(fVM); jlong jtotalSize = fTotalSize; - fEnv->CallVoidMethod(gVMRuntime_singleton, + env->CallVoidMethod(gVMRuntime_singleton, gVMRuntime_trackExternalFreeMethodID, jtotalSize); } bool JavaMemoryUsageReporter::reportMemory(size_t memorySize) { jlong jsize = memorySize; // the VM wants longs for the size - bool r = fEnv->CallBooleanMethod(gVMRuntime_singleton, + JNIEnv* env = vm2env(fVM); + bool r = env->CallBooleanMethod(gVMRuntime_singleton, gVMRuntime_trackExternalAllocationMethodID, jsize); - if (GraphicsJNI::hasException(fEnv)) { + if (GraphicsJNI::hasException(env)) { return false; } if (!r) { LOGE("VM won't let us allocate %zd bytes\n", memorySize); - doThrowOOME(fEnv, "bitmap size exceeds VM budget"); + doThrowOOME(env, "bitmap size exceeds VM budget"); return false; } fTotalSize += memorySize; diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h index 8d6528b..1a43a3e 100644 --- a/core/jni/android/graphics/GraphicsJNI.h +++ b/core/jni/android/graphics/GraphicsJNI.h @@ -80,7 +80,7 @@ public: virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable); private: - JNIEnv* fEnv; + JavaVM* fVM; bool fReportSizeToVM; }; @@ -92,7 +92,7 @@ public: virtual bool reportMemory(size_t memorySize); private: - JNIEnv* fEnv; + JavaVM* fVM; size_t fTotalSize; }; |