Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ open class EventProducer<THandler> : IEventNotifier<THandler> {
* @param callback The callback will be invoked for each subscribed handler, allowing you to call the handler.
*/
fun fire(callback: (THandler) -> Unit) {
val localList = subscribers.toList()
val localList = synchronized(subscribers) { subscribers.toList() }
for (s in localList) {
callback(s)
}
Expand All @@ -60,7 +60,7 @@ open class EventProducer<THandler> : IEventNotifier<THandler> {
*/
fun fireOnMain(callback: (THandler) -> Unit) {
suspendifyOnMain {
val localList = subscribers.toList()
val localList = synchronized(subscribers) { subscribers.toList() }
for (s in localList) {
callback(s)
}
Expand All @@ -74,7 +74,7 @@ open class EventProducer<THandler> : IEventNotifier<THandler> {
* @param callback The callback will be invoked for each subscribed handler, allowing you to call the handler.
*/
suspend fun suspendingFire(callback: suspend (THandler) -> Unit) {
val localList = subscribers.toList()
val localList = synchronized(subscribers) { subscribers.toList() }
for (s in localList) {
callback(s)
}
Expand All @@ -88,7 +88,7 @@ open class EventProducer<THandler> : IEventNotifier<THandler> {
*/
suspend fun suspendingFireOnMain(callback: suspend (THandler) -> Unit) {
withContext(Dispatchers.Main) {
val localList = subscribers.toList()
val localList = synchronized(subscribers) { subscribers.toList() }
for (s in localList) {
callback(s)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.onesignal.common

import com.onesignal.common.events.EventProducer
import io.kotest.core.spec.style.FunSpec
import kotlin.concurrent.thread

class EventProducerTest : FunSpec({

fun modifyingSubscribersThread(eventProducer: EventProducer<Boolean>): Thread {
return thread(start = true) {
repeat(10_000) {
eventProducer.subscribe(true)
eventProducer.unsubscribe(true)
}
}
}

test("fire is thread safe") {
val eventProducer = EventProducer<Boolean>()
val modifyingSubscribersThread = modifyingSubscribersThread(eventProducer)

repeat(10_000) {
eventProducer.fire { }
}

modifyingSubscribersThread.join()
}

test("suspendingFire is thread safe") {
val eventProducer = EventProducer<Boolean>()
val modifyingSubscribersThread = modifyingSubscribersThread(eventProducer)

repeat(10_000) {
eventProducer.suspendingFire { }
}

modifyingSubscribersThread.join()
}

test("hasSubscribers is thread safe") {
val eventProducer = EventProducer<Boolean>()
val modifyingSubscribersThread = modifyingSubscribersThread(eventProducer)

repeat(10_000) {
eventProducer.hasSubscribers
}

modifyingSubscribersThread.join()
}
})