Skip to content

Commit 445767c

Browse files
jsharkeyAndroid (Google) Code Review
authored andcommitted
Merge "Watch for leaked ParcelFileDescriptors." into jb-mr1.1-dev
2 parents f6ba84b + 7407c94 commit 445767c

File tree

1 file changed

+39
-22
lines changed

1 file changed

+39
-22
lines changed

core/java/android/os/ParcelFileDescriptor.java

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
*/
1616

1717
package android.os;
18+
19+
import dalvik.system.CloseGuard;
20+
1821
import java.io.Closeable;
1922
import java.io.File;
2023
import java.io.FileDescriptor;
@@ -31,12 +34,16 @@
3134
*/
3235
public class ParcelFileDescriptor implements Parcelable, Closeable {
3336
private final FileDescriptor mFileDescriptor;
34-
private boolean mClosed;
35-
//this field is to create wrapper for ParcelFileDescriptor using another
36-
//PartialFileDescriptor but avoid invoking close twice
37-
//consider ParcelFileDescriptor A(fileDescriptor fd), ParcelFileDescriptor B(A)
38-
//in this particular case fd.close might be invoked twice.
39-
private final ParcelFileDescriptor mParcelDescriptor;
37+
38+
/**
39+
* Wrapped {@link ParcelFileDescriptor}, if any. Used to avoid
40+
* double-closing {@link #mFileDescriptor}.
41+
*/
42+
private final ParcelFileDescriptor mWrapped;
43+
44+
private volatile boolean mClosed;
45+
46+
private final CloseGuard mGuard = CloseGuard.get();
4047

4148
/**
4249
* For use with {@link #open}: if {@link #MODE_CREATE} has been supplied
@@ -289,13 +296,15 @@ public int detachFd() {
289296
if (mClosed) {
290297
throw new IllegalStateException("Already closed");
291298
}
292-
if (mParcelDescriptor != null) {
293-
int fd = mParcelDescriptor.detachFd();
299+
if (mWrapped != null) {
300+
int fd = mWrapped.detachFd();
294301
mClosed = true;
302+
mGuard.close();
295303
return fd;
296304
}
297305
int fd = getFd();
298306
mClosed = true;
307+
mGuard.close();
299308
Parcel.clearFileDescriptor(mFileDescriptor);
300309
return fd;
301310
}
@@ -307,15 +316,16 @@ public int detachFd() {
307316
* @throws IOException
308317
* If an error occurs attempting to close this ParcelFileDescriptor.
309318
*/
319+
@Override
310320
public void close() throws IOException {
311-
synchronized (this) {
312-
if (mClosed) return;
313-
mClosed = true;
314-
}
315-
if (mParcelDescriptor != null) {
321+
if (mClosed) return;
322+
mClosed = true;
323+
mGuard.close();
324+
325+
if (mWrapped != null) {
316326
// If this is a proxy to another file descriptor, just call through to its
317327
// close method.
318-
mParcelDescriptor.close();
328+
mWrapped.close();
319329
} else {
320330
Parcel.closeFileDescriptor(mFileDescriptor);
321331
}
@@ -374,6 +384,9 @@ public String toString() {
374384

375385
@Override
376386
protected void finalize() throws Throwable {
387+
if (mGuard != null) {
388+
mGuard.warnIfOpen();
389+
}
377390
try {
378391
if (!mClosed) {
379392
close();
@@ -384,21 +397,22 @@ protected void finalize() throws Throwable {
384397
}
385398

386399
public ParcelFileDescriptor(ParcelFileDescriptor descriptor) {
387-
super();
388-
mParcelDescriptor = descriptor;
389-
mFileDescriptor = mParcelDescriptor.mFileDescriptor;
400+
mWrapped = descriptor;
401+
mFileDescriptor = mWrapped.mFileDescriptor;
402+
mGuard.open("close");
390403
}
391404

392-
/*package */ParcelFileDescriptor(FileDescriptor descriptor) {
393-
super();
405+
/** {@hide} */
406+
public ParcelFileDescriptor(FileDescriptor descriptor) {
394407
if (descriptor == null) {
395408
throw new NullPointerException("descriptor must not be null");
396409
}
410+
mWrapped = null;
397411
mFileDescriptor = descriptor;
398-
mParcelDescriptor = null;
412+
mGuard.open("close");
399413
}
400414

401-
/* Parcelable interface */
415+
@Override
402416
public int describeContents() {
403417
return Parcelable.CONTENTS_FILE_DESCRIPTOR;
404418
}
@@ -408,6 +422,7 @@ public int describeContents() {
408422
* If {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE} is set in flags,
409423
* the file descriptor will be closed after a copy is written to the Parcel.
410424
*/
425+
@Override
411426
public void writeToParcel(Parcel out, int flags) {
412427
out.writeFileDescriptor(mFileDescriptor);
413428
if ((flags&PARCELABLE_WRITE_RETURN_VALUE) != 0 && !mClosed) {
@@ -421,12 +436,14 @@ public void writeToParcel(Parcel out, int flags) {
421436

422437
public static final Parcelable.Creator<ParcelFileDescriptor> CREATOR
423438
= new Parcelable.Creator<ParcelFileDescriptor>() {
439+
@Override
424440
public ParcelFileDescriptor createFromParcel(Parcel in) {
425441
return in.readFileDescriptor();
426442
}
443+
444+
@Override
427445
public ParcelFileDescriptor[] newArray(int size) {
428446
return new ParcelFileDescriptor[size];
429447
}
430448
};
431-
432449
}

0 commit comments

Comments
 (0)