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 @@ -8,25 +8,26 @@ namespace AlphaTab.Platform.CSharp;
internal abstract class ManagedThreadWorkerBase<T> : IAlphaTabWorker<T>
{
private readonly Action<Action> _postToMain;
private readonly Thread _workerThread;
private readonly BlockingCollection<Action> _workerQueue;
private readonly CancellationTokenSource _workerCancellationToken;
private readonly ManualResetEventSlim? _threadStartedEvent;
private readonly ConcurrentDictionary<Action<MessageEvent<T>>,Action<MessageEvent<T>>> _listenerInsideWorker = new();
private readonly ConcurrentDictionary<Action<MessageEvent<T>>,Action<MessageEvent<T>>> _listenerOutsideWorker = new();

protected Thread WorkerThread { get; }

protected ManagedThreadWorkerBase(Action<Action> postToMain)
{
_postToMain = postToMain;
_threadStartedEvent = new ManualResetEventSlim(false);
_workerQueue = new BlockingCollection<Action>();
_workerCancellationToken = new CancellationTokenSource();

_workerThread = new Thread(DoWork)
WorkerThread = new Thread(DoWork)
{
IsBackground = true
};
_workerThread.Start();
WorkerThread.Start();

_threadStartedEvent.Wait();
_threadStartedEvent.Dispose();
Expand Down Expand Up @@ -55,7 +56,7 @@ private void DoWork()
public void PostMessage(T message)
{
var ev = new MessageEvent<T>(message);
if (Thread.CurrentThread.ManagedThreadId == _workerThread.ManagedThreadId)
if (Thread.CurrentThread.ManagedThreadId == WorkerThread.ManagedThreadId)
{
// Inside Worker -> Post to main
_postToMain(() =>
Expand Down Expand Up @@ -87,7 +88,7 @@ public void PostToWorker(Action action)
public void AddEventListener(string @event, Action<MessageEvent<T>> handler)
{
if (@event != "message") return;
var listeners = Thread.CurrentThread.ManagedThreadId == _workerThread.ManagedThreadId
var listeners = Thread.CurrentThread.ManagedThreadId == WorkerThread.ManagedThreadId
? _listenerInsideWorker
: _listenerOutsideWorker;
listeners[handler] = handler;
Expand All @@ -96,7 +97,7 @@ public void AddEventListener(string @event, Action<MessageEvent<T>> handler)
public void RemoveEventListener(string @event, Action<MessageEvent<T>> handler)
{
if (@event != "message") return;
var listeners = Thread.CurrentThread.ManagedThreadId == _workerThread.ManagedThreadId
var listeners = Thread.CurrentThread.ManagedThreadId == WorkerThread.ManagedThreadId
? _listenerInsideWorker
: _listenerOutsideWorker;
listeners.TryRemove(handler, out _);
Expand All @@ -105,7 +106,7 @@ public void RemoveEventListener(string @event, Action<MessageEvent<T>> handler)
public virtual void Terminate()
{
_workerCancellationToken.Cancel();
_workerThread.Join();
WorkerThread.Join();
while (_workerQueue.Count > 0)
{
_workerQueue.Take();
Expand Down Expand Up @@ -133,6 +134,12 @@ protected override void OnStartInsideWorker()
WorkerLookup[Thread.CurrentThread.ManagedThreadId] = this;
AlphaTabWebWorker.Init();
}

public override void Terminate()
{
base.Terminate();
WorkerLookup.TryRemove(WorkerThread.ManagedThreadId, out _);
}
}

internal class ManagedThreadAlphaSynthWorker :
Expand All @@ -155,4 +162,10 @@ protected override void OnStartInsideWorker()
WorkerLookup[Thread.CurrentThread.ManagedThreadId] = this;
AlphaSynthWebWorker.Init();
}

public override void Terminate()
{
base.Terminate();
WorkerLookup.TryRemove(WorkerThread.ManagedThreadId, out _);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import kotlin.contracts.ExperimentalContracts
@OptIn(ExperimentalContracts::class, ExperimentalUnsignedTypes::class)
internal abstract class JavaThreadWorkerBase<T> : IAlphaTabWorker<T>, Runnable {
private val _postToMain: (action: () -> Unit) -> Unit
private val _workerThread: Thread
protected val workerThread: Thread
private val _workerQueue = LinkedBlockingQueue<() -> Unit>()
private var _isCancelled = false
private val _threadStartedEvent = Semaphore(1)
Expand All @@ -29,9 +29,9 @@ internal abstract class JavaThreadWorkerBase<T> : IAlphaTabWorker<T>, Runnable {
protected constructor(postToMain: (action: () -> Unit) -> Unit) {
_postToMain = postToMain;

_workerThread = Thread(this)
_workerThread.isDaemon = true
_workerThread.start()
workerThread = Thread(this)
workerThread.isDaemon = true
workerThread.start()

_threadStartedEvent.acquire()
}
Expand All @@ -56,7 +56,7 @@ internal abstract class JavaThreadWorkerBase<T> : IAlphaTabWorker<T>, Runnable {

override fun postMessage(message: T) {
val ev = MessageEvent(message);
if (Thread.currentThread().id == _workerThread.id) {
if (Thread.currentThread().id == workerThread.id) {
// Inside Worker -> Post to main
_postToMain(
{
Expand All @@ -83,7 +83,7 @@ internal abstract class JavaThreadWorkerBase<T> : IAlphaTabWorker<T>, Runnable {
if (event != "message") {
return;
}
val listeners = if (Thread.currentThread().id == _workerThread.id) {
val listeners = if (Thread.currentThread().id == workerThread.id) {
_listenerInsideWorker
} else {
_listenerOutsideWorker
Expand All @@ -95,7 +95,7 @@ internal abstract class JavaThreadWorkerBase<T> : IAlphaTabWorker<T>, Runnable {
if (event != "message") {
return;
}
val listeners = if (Thread.currentThread().id == _workerThread.id) {
val listeners = if (Thread.currentThread().id == workerThread.id) {
_listenerInsideWorker
} else {
_listenerOutsideWorker
Expand All @@ -105,8 +105,8 @@ internal abstract class JavaThreadWorkerBase<T> : IAlphaTabWorker<T>, Runnable {

override fun terminate() {
_isCancelled = true
_workerThread.interrupt()
_workerThread.join()
workerThread.interrupt()
workerThread.join()
_workerQueue.clear()
}
}
Expand All @@ -130,6 +130,11 @@ internal class JavaThreadAlphaTabRendererWorker(postToMain: (action: () -> Unit)
workerLookup[Thread.currentThread().id] = this;
AlphaTabWebWorker.init();
}

override fun terminate() {
super.terminate()
workerLookup.remove(workerThread.id)
}
}

@OptIn(ExperimentalContracts::class, ExperimentalUnsignedTypes::class)
Expand All @@ -151,4 +156,9 @@ internal class JavaThreadAlphaSynthWorker(postToMain: (action: () -> Unit) -> Un
workerLookup[Thread.currentThread().id] = this;
AlphaSynthWebWorker.init();
}

override fun terminate() {
super.terminate()
workerLookup.remove(workerThread.id)
}
}
Loading