In case anyone else is using a global forked thread that loops the entire time that SageTV is running...
I recently noticed that a forked loop was continuing to run on my SageTV server after a Placeshifter or MVP client disconnected. This particular loop (to update the disk space usage info) was a global loop, meaning it wasn't linked to any particular menu's hooks and did not shut off via a variable setting when the menu was exited. This is not an issue for a local client UI, because when you exit the program, all code associated with that program will cease to execute. But, since remote clients run as part of the server application, exiting the remote client will not automatically kill the permanent global loop on the server. As multiple remote clients connect & disconnect, these background loops can easily multiply and eat cpu time. Thus, all forked threads need to be able to exit their loops when a client disconnects. If any other globally looping threads have this issue, there are at least a couple ways this can be done:
- Use the ApplicationExiting hook to set a global variable that tells the global loop that it should end. This is probably better than using UI context names (described below), since all clients should execute the ApplicationExiting hook when they disconnect, thus preventing any possibility of multiple loops continuing to run. (I have not used this method yet, so you should test it to make sure it is working to exit your loop on a remote client.)
- Check the UI context -- Before continuing a global loop, use GetUIContextNames() to get all UI context names, use GetUIContextName() to get the current UI context, then check to see if the current UI context is still in the list of all context names. If it isn't, then the remote client has exited and the loop should end. Note: Depending on how quickly the UI contexts are checked, it is possible to reconnect a remote client before the loop sees that it has exited. This could result in the loop thinking that it should still be running, even though it can't talk to the reconnected remote client. In this case, you could end up with multiple forked loops, but they should all end when the remote client disconnects for longer than the loop's Wait() period.
A 'just in case' reminder: don't forget to make sure all non-global hooks that are linked to specific menus also stop themselves eventually. This is usually done by setting a variable in the BeforeMenuUnload hook that tells the local loop to end because the menu no longer needs it.
- Andy