Comments (10)
This may be an issue with the Csound API. I was able to reproduce this outside of Node.js, and I’ve opened an issue at csound/csound#778.
from csound-api.
So, using the Csound API sets, by default, a signal handler that can delay or prevent termination of a process, almost always (but not necessarily, it seems) when running Csound on a background thread.
The simplest solution I can think of is to just not use the Csound API signal handler. I can do this by putting
csoundInitialize(CSOUNDINIT_NO_SIGNAL_HANDLER);
at the beginning of the binding to csoundCreate
. This would mean that, by default, the Csound API signal handler would not be set, and pressing Ctrl-C would terminate Node.js as expected. If someone wants to use the Csound API’s default signal handler for some reason, you’d just need to run
csound.Initialize();
(with no arguments) before any calls to csound.Create()
. Some remarks about the drawbacks of doing this are at csound/csound#778 (comment).
From there, I think potential solutions get complex pretty quickly. At minimum, I think I’d need
- A custom signal handler that sets a global “stop everything now” flag
- An extra check for this flag in the
csoundPerformKsmps
loops here and here - Some kind of mechanism (maybe a global list of performing Csound instances that gets removed from in
HandleOKCallback
andWorkComplete
) that actually enforces finishing and cleaning up after Csound performances before re-raising the signal
My leaning, of course, is to not use the Csound API signal handler. What do you think?
from csound-api.
I must admit I didn't expect the answer to be so complicated!
I have done a bit of reading on signals in multithreaded applications this morning and from what I can tell the standard approach appears to be setting up a single handler which takes care of signals for everything. As the API caller (csound-api in this case) is the one setting up the threads, I suppose it falls on us to handle the interrupts. So this would mean CSOUNDINIT_NO_SIGNAL_HANDLER
and creating our own handler function.
What is the advantage of having a global flag (needing the dot points above) versus just calling csound.Stop()/csound.Destroy()?
from csound-api.
I’m honestly not sure about this myself, but here goes…
If you mean calling csound.Stop
and csound.Destroy
in JavaScript in response to signals, it’s a possibility, but I think this would mean that every csound-api user would then have to handle signals in JavaScript; anyone running Csound asynchronously in Node.js would need to use process.on
. Ideally, though, I’d like csound-api to “just work” and handle signals for you (if you want it to).
If you mean calling the csoundStop
and csoundDestroy
C API functions in a signal handler, this gets tricky, I’m afraid. The asynchronous Csound performance functions of csound-api (PerformAsync
and PerformKsmpsAsync
) both use csoundPerformKsmps
(the C function) under the hood. This is because, despite being nominally thread-safe, functions like csoundInputMessage
must be called on Csound’s performance thread to avoid unacceptable delays on everything other than macOS (which I found out with issue #7). So, if you call csound.PerformAsync
in Node.js, and then use csound.InputMessage
, you’re really setting up a loop that calls csoundPerformKsmps
repeatedly and gets input arguments for csoundInputMessage
(and a few other functions) off of a queue. This is happening here and here.
The upshot is that there needs to be a way to break out of these csoundPerformKsmps
loops in response to a signal, and csoundStop
doesn’t do that. About the only thing I can think of to do (and what seems to be suggested here) is set a flag that can be checked in these loops.
The idea behind the last bullet point is that if there are asynchronous Csound performances in progress when a SIGINT
occurs, we still need to re-raise the signal, call the default signal handler, or otherwise do something to terminate Node.js. When should we do this? Most likely when all the csoundPerformKsmps
loops are broken out of. Either HandleOKCallback
or WorkComplete
are called when that happens. So, if the “a signal was raised so stop everything” flag was set, HandleOKCallback
or WorkComplete
would need to somehow terminate Node.js when the last asynchronous Csound performance ends.
from csound-api.
this would mean that every csound-api user would then have to handle signals in JavaScript
I see. I thought that it might be possible within the library, but if that's not the case it's definitely not a "just works" solution and the flag option is the way.
So it sounds like the solution would be to catch the signal, terminate all playing instruments (via flag on csoundPerformKsmps loop), then re-raise the signal on the main thread.
from csound-api.
I pushed a possible fix for this in commit a54e6c3. Can you take a look and give it a spin?
from csound-api.
The code makes sense to me, and from my tests everything is working as expected. I've tested with single performers and many, both situations work fine.
Are there any other signals we should catch other than SIGINT and SIGTERM?
from csound-api.
Maybe. The Csound API signal handler ignores SIGPIPE
, sets a flag on SIGINT
and SIGTERM
, and exits on everything else. I’m not sure how handling more signals would interact with Node.js, though; my leaning is to stick with just SIGINT
and SIGTERM
, for now.
from csound-api.
I just tested with a bunch of other ones and they all exit fine anyway.
from csound-api.
Awesome, thanks!
from csound-api.
Related Issues (17)
- Broken in Node 4.x HOT 7
- Allow working from global install HOT 3
- undefined symbol: __atomic_load_16** HOT 12
- undefined symbol on node 10.7 HOT 2
- Possibility of supressing stdout/stderr writes? HOT 2
- Problems installing HOT 5
- npm install csound-api not working HOT 17
- csdebug.h missing when installing on Debian Linux Jessie HOT 2
- Error with `npm install csound-api` HOT 4
- Errors running csound-api and Electron HOT 3
- Throttling in `.GetControlChannel()` method? HOT 7
- error with boost when installing csound-api HOT 4
- Stopping/Resetting an instance of PerformAsync causes crash HOT 3
- Feature request and version error HOT 7
- Async .InputMessage? HOT 21
- Add CompileOrc and EvalCode to CsoundEventType HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from csound-api.