Atte:
I don't know if this is directly relevant to your overall goal, but for my many hours of real-time performance work, I found the following construct to be 100% bullet proof.
The idea is that you assign the Shred to a variable, e.g. _phoneme_handle, when you spork the shred. When you want to stop the shred, you don't directly kill it -- instead, you set the variable to something else (e.g. null). Within the shred's main processing loop, you compare the value of _phoneme_handle against "me", and stop processing if they differ. This approach cleanly avoids any race conditions associated with starting and stopping shreds:
// called when the note first starts.
fun Vox note_started() {
spork ~ _phoneme_proc() @=> _phoneme_handle; // start babbling
_vox => AudioIO.output_bus();
return this;
}
// called when note has finished.
fun Vox note_ended() {
null @=> _phoneme_handle; // stop babbling
_vox =< AudioIO.output_bus();
return this;
}
// shred that modifies phonemes
fun void _phoneme_proc() {
while (me == _phoneme_handle) {
// ... do stuff until _phoneme_handle changes
}
// here when the shred is absolutely about to exit
}