diff options
author | Daisuke Miyakawa <dmiyakawa@google.com> | 2011-02-22 07:54:52 -0800 |
---|---|---|
committer | Daisuke Miyakawa <dmiyakawa@google.com> | 2011-02-23 20:01:16 -0800 |
commit | 91ff68b93f7a623f168697ebdb895daea3542579 (patch) | |
tree | c67d0f19164c94772c7a715993e8ef6ba34d0f12 | |
parent | f98084b727f30713a31ace82e63341a4fa2ae5d7 (diff) | |
download | android_frameworks_opt_vcard-91ff68b93f7a623f168697ebdb895daea3542579.tar.gz android_frameworks_opt_vcard-91ff68b93f7a623f168697ebdb895daea3542579.tar.bz2 android_frameworks_opt_vcard-91ff68b93f7a623f168697ebdb895daea3542579.zip |
Refrain wrong Writer#flush() call.
- We cannot rely on finilizer ordering: FileOutputStream may be
released before HandlerForOutputStream
- Writer#flush() call in finalizer may lock file system for a long time
(10> secs), which will let the VM assume there is deadlock
- Writer#flush() will be called from Writer#close() so we don't need
to call it explicitly.
- There's a race condition between VCardComposer.finalize()
and FileOutputSteram.finalize() since they may be called
concurrently.
- Use CloseGuard for detecting missing terminate() call.
Change-Id: I1ddcaf2c4564476e81dc67d3ec6ec1c947872a84
-rw-r--r-- | java/com/android/vcard/VCardComposer.java | 51 |
1 files changed, 13 insertions, 38 deletions
diff --git a/java/com/android/vcard/VCardComposer.java b/java/com/android/vcard/VCardComposer.java index f7e7d52..87d0313 100644 --- a/java/com/android/vcard/VCardComposer.java +++ b/java/com/android/vcard/VCardComposer.java @@ -17,6 +17,8 @@ package com.android.vcard; import com.android.vcard.exception.VCardException; +import dalvik.system.CloseGuard; + import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; @@ -47,7 +49,6 @@ import android.text.TextUtils; import android.util.Log; import java.io.BufferedWriter; -import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; @@ -165,8 +166,6 @@ public class VCardComposer { @SuppressWarnings("hiding") private static final String LOG_TAG = "VCardComposer.HandlerForOutputStream"; - private boolean mOnTerminateIsCalled = false; - private final OutputStream mOutputStream; // mWriter will close this. private Writer mWriter; @@ -224,41 +223,14 @@ public class VCardComposer { @Override public void onTerminate() { - mOnTerminateIsCalled = true; if (mWriter != null) { try { - // Flush and sync the data so that a user is able to pull - // the SDCard just after - // the export. - mWriter.flush(); - if (mOutputStream != null - && mOutputStream instanceof FileOutputStream) { - ((FileOutputStream) mOutputStream).getFD().sync(); - } + mWriter.close(); } catch (IOException e) { - Log.d(LOG_TAG, - "IOException during closing the output stream: " - + e.getMessage()); - } finally { - closeOutputStream(); + Log.w(LOG_TAG, "IOException is thrown during close(). Ignored.", e); } } } - - public void closeOutputStream() { - try { - mWriter.close(); - } catch (IOException e) { - Log.w(LOG_TAG, "IOException is thrown during close(). Ignoring."); - } - } - - @Override - public void finalize() { - if (!mOnTerminateIsCalled) { - onTerminate(); - } - } } private final Context mContext; @@ -271,11 +243,12 @@ public class VCardComposer { private int mIdColumn; private final String mCharset; - private boolean mTerminateIsCalled; private final List<OneEntryHandler> mHandlerList; private String mErrorReason = NO_ERROR; + private final CloseGuard mGuard = CloseGuard.get(); + private static final String[] sContactsProjection = new String[] { Contacts._ID, }; @@ -464,6 +437,7 @@ public class VCardComposer { mIdColumn = mCursor.getColumnIndex(Contacts._ID); + mGuard.open("terminate"); return true; } @@ -640,14 +614,15 @@ public class VCardComposer { mCursor = null; } - mTerminateIsCalled = true; + mGuard.close(); } @Override - public void finalize() { - if (!mTerminateIsCalled) { - Log.w(LOG_TAG, "terminate() is not called yet. We call it in finalize() step."); - terminate(); + protected void finalize() throws Throwable { + try { + mGuard.warnIfOpen(); + } finally { + super.finalize(); } } |