Many places around were re-inventing logException with varying level of success.
In addition, the full error is now printed as a diagnostic instead of debug.
This is more in line with the description of `LogLevel.diagnostic`
("Extended user information (e.g. for more detailed error information)"),
as opposed to the one of `LogLevel.debug_`
("Developer information useful for algorithm debugging").
1. Removes the marker task used by schedule() and instead limits the number of task resumptions to the initial length of the task queue
2. Assigns a static and a dynamic priority to each task. The dynamic priority starts with the same value as the static priority and gets incremented by the static priority each time the task gets overtaken by a higher priority task, eventually leading to the task becoming the highest priority (unless the static priority is zero). Tasks with a higher dynamic priority generally take precedence, unless the concurrency exceeds 10 scheduled tasks, in which case the front of the queue is scheduled in normal FIFO order.
- terminate() would hang if called from a worker thread because it would attempt to self-join
- the handleWorkerTasks could miss signal emits, resulting in a hanging task queue or a missed termination signal