Fix thread race caused double free issue.

The SharedZip's Asset is not thread-safety,the getResourceTableAsset()
and setResourceTableAsset(Asset* asset) function of the SharedZip is
not sync with a same lock.

Consider the following sequence of events:
Thread A calls setResourceTableAsset(Asset* asset),it will set
mResourceTableAsset = asset; then to calls getBuffer() of the asset.
Thread B calls getResourceTableAsset(),which return mResourceTableAsset,
then to calls getBuffer() of the mResourceTableAsset,the asset and
mResourceTableAsset is same one object.
Thread A to delete mZipInflater in getBuffer().
Thread B to delete mZipInflater in getBuffer().

It will cause crash becuase double delete mZipInflater in getBuffer().

Change-Id: I5a7d67fdf64c4aa03f505b37a2fa840f4443d158
Signed-off-by: songjinshi <>
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index f50cff4..8ea25d6 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -1892,6 +1892,7 @@
 Asset* AssetManager::SharedZip::getResourceTableAsset()
+    AutoMutex _l(gLock);
     ALOGV("Getting from SharedZip %p resource asset %p\n", this, mResourceTableAsset);
     return mResourceTableAsset;
@@ -1901,10 +1902,10 @@
         AutoMutex _l(gLock);
         if (mResourceTableAsset == NULL) {
-            mResourceTableAsset = asset;
             // This is not thread safe the first time it is called, so
             // do it here with the global lock held.
+            mResourceTableAsset = asset;
             return asset;