diff --git a/android/app/src/main/java/com/ts3client/android/ServerController.kt b/android/app/src/main/java/com/ts3client/android/ServerController.kt index edbc870..cc83b2e 100644 --- a/android/app/src/main/java/com/ts3client/android/ServerController.kt +++ b/android/app/src/main/java/com/ts3client/android/ServerController.kt @@ -117,11 +117,10 @@ class ServerController internal constructor( session.disconnect() } - /** Leaves the server before returning, for when the app goes away with the connection. */ - internal fun leave() { + /** Before the app goes away with the connection, which [SessionController.leave] then ends. */ + internal fun leaving() { left = true network.leaving() - session.shutdown() } internal fun dispose() { diff --git a/android/app/src/main/java/com/ts3client/android/SessionController.kt b/android/app/src/main/java/com/ts3client/android/SessionController.kt index 6730dd7..a15dedb 100644 --- a/android/app/src/main/java/com/ts3client/android/SessionController.kt +++ b/android/app/src/main/java/com/ts3client/android/SessionController.kt @@ -21,6 +21,7 @@ import com.ts3client.myts.MyTeamSpeak import com.ts3client.net.HostButton import com.ts3client.myts.MyTeamSpeakLogin import com.ts3client.session.SelfState +import com.ts3client.session.ServerSession import com.ts3client.session.Sessions import com.ts3client.sound.SoundNotifier import com.ts3client.sound.SoundPack @@ -199,7 +200,9 @@ class SessionController(private val context: Context) { /** Leaves every server before returning, for when the app goes away with the connections. */ fun leave() { - _servers.value.forEach(ServerController::leave) + val servers = _servers.value + servers.forEach(ServerController::leaving) + ServerSession.shutdownAll(servers.map { it.session }) contactStore.flush() } diff --git a/ts3-client/core/src/main/java/com/ts3client/session/ServerSession.java b/ts3-client/core/src/main/java/com/ts3client/session/ServerSession.java index 7643a76..9fcc174 100644 --- a/ts3-client/core/src/main/java/com/ts3client/session/ServerSession.java +++ b/ts3-client/core/src/main/java/com/ts3client/session/ServerSession.java @@ -208,6 +208,27 @@ public final class ServerSession { if (isBusy()) conn.disconnectBlocking("Leaving"); } + /** + * {@link #shutdown()}s every session at once, so leaving takes as long as the slowest + * server rather than all of them together: a frontend may have little time left. + */ + public static void shutdownAll(List sessions) { + List leaving = new ArrayList<>(); + for (ServerSession s : sessions) { + Thread t = new Thread(s::shutdown, "ts3-leave"); + t.start(); + leaving.add(t); + } + for (Thread t : leaving) { + try { + t.join(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return; + } + } + } + /** Releases the background resources of a session that is being thrown away. */ public void dispose() { conn.getIcons().shutdown(); diff --git a/ts3-client/core/src/main/java/com/ts3client/session/Sessions.java b/ts3-client/core/src/main/java/com/ts3client/session/Sessions.java index 745c7ef..ddbd700 100644 --- a/ts3-client/core/src/main/java/com/ts3client/session/Sessions.java +++ b/ts3-client/core/src/main/java/com/ts3client/session/Sessions.java @@ -153,7 +153,7 @@ public final class Sessions { /** Leaves every server, waiting until each has been told. */ public void shutdown() { - for (ServerSession s : new ArrayList<>(sessions)) s.shutdown(); + ServerSession.shutdownAll(new ArrayList<>(sessions)); handover.shutdown(); } }