summaryrefslogtreecommitdiffstats
path: root/core/java/android/os
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2012-11-15 11:51:49 -0800
committerAndroid Git Automerger <android-git-automerger@android.com>2012-11-15 11:51:49 -0800
commit9077ca586e083fd0e2913c4232915416b3719e7d (patch)
tree4add43aef19536e062171f574c0494eaa4d9d785 /core/java/android/os
parentf838eb40e8f53263c10d251ec4ec72f167f82541 (diff)
parentdcb72dbb39227674e4a54167efabcdc8add4548a (diff)
downloadframeworks_base-9077ca586e083fd0e2913c4232915416b3719e7d.zip
frameworks_base-9077ca586e083fd0e2913c4232915416b3719e7d.tar.gz
frameworks_base-9077ca586e083fd0e2913c4232915416b3719e7d.tar.bz2
am dcb72dbb: am 445767c1: Merge "Watch for leaked ParcelFileDescriptors." into jb-mr1.1-dev
* commit 'dcb72dbb39227674e4a54167efabcdc8add4548a': Watch for leaked ParcelFileDescriptors.
Diffstat (limited to 'core/java/android/os')
-rw-r--r--core/java/android/os/ParcelFileDescriptor.java61
1 files changed, 39 insertions, 22 deletions
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index 3e90dfc..ec660ee 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -15,6 +15,9 @@
*/
package android.os;
+
+import dalvik.system.CloseGuard;
+
import java.io.Closeable;
import java.io.File;
import java.io.FileDescriptor;
@@ -31,12 +34,16 @@ import java.net.Socket;
*/
public class ParcelFileDescriptor implements Parcelable, Closeable {
private final FileDescriptor mFileDescriptor;
- private boolean mClosed;
- //this field is to create wrapper for ParcelFileDescriptor using another
- //PartialFileDescriptor but avoid invoking close twice
- //consider ParcelFileDescriptor A(fileDescriptor fd), ParcelFileDescriptor B(A)
- //in this particular case fd.close might be invoked twice.
- private final ParcelFileDescriptor mParcelDescriptor;
+
+ /**
+ * Wrapped {@link ParcelFileDescriptor}, if any. Used to avoid
+ * double-closing {@link #mFileDescriptor}.
+ */
+ private final ParcelFileDescriptor mWrapped;
+
+ private volatile boolean mClosed;
+
+ private final CloseGuard mGuard = CloseGuard.get();
/**
* For use with {@link #open}: if {@link #MODE_CREATE} has been supplied
@@ -289,13 +296,15 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
if (mClosed) {
throw new IllegalStateException("Already closed");
}
- if (mParcelDescriptor != null) {
- int fd = mParcelDescriptor.detachFd();
+ if (mWrapped != null) {
+ int fd = mWrapped.detachFd();
mClosed = true;
+ mGuard.close();
return fd;
}
int fd = getFd();
mClosed = true;
+ mGuard.close();
Parcel.clearFileDescriptor(mFileDescriptor);
return fd;
}
@@ -307,15 +316,16 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
* @throws IOException
* If an error occurs attempting to close this ParcelFileDescriptor.
*/
+ @Override
public void close() throws IOException {
- synchronized (this) {
- if (mClosed) return;
- mClosed = true;
- }
- if (mParcelDescriptor != null) {
+ if (mClosed) return;
+ mClosed = true;
+ mGuard.close();
+
+ if (mWrapped != null) {
// If this is a proxy to another file descriptor, just call through to its
// close method.
- mParcelDescriptor.close();
+ mWrapped.close();
} else {
Parcel.closeFileDescriptor(mFileDescriptor);
}
@@ -374,6 +384,9 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
@Override
protected void finalize() throws Throwable {
+ if (mGuard != null) {
+ mGuard.warnIfOpen();
+ }
try {
if (!mClosed) {
close();
@@ -384,21 +397,22 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
}
public ParcelFileDescriptor(ParcelFileDescriptor descriptor) {
- super();
- mParcelDescriptor = descriptor;
- mFileDescriptor = mParcelDescriptor.mFileDescriptor;
+ mWrapped = descriptor;
+ mFileDescriptor = mWrapped.mFileDescriptor;
+ mGuard.open("close");
}
- /*package */ParcelFileDescriptor(FileDescriptor descriptor) {
- super();
+ /** {@hide} */
+ public ParcelFileDescriptor(FileDescriptor descriptor) {
if (descriptor == null) {
throw new NullPointerException("descriptor must not be null");
}
+ mWrapped = null;
mFileDescriptor = descriptor;
- mParcelDescriptor = null;
+ mGuard.open("close");
}
- /* Parcelable interface */
+ @Override
public int describeContents() {
return Parcelable.CONTENTS_FILE_DESCRIPTOR;
}
@@ -408,6 +422,7 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
* If {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE} is set in flags,
* the file descriptor will be closed after a copy is written to the Parcel.
*/
+ @Override
public void writeToParcel(Parcel out, int flags) {
out.writeFileDescriptor(mFileDescriptor);
if ((flags&PARCELABLE_WRITE_RETURN_VALUE) != 0 && !mClosed) {
@@ -421,12 +436,14 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
public static final Parcelable.Creator<ParcelFileDescriptor> CREATOR
= new Parcelable.Creator<ParcelFileDescriptor>() {
+ @Override
public ParcelFileDescriptor createFromParcel(Parcel in) {
return in.readFileDescriptor();
}
+
+ @Override
public ParcelFileDescriptor[] newArray(int size) {
return new ParcelFileDescriptor[size];
}
};
-
}