/soc/2012/michael/android: 83adcb3b61b5: Fixed event loop synchr...

Michael Zangl michael at soc.pidgin.im
Sat Jul 7 13:00:48 EDT 2012


Changeset: 83adcb3b61b5c7833ebfd302951e9f044774f3c1
Author:	 Michael Zangl <michael at soc.pidgin.im>
Date:	 2012-07-07 18:59 +0200
Branch:	 soc.2012.android
URL: http://hg.pidgin.im/soc/2012/michael/android/rev/83adcb3b61b5

Description:

Fixed event loop synchronisation, so that account name is set before setName returns (same for setAlias, ...).

diffstat:

 android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/account/PurpleAccount.java                |  16 ++--
 android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/account/PurpleAccountManager.java         |  34 +++++++--
 android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/EventLoop.java                       |   5 +-
 android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/thread/AbstractWaitableRunnable.java |  12 +++
 android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/thread/PurpleThread.java             |  22 ++++++
 5 files changed, 73 insertions(+), 16 deletions(-)

diffs (177 lines):

diff --git a/android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/account/PurpleAccount.java b/android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/account/PurpleAccount.java
--- a/android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/account/PurpleAccount.java
+++ b/android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/account/PurpleAccount.java
@@ -106,7 +106,7 @@
 	 *            The Password or null to reset the password.
 	 */
 	public void setPassword(final String password) {
-		getManager().getThread().schedule(new AbstractWaitableRunnable() {
+		getManager().getThread().scheduleAndWaitForUninterruptable(new AbstractWaitableRunnable() {
 			@Override
 			protected void execute() {
 				setPassword_native(password);
@@ -135,7 +135,7 @@
 	 *            true if libpurple should store the password
 	 */
 	public void setRememberPassword(final boolean remember) {
-		getManager().getThread().schedule(new AbstractWaitableRunnable() {
+		getManager().getThread().scheduleAndWaitForUninterruptable(new AbstractWaitableRunnable() {
 			@Override
 			protected void execute() {
 				setRememberPassword_native(remember);
@@ -184,12 +184,12 @@
 	 *            The new enabled state of the account
 	 */
 	public void setEnabled(final boolean enabled) {
-		getManager().getThread().schedule(new AbstractWaitableRunnable() {
-			@Override
-			protected void execute() {
-				setEnabled_native(enabled);
-			}
-		});
+			getManager().getThread().scheduleAndWaitForUninterruptable(new AbstractWaitableRunnable() {
+				@Override
+				protected void execute() {
+					setEnabled_native(enabled);
+				}
+			});
 		notifyStatusChanged();
 	}
 
diff --git a/android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/account/PurpleAccountManager.java b/android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/account/PurpleAccountManager.java
--- a/android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/account/PurpleAccountManager.java
+++ b/android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/account/PurpleAccountManager.java
@@ -2,6 +2,7 @@
 
 import im.pidgin.libpurple.core.AbstractPurpleManaged;
 import im.pidgin.libpurple.core.CoreManager;
+import im.pidgin.libpurple.core.thread.AbstractWaitableRunnable;
 import im.pidgin.libpurple.glib.GList;
 import im.pidgin.libpurple.peering.PeerGenerator;
 import im.pidgin.libpurple.plugin.PurpleProtocolPlugin;
@@ -21,6 +22,27 @@
 public final class PurpleAccountManager extends AbstractPurpleManaged implements
 		PurpleAccountList, PeerGenerator<PurpleAccount> {
 
+	private final class AddAccountExecutor extends
+			AbstractWaitableRunnable {
+		private final PurpleProtocolPlugin protocol;
+		private final String username;
+		PurpleAccount account;
+
+		private AddAccountExecutor(
+				PurpleProtocolPlugin protocol, String username) {
+			this.protocol = protocol;
+			this.username = username;
+		}
+
+		@Override
+		protected void execute() {
+			account = PurpleAccount.newAccount(getManager(),
+					username, protocol);
+			knownAccounts.put(account.getNativePointer(), account);
+			addAccount_native(account.getNativePointer());
+		}
+	}
+
 	private final LinkedList<PurpleAccountListListener> listeners = new LinkedList<PurpleAccountListListener>();
 
 	private final AccountListenerList accountListeners = new AccountListenerList();
@@ -141,13 +163,11 @@
 	}
 
 	@Override
-	public PurpleAccount addAccount(String username,
-			PurpleProtocolPlugin protocol) {
-		PurpleAccount account = PurpleAccount.newAccount(getManager(),
-				username, protocol);
-		knownAccounts.put(account.getNativePointer(), account);
-		addAccount_native(account.getNativePointer());
-		return account;
+	public PurpleAccount addAccount(final String username,
+			final PurpleProtocolPlugin protocol) {
+		AddAccountExecutor runnable = new AddAccountExecutor(protocol, username);
+		getManager().getThread().scheduleAndWaitForUninterruptable(runnable);
+		return runnable.account;
 	}
 
 	/**
diff --git a/android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/EventLoop.java b/android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/EventLoop.java
--- a/android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/EventLoop.java
+++ b/android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/EventLoop.java
@@ -129,9 +129,12 @@
 			if (!doContinue) {
 				cancel();
 			}
+		}
+
+		@Override
+		protected void executionFinished() {
 			markForReuse();
 		}
-
 	}
 
 	private native boolean exeucte_native(long function, long data);
diff --git a/android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/thread/AbstractWaitableRunnable.java b/android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/thread/AbstractWaitableRunnable.java
--- a/android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/thread/AbstractWaitableRunnable.java
+++ b/android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/thread/AbstractWaitableRunnable.java
@@ -19,6 +19,14 @@
 			mutex.notifyAll();
 			wasRun = true;
 		}
+		executionFinished();
+	}
+
+	/**
+	 * Called after the execution was terminated and the wasRun flag is set, but
+	 * there may be wasFinished calls active. You may call markForReuse here.
+	 */
+	protected void executionFinished() {
 	}
 
 	protected abstract void execute();;
@@ -38,6 +46,10 @@
 		}
 	}
 
+	/**
+	 * Waits until all waiting threads have been notified that this task was
+	 * finished and marks this runnable as not run.
+	 */
 	protected void markForReuse() {
 		synchronized (mutex) {
 			while (waitForRunning > 0) {
diff --git a/android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/thread/PurpleThread.java b/android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/thread/PurpleThread.java
--- a/android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/thread/PurpleThread.java
+++ b/android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/thread/PurpleThread.java
@@ -83,7 +83,29 @@
 
 	public void scheduleAndWaitFor(Runnable r) throws InterruptedException {
 		WaitableRunnableRunner waitable = new WaitableRunnableRunner(r);
+		scheduleAndWaitFor(waitable);
+	}
+
+	public void scheduleAndWaitFor(WaitableRunnable waitable)
+			throws InterruptedException {
 		schedule(waitable);
 		waitable.waitFor();
 	}
+
+	public void scheduleAndWaitForUninterruptable(WaitableRunnable r) {
+		WaitableRunnableRunner waitable = new WaitableRunnableRunner(r);
+		scheduleAndWaitForUninterruptable(waitable);
+	}
+
+	private void scheduleAndWaitForUninterruptable(WaitableRunnableRunner waitable) {
+		schedule(waitable);
+		boolean finished = false;
+		while (!finished) {
+			try {
+				waitable.waitFor();
+				finished = true;
+			} catch (InterruptedException e) {
+			}
+		}
+	}
 }



More information about the Commits mailing list