Skip to content

Commit

Permalink
Simplify Tox threading
Browse files Browse the repository at this point in the history
A lot of this wasn't needed. Turns out jvm-toxcore-c is thread-safe
already.
  • Loading branch information
robinlinden committed May 20, 2021
1 parent 83e9423 commit f5cfb52
Show file tree
Hide file tree
Showing 9 changed files with 38 additions and 57 deletions.
5 changes: 1 addition & 4 deletions atox/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,7 @@ android {
}
kotlinOptions {
jvmTarget = Java.version.toString()
freeCompilerArgs = listOf(
"-XXLanguage:+InlineClasses",
"-Xuse-experimental=kotlinx.coroutines.ObsoleteCoroutinesApi"
)
freeCompilerArgs = listOf("-XXLanguage:+InlineClasses")
}
lintOptions {
disable("GoogleAppIndexingWarning", "MissingTranslation", "InvalidPackage")
Expand Down
2 changes: 1 addition & 1 deletion atox/src/main/kotlin/AutoAway.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class AutoAway @Inject constructor(
Log.i(TAG, "In background, scheduling away")
awayTimer.schedule(settings.autoAwaySeconds * 1_000) {
GlobalScope.launch {
if (tox.getStatus().await() != UserStatus.None) return@launch
if (tox.getStatus() != UserStatus.None) return@launch
Log.i(TAG, "Setting away")
userManager.setStatus(UserStatus.Away)
autoAway = true
Expand Down
8 changes: 2 additions & 6 deletions atox/src/main/kotlin/ReplyReceiver.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import android.content.Context
import android.content.Intent
import androidx.core.app.RemoteInput
import javax.inject.Inject
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import ltd.evilcorp.atox.ui.NotificationHelper
import ltd.evilcorp.core.vo.Contact
import ltd.evilcorp.domain.feature.ChatManager
Expand All @@ -31,9 +29,7 @@ class ReplyReceiver : BroadcastReceiver() {
val results = RemoteInput.getResultsFromIntent(intent) ?: return
val input = results.getCharSequence(KEY_TEXT_REPLY)?.toString() ?: return
val pk = intent.getStringExtra(KEY_CONTACT_PK) ?: return
GlobalScope.launch {
chatManager.sendMessage(PublicKey(pk), input)
notificationHelper.showMessageNotification(Contact(pk, tox.getName().await()), input, outgoing = true)
}
chatManager.sendMessage(PublicKey(pk), input)
notificationHelper.showMessageNotification(Contact(pk, tox.getName()), input, outgoing = true)
}
}
3 changes: 1 addition & 2 deletions atox/src/main/kotlin/ui/contactlist/ContactListViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,7 @@ class ContactListViewModel @Inject constructor(
// Export the save.
resolver.openFileDescriptor(uri, "w")!!.use { fd ->
FileOutputStream(fd.fileDescriptor).use { out ->
val saveData = tox.getSaveData().await()
out.write(saveData)
out.write(tox.getSaveData())
}
}

Expand Down
5 changes: 1 addition & 4 deletions domain/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,7 @@ android {
}
kotlinOptions {
jvmTarget = Java.version.toString()
freeCompilerArgs = listOf(
"-XXLanguage:+InlineClasses",
"-Xuse-experimental=kotlinx.coroutines.ObsoleteCoroutinesApi"
)
freeCompilerArgs = listOf("-XXLanguage:+InlineClasses")
}
lintOptions {
disable("InvalidPackage") // tox4j is still not really allowed on Android. :/
Expand Down
8 changes: 4 additions & 4 deletions domain/src/main/kotlin/feature/ChatManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class ChatManager @Inject constructor(

val msgs = message.chunked(MAX_MESSAGE_LENGTH)
while (msgs.size > 1) {
tox.sendMessage(publicKey, msgs.removeFirst(), type).start()
tox.sendMessage(publicKey, msgs.removeFirst(), type)
}

messageRepository.add(
Expand All @@ -71,7 +71,7 @@ class ChatManager @Inject constructor(
message,
Sender.Sent,
type,
tox.sendMessage(publicKey, msgs.first(), type).await()
tox.sendMessage(publicKey, msgs.first(), type),
)
)
}
Expand All @@ -84,12 +84,12 @@ class ChatManager @Inject constructor(
val msgs = message.message.chunked(MAX_MESSAGE_LENGTH)

while (msgs.size > 1) {
tox.sendMessage(PublicKey(message.publicKey), msgs.removeFirst(), message.type).start()
tox.sendMessage(PublicKey(message.publicKey), msgs.removeFirst(), message.type)
}

messageRepository.setCorrelationId(
message.id,
tox.sendMessage(PublicKey(message.publicKey), msgs.first(), message.type).await()
tox.sendMessage(PublicKey(message.publicKey), msgs.first(), message.type),
)
}
}
Expand Down
2 changes: 1 addition & 1 deletion domain/src/main/kotlin/feature/FileTransferManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ class FileTransferManager @Inject constructor(

val ft = FileTransfer(
pk.string(),
tox.sendFile(pk, FileKind.Data, size, name).await(),
tox.sendFile(pk, FileKind.Data, size, name),
FileKind.Data.ordinal,
size,
name,
Expand Down
4 changes: 2 additions & 2 deletions domain/src/main/kotlin/feature/UserManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ class UserManager @Inject constructor(

fun verifyExists(publicKey: PublicKey) = launch {
if (!userRepository.exists(publicKey.string())) {
val name = tox.getName().await()
val statusMessage = tox.getStatusMessage().await()
val name = tox.getName()
val statusMessage = tox.getStatusMessage()
val user = User(publicKey.string(), name, statusMessage)
userRepository.add(user)
}
Expand Down
58 changes: 25 additions & 33 deletions domain/src/main/kotlin/tox/Tox.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,10 @@ import javax.inject.Inject
import javax.inject.Singleton
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.ObsoleteCoroutinesApi
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.newSingleThreadContext
import kotlinx.coroutines.plus
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import ltd.evilcorp.core.repository.ContactRepository
import ltd.evilcorp.core.repository.UserRepository
import ltd.evilcorp.core.vo.ConnectionStatus
Expand All @@ -23,14 +20,13 @@ import ltd.evilcorp.core.vo.UserStatus

private const val TAG = "Tox"

@ObsoleteCoroutinesApi
@Singleton
class Tox @Inject constructor(
private val contactRepository: ContactRepository,
private val userRepository: UserRepository,
private val saveManager: SaveManager,
private val nodeRegistry: BootstrapNodeRegistry,
) : CoroutineScope by GlobalScope + newSingleThreadContext("Tox") {
) : CoroutineScope by GlobalScope {
val toxId: ToxID get() = tox.getToxId()
val publicKey: PublicKey by lazy { tox.getPublicKey() }
var nospam: Int
Expand Down Expand Up @@ -95,66 +91,64 @@ class Tox @Inject constructor(
fun stop() = launch {
running = false
while (started) delay(10)
save()
save().join()
tox.stop()
}

private fun save() = runBlocking {
saveManager.save(publicKey, tox.getSaveData())
private val saveMutex = Mutex()
private fun save() = launch {
saveMutex.withLock {
saveManager.save(publicKey, tox.getSaveData())
}
}

fun acceptFriendRequest(publicKey: PublicKey) = launch {
fun acceptFriendRequest(publicKey: PublicKey) {
tox.acceptFriendRequest(publicKey)
save()
}

fun startFileTransfer(pk: PublicKey, fileNumber: Int) = launch {
fun startFileTransfer(pk: PublicKey, fileNumber: Int) {
Log.i(TAG, "Starting file transfer $fileNumber from ${pk.fingerprint()}")
tox.startFileTransfer(pk, fileNumber)
}

fun stopFileTransfer(pk: PublicKey, fileNumber: Int) = launch {
fun stopFileTransfer(pk: PublicKey, fileNumber: Int) {
Log.i(TAG, "Stopping file transfer $fileNumber from ${pk.fingerprint()}")
tox.stopFileTransfer(pk, fileNumber)
}

fun sendFile(pk: PublicKey, fileKind: FileKind, fileSize: Long, fileName: String) = async {
fun sendFile(pk: PublicKey, fileKind: FileKind, fileSize: Long, fileName: String) =
tox.sendFile(pk, fileKind, fileSize, fileName)
}

fun sendFileChunk(pk: PublicKey, fileNo: Int, pos: Long, data: ByteArray) = launch {
fun sendFileChunk(pk: PublicKey, fileNo: Int, pos: Long, data: ByteArray) =
tox.sendFileChunk(pk, fileNo, pos, data)
}

fun getName() = async { tox.getName() }
fun setName(name: String) = launch {
fun getName() = tox.getName()
fun setName(name: String) {
tox.setName(name)
save()
}

fun getStatusMessage() = async { tox.getStatusMessage() }
fun setStatusMessage(statusMessage: String) = launch {
fun getStatusMessage() = tox.getStatusMessage()
fun setStatusMessage(statusMessage: String) {
tox.setStatusMessage(statusMessage)
save()
}

fun addContact(toxId: ToxID, message: String) = launch {
fun addContact(toxId: ToxID, message: String) {
tox.addContact(toxId, message)
save()
}

fun deleteContact(publicKey: PublicKey) = launch {
fun deleteContact(publicKey: PublicKey) {
tox.deleteContact(publicKey)
save()
}

fun sendMessage(publicKey: PublicKey, message: String, type: MessageType) = async {
fun sendMessage(publicKey: PublicKey, message: String, type: MessageType) =
tox.sendMessage(publicKey, message, type)
}

fun getSaveData() = async {
tox.getSaveData()
}
fun getSaveData() = tox.getSaveData()

private fun bootstrap() {
nodeRegistry.get(4).forEach { node ->
Expand All @@ -163,12 +157,10 @@ class Tox @Inject constructor(
}
}

fun setTyping(publicKey: PublicKey, typing: Boolean) = launch {
tox.setTyping(publicKey, typing)
}
fun setTyping(publicKey: PublicKey, typing: Boolean) = tox.setTyping(publicKey, typing)

fun setStatus(status: UserStatus) = launch { tox.setStatus(status) }
fun getStatus() = async { tox.getStatus() }
fun setStatus(status: UserStatus) = tox.setStatus(status)
fun getStatus() = tox.getStatus()

// ToxAv, probably move these.
fun startCall(pk: PublicKey) = tox.startCall(pk)
Expand Down

0 comments on commit f5cfb52

Please sign in to comment.