[Gambas-user] can't terminate fluidsynth processes by sending "quit" command over socket
Doriano Blengino
doriano.blengino at ...1909...
Thu May 7 07:42:53 CEST 2009
Kevin Fishburne ha scritto:
> Hello everyone. I'm having an odd issue that's got me stumped. My GAMBAS
> app opens several fluidsynth daemons listening on different ports and
> communicates with them over a socket. While they do all send and receive
> commands properly, when I issue the "quit" command to any of the
> fluidsynth daemons they don't actually terminate. They do respond with
> "Cheers!", which is what they say when they terminate, but the processes
> remain and they continue responding to commands. I have to use SHELL
> "pkill fluidsynth", which leaves the daemons unable to be restarted
> because they can't bind to their designated port/socket afterward for
> some reason.
>
> At first I thought it was fluidsynth behaving badly, but I'm able to
> telnet to the fluidsynth daemon and issue the "quit" command
> successfully using the same shell command as GAMBAS. I'm starting
> fluidsynth with the following command:
>
> SHELL "fluidsynth --connect-jack-outputs --no-shell --verbose --server
> --audio-driver=jack --midi-channels=1 --portname=LiquidSynth01
> -oshell.port=9800 -oaudio.jack.id=LiquidSynth01 -omidi.driver=alsa_seq
> -omidi.portname=LiquidSynth01 -omidi.alsa_seq.id=LiquidSynth01"
>
> My code to stop the fluidsynth daemons is:
>
> DIM i AS Integer
>
> ' Stop FluidSynth.
> FOR i = 1 TO 16
> Send_To_FluidSynth("quit", i)
> SLEEP 0.125
> NEXT
>
> PUBLIC SUB Send_To_FluidSynth(FluidString AS String, Daemon AS Integer)
>
> ' Send a command to FluidSynth
> DIM Timeout AS Single
> FluidString = FluidString & "\n" ' Add carriage return to command is
> executed.
> Socket = NEW Socket
> Socket.Connect("localhost", 9799 + Daemon)
> DO WHILE (Socket.Status <> 7) AND (Socket.Status > 0)
> WAIT 0.1
> Timeout = Timeout + 0.1
> IF Timeout >= 0.25 THEN EXIT
> LOOP
> Timeout = 0
> IF Socket.Status = 7 THEN
> ' Socket is good, send command.
> WRITE #Socket, FluidString, Len(FluidString)
> PRINT "Sending command to FluidSynth daemon: " & FluidString
> END IF
> DO WHILE Lof(Socket) = 0
> WAIT 0.1
> Timeout = Timeout + 0.1
> IF Timeout >= 0.25 THEN EXIT
> LOOP
> READ #Socket, FluidString, Lof(Socket)
> PRINT "FluidSynth daemon replies with: " & FluidString
> CLOSE #Socket
>
> END
>
> As you can see there are 16 fluidsynth daemons starting at port 9800 and
> going up to port 9815. The for/next loop just cycles through these 16
> ports to terminate each process sequentially. I added the timeout stuff
> because if the code runs with no fluidsynth processes active/listening
> it just hangs there in the do/loop loops.
>
> Here's my debug/console output right after trying to quit the fluidsynth
> daemons, including anything they replied with:
>
> Sending command to FluidSynth daemon: quit
> FluidSynth daemon replies with: cheers!
> Sending command to FluidSynth daemon: quit
> FluidSynth daemon replies with: cheers!
> Sending command to FluidSynth daemon: quit
> FluidSynth daemon replies with: cheers!
> Sending command to FluidSynth daemon: quit
> FluidSynth daemon replies with: cheers!
> Sending command to FluidSynth daemon: quit
> FluidSynth daemon replies with: cheers!
> Sending command to FluidSynth daemon: quit
> FluidSynth daemon replies with: cheers!
> Sending command to FluidSynth daemon: quit
> FluidSynth daemon replies with: cheers!
> Sending command to FluidSynth daemon: quit
> FluidSynth daemon replies with: cheers!
> Sending command to FluidSynth daemon: quit
> FluidSynth daemon replies with: cheers!
> Sending command to FluidSynth daemon: quit
> FluidSynth daemon replies with: cheers!
> Sending command to FluidSynth daemon: quit
> FluidSynth daemon replies with: cheers!
> Sending command to FluidSynth daemon: quit
> FluidSynth daemon replies with: cheers!
> Sending command to FluidSynth daemon: quit
> FluidSynth daemon replies with: cheers!
> Sending command to FluidSynth daemon: quit
> FluidSynth daemon replies with: cheers!
> Sending command to FluidSynth daemon: quit
> FluidSynth daemon replies with: cheers!
> Sending command to FluidSynth daemon: quit
> FluidSynth daemon replies with: cheers!
> Terminated
> WARNING: Child process terminated by signal 15
> cannot read server event (Success)
> cannot complete execution of the processing graph (Resource temporarily
> unavailable)
> zombified - calling shutdown handler
> fluidsynth: error: Help! Lost the connection to the JACK server
> zombified - calling shutdown handler
> fluidsynth: error: Help! Lost the connection to the JACK server
> zombified - calling shutdown handler
> fluidsynth: error: Help! Lost the connection to the JACK server
> zombified - calling shutdown handler
> fluidsynth: error: Help! Lost the connection to the JACK server
> zombified - calling shutdown handler
> fluidsynth: error: Help! Lost the connection to the JACK server
> zombified - calling shutdown handler
> fluidsynth: error: Help! Lost the connection to the JACK server
> zombified - calling shutdown handler
> fluidsynth: error: Help! Lost the connection to the JACK server
> zombified - calling shutdown handler
> fluidsynth: error: Help! Lost the connection to the JACK server
> cannot complete execution of the processing graph (Success)
> cannot complete execution of the processing graph (Success)
> zombified - calling shutdown handler
> zombified - calling shutdown handler
> fluidsynth: error: Help! Lost the connection to the JACK server
> fluidsynth: error: Help! Lost the connection to the JACK server
> zombified - calling shutdown handler
> fluidsynth: error: Help! Lost the connection to the JACK server
> zombified - calling shutdown handler
> fluidsynth: error: Help! Lost the connection to the JACK server
> zombified - calling shutdown handler
> fluidsynth: error: Help! Lost the connection to the JACK server
> zombified - calling shutdown handler
> fluidsynth: error: Help! Lost the connection to the JACK server
> zombified - calling shutdown handler
> fluidsynth: error: Help! Lost the connection to the JACK server
> zombified - calling shutdown handler
> fluidsynth: error: Help! Lost the connection to the JACK server
> Failure to resume: Invalid argument
>
> The messages about JACK are because JACK is terminated after I attempt
> to terminate the fluidsynth daemons. Of course if they actually
> terminated properly they'd have nothing to complain about. I have no
> idea what's up with the "zombified" messages. Any ideas anyone?
>
I don't know fluidsynth enough, and I never used sockets with gambas,
but some idea could be stated anyway.
A "zombie" is a process which has no more its parent. Every process in
Linux is started by some other process, which then becomes the parent of
the new process (the child). The parent should wait for the child to
terminate, but if the parent terminates prematurely, then the child
process becomes a zombie. What here seems to happen is that your program
terminates before fluidsynth, turning it in a zombie. It seems that
fluidsynth, noticing to be "zombified", chooses to terminate.
Perhaps the reason is somehow related to the way you communicate with it
- just to start, I can say that a telnet program does many more things
than a simple TCP connection, so you should investigate about this. Is
fluidsynth able to communicate smoothly using a simple TCP connection,
or it requires some more handshake?
A try you can do is to modify slightly your code for waiting a reply
from the daemon:
DO WHILE Lof(Socket) = 0
WAIT 0.1
Timeout = Timeout + 0.1
IF Timeout >= 0.25 THEN EXIT
LOOP
READ #Socket, FluidString, Lof(Socket)
PRINT "FluidSynth daemon replies with: " & FluidString
CLOSE #Socket
Here, you wait until something appears on the socket, then read it and
close the socket; but it could be too soon. I think it would be better
to wait for the EOF. May be that fluidsynth sends "cheers!" then, after
a short time, it wants to send more. But your socket is already closed,
You could put a delay just after asking all daemons to stop; few
milliseconds are not a long time, but a gambas program can do a lot of
things in the meantime (ie, terminate too early...).
Does all the rest of the communication work properly? If yes, then
probably you are near to success. If not, then it is a communication
problem. Could be (I repeat, "could be") that you must send CR instead
of newline, or something similar.
Hope this help, cheers! (but I am not terminating... :-))
--
Doriano Blengino
"Listen twice before you speak.
This is why we have two ears, but only one mouth."
More information about the User
mailing list