OSDN Git Service

CM File Manager - Make AsyncResultExecutable's cancel() and end() innocuous
[android-x86/packages-apps-CMFileManager.git] / src / com / cyanogenmod / filemanager / commands / java / FindCommand.java
index 2a7ccf5..e4f1b08 100644 (file)
@@ -43,8 +43,8 @@ public class FindCommand extends Program implements FindExecutable {
     private final String[] mQueryRegExp;
     private final ConcurrentAsyncResultListener mAsyncResultListener;
 
-    private boolean mCancelled;
-    private boolean mEnded;
+    private volatile boolean mCancelled;
+    private volatile boolean mEnded;
     private final Object mSync = new Object();
 
     /**
@@ -110,6 +110,15 @@ public class FindCommand extends Program implements FindExecutable {
             findRecursive(f);
         }
 
+        // record program's execution termination
+        synchronized (mSync) {
+            mEnded = true;
+            // account for the delay between the end of findRecursive and setting program
+            // termination flag (mEnded)
+            // notify again in case a thread entered wait state since
+            mSync.notify();
+        }
+
         if (this.mAsyncResultListener != null) {
             this.mAsyncResultListener.onAsyncEnd(this.mCancelled);
         }
@@ -187,8 +196,12 @@ public class FindCommand extends Program implements FindExecutable {
     public boolean cancel() {
         try {
             synchronized (this.mSync) {
-                this.mCancelled = true;
-                this.mSync.wait(5000L);
+                // ensure the program is running before attempting to cancel
+                // there won't be a corresponding lock.notify() otherwise
+                if (!mEnded) {
+                    this.mCancelled = true;
+                    this.mSync.wait(5000L);
+                }
             }
         } catch (Exception e) {/**NON BLOCK**/}
         return true;
@@ -201,8 +214,11 @@ public class FindCommand extends Program implements FindExecutable {
     public boolean end() {
         try {
             synchronized (this.mSync) {
-                this.mEnded = true;
-                this.mSync.wait(5000L);
+                // ensure the program is running before attempting to terminate
+                if (!mEnded) {
+                    this.mEnded = true;
+                    this.mSync.wait(5000L);
+                }
             }
         } catch (Exception e) {/**NON BLOCK**/}
         return true;