Sclang failing to release its UDP port upon shutdown?

Does anyone else find that sclang fails to release its port when rebooting the interpreter?

This happens so often to me that I ended up putting some logic into my startup file to check NetAddr.langPort and, if different from 57120, get PIDs from fuser 57120/udp and kill those processes, and then quit the language to be free and clear to reboot again.

I’m not clear on the ins and outs of OS port management. I’d have assumed that sclang’s exit would release the port so that it would be available for the next sclang instance. In practice, this seems not to be happening.

hjh

Does it happen when running the process again soon after killing it, or is there no relation? vscode/linux specific?

(The command fuser in Linux makes it possible to just kill any process listening to a given port, which might be simpler workaround since it checks the PID and kills the process with one command)

What do you mean exactly? Do you get an error message? If yes, please post it.

Generally, the OS releases all open file and socket handles when a program exits, so even if sclang did not properly release its resources, the OS would do anyway.

A UDP port is typically released immediately after closing the socket. There is no need for the OS to keep it around.

Since you are on Linux, my guess would be that some child process inherits the socket handle and stays around after the interpreter has been quit. Have you checked which processes occupy port 57120? See also: Child processes inherit all file descriptors · Issue #5897 · supercollider/supercollider · GitHub.


Side note: TCP ports are not immediately released because of CLOSE_WAIT and TIME_WAIT states (windows - What are CLOSE_WAIT and TIME_WAIT states? - Super User). That is why Pd sets the SO_REUSEADDR flag on TCP sockets which allows to bind to an already bound socket. This makes sure that you can close and immediately reopen a patch and still use the same TCP port.

1 Like

I’ve observed this behavior when rebooting the interpreter from within sc-ide (but not when restarting sclang in vscode), and when sclang crashes and I subsequently boot the interpreter.

I don’t recall seeing this in Windows, but I seldom use Windows or Mac so I can’t say for sure that it wouldn’t happen.

There’s no error. Sclang just cheerfully occupies 57121 instead. But this messes up my Open Stage Control interface, so I added the logic to detect the situation automatically.

This, I don’t recall. I wonder now if it’s SC-IDE. Maybe the other process is supposed to release it, but doesn’t do it fast enough.

You know, I don’t remember seeing this on my old computer, which had a not very speedy HDD instead of the lightning fast SSD that I have now (and CPU speed also matters). Maybe I never saw it before because library compilation took a full second, long enough for the port to get dropped outside of sclang. On my current system, compilation is a good 10 times faster, so sclang may be trying to grab the port sooner than it’s available.

User impact is mainly that I need to reboot the interpreter twice – it’s minor, just a point of curiosity.

hjh

I’ve noticed this switching between 57120 and 57121 as well, but only when using Open Stage Control. That doesn’t mean it wasn’t/isn’t happening other times, but I’ve never really been able to consistently reproduce it or notice any patterns regarding when it happens. I’m on MacOS…could it be something to do with o-s-c overstaying its welcome on the port perhaps?

I wonder now if it’s SC-IDE.

After a quick look at the code, SC-IDE seems to properly wait until the old sclang process has finished before starting the new one.

It could also be that the OS intentionally keeps the UDP port open for a while, e.g. to prevent inbound messages still in transit to be received by the wrong application. Will do some tests later.

I’ve definitely seen it when Open Stage Control was closed.

hjh

yea, terminating a process by itself will not terminate its child processes in linux. you need to be explicit. To signal all processes within a specific process group, you need to send the signal to the process group. parent’s PID requires a minus symbol before the parent’s process ID (if you use a simple kill command, for example).

See Sclang failing to release its UDP port upon shutdown? - #6 by Spacechild1

BTW, SC-IDE does not quit sclang by sending a signal (which wouldn’t work on Windows), it rather asks it to execute the code 0.exit;, then waits until the process has finished (or terminates it after a certain timeout).

1 Like

Good to know you’re close to solve it. I was not saying that’s how sclang would do it, I was just giving an example how child process survive by default in linux, the reason one needs a special syntax when using common system tools…

I had a similar problem:
https://listarc.cal.bham.ac.uk/lists/sc-users-2018/msg60884.html

In this case, dos-command-prompt seems to be holding UDP.
Could the terminal window hold UDP on Linux and MacOS?

Just checked… it’s only sclang:

$ fuser 57120/udp
57120/udp:           496835

$ ps x | grep 496835
 496835 ?        SLl    0:01 /usr/local/bin/sclang -l /home/dlm/.config/SuperCollider/sclang_conf.yaml -i scqt

(That’s with Open Stage Control up and running – so Open Stage shouldn’t be the issue.)

I also briefly checked when, in the sclang startup process, does the inbound OSC port get opened? Answer: Early. In TerminalClient, I see:

  1. Read commandline options.
  2. Read library configuration file.
  3. initRuntime – OSC init happens here.
  4. Set up user/system path variables.
  5. Compile the class library.
  6. etc.

So my idea that the speed of library compilation could affect the timing of opening the OSC port doesn’t seem to pan out.

hjh

1 Like