fm_server Thread Design
The fm_server uses many different threads for execution, with different realtime requirements and priorities.
Taking a look at a gdb session (stopping the server with Ctrl-C while playing an audio file):
Program received signal SIGINT, Interrupt. [Switching to Thread -1214629680 (LWP 11072)] 0xffffe410 in __kernel_vsyscall () (gdb) info threads
(gdb) info threads 7 Thread -1261929584 (LWP 11082) 0xffffe410 in __kernel_vsyscall () 4 Thread -1236751472 (LWP 11079) 0xffffe410 in __kernel_vsyscall () 3 Thread -1224492144 (LWP 11078) 0xffffe410 in __kernel_vsyscall () 2 Thread -1216099440 (LWP 11074) 0xffffe410 in __kernel_vsyscall () * 1 Thread -1214629680 (LWP 11072) 0xffffe410 in __kernel_vsyscall ()
Taking a closer look:
(gdb) thread 1 [Switching to thread 1 (Thread -1214629680 (LWP 11072))]#0 0xffffe410 in __kernel_vsyscall () (gdb) bt #0 0xffffe410 in __kernel_vsyscall () #1 0xb7a6a893 in poll () from /lib/tls/i686/cmov/libc.so.6 #2 0xb7c40e03 in g_main_context_iterate (context=0x807c338, block=1, dispatch=1, self=0x805de08) at gmain.c:2979 #3 0xb7c41179 in IA__g_main_loop_run (loop=0x8169d60) at gmain.c:2881 #4 0x0804d9c6 in main (argc=Cannot access memory at address 0x3 ) at main.c:164
Thread 1 - main thread which executes in GLib mainloop
(gdb) thread 2 [Switching to thread 2 (Thread -1216099440 (LWP 11074))]#0 0xffffe410 in __kernel_vsyscall () (gdb) bt #0 0xffffe410 in __kernel_vsyscall () #1 0xb7b0b3a8 in accept () from /lib/tls/i686/cmov/libpthread.so.0 #2 0xb7f243ff in socket_listen (data=0x80b9240) at rgc_protocol_rbp_server.c:305 #3 0xb7c5bb7f in g_thread_create_proxy (data=0x8078018) at gthread.c:591 #4 0xb7b0431b in start_thread () from /lib/tls/i686/cmov/libpthread.so.0 #5 0xb7a7457e in clone () from /lib/tls/i686/cmov/libc.so.6
Thread 2 - RGC thread that listens for TCP connections
(gdb) thread 3 [Switching to thread 3 (Thread -1224492144 (LWP 11078))]#0 0xffffe410 in __kernel_vsyscall () (gdb) bt #0 0xffffe410 in __kernel_vsyscall () #1 0xb7a6ca29 in ioctl () from /lib/tls/i686/cmov/libc.so.6 #2 0xb7b99a20 in ?? () from /usr/lib/libasound.so.2 #3 0x0000000d in ?? () #4 0x400c4150 in ?? () #5 0xb703b320 in ?? () #6 0xb7c03f80 in ?? () from /usr/lib/libasound.so.2 #7 0xfffffe00 in ?? () #8 0x08189ad8 in ?? () #9 0x000001e5 in ?? () #10 0xb7c03f80 in ?? () from /usr/lib/libasound.so.2 #11 0x08189ad8 in ?? () #12 0xb7b07be0 in ?? () from /lib/tls/i686/cmov/libpthread.so.0 #13 0xb703b368 in ?? () #14 0xb7b89b55 in snd_pcm_writei () from /usr/lib/libasound.so.2 Backtrace stopped: frame did not save the PC
Thread 3 - the main pipeline thread. This runs the entire pipeline (traversing the chain of FmElements and passing the audio data to an FmOutput?). Runs with RT privileges, so it can't use locking operations or busy-wait.
(gdb) thread 4
[Switching to thread 4 (Thread -1236751472 (LWP 11079))]#0 0xffffe410 in __kernel_vsyscall ()
(gdb) bt
#0 0xffffe410 in __kernel_vsyscall ()
#1 0xb7b0a5ce in sem_wait@GLIBC_2.0 () from /lib/tls/i686/cmov/libpthread.so.0
#2 0x0804da8f in fm_sem_decrease (sem=0x80a9aa0) at fm_utils.c:68
#3 0x08057c6c in gst_fm_sink_render (bsink=0x81ac340, buf=0x81f2060) at gstfmsink.c:413
#4 0xb7ebfa90 in gst_base_sink_render_object (basesink=0x81ac340, pad=0x81ae558, obj=0x81f2060) at gstbasesink.c:1684
#5 0xb7ec1905 in gst_base_sink_queue_object_unlocked (basesink=0x81ac340, pad=0x81ae558, obj=0x81f2060, prerollable=1)
at gstbasesink.c:1860
#6 0xb7ec1f36 in gst_base_sink_chain_unlocked (basesink=0x81ac340, pad=0x81ae558, buf=0x81f2060) at gstbasesink.c:2120
#7 0xb7ec24ee in gst_base_sink_chain (pad=0x81ae558, buf=0x81f2060) at gstbasesink.c:2154
#8 0xb7e5fa49 in gst_pad_chain_unchecked (pad=0x81ae558, buffer=0x81f2060) at gstpad.c:3459
#9 0xb7e6013b in gst_pad_push (pad=0x81ae498, buffer=0x81f2060) at gstpad.c:3625
#10 0xb7ecd364 in gst_base_transform_chain (pad=0x81ae3d8, buffer=0x81f2060) at gstbasetransform.c:1571
#11 0xb7e5fa49 in gst_pad_chain_unchecked (pad=0x81ae3d8, buffer=0x81f2060) at gstpad.c:3459
#12 0xb7e6013b in gst_pad_push (pad=0x81ae318, buffer=0x81f2060) at gstpad.c:3625
#13 0xb7ecd364 in gst_base_transform_chain (pad=0x81ae258, buffer=0x81f1c58) at gstbasetransform.c:1571
#14 0xb7e5fa49 in gst_pad_chain_unchecked (pad=0x81ae258, buffer=0x81f1c58) at gstpad.c:3459
#15 0xb7e6013b in gst_pad_push (pad=0x819da58, buffer=0x81f1c58) at gstpad.c:3625
#16 0xb7e5164a in gst_proxy_pad_do_chain (pad=0x819d2a0, buffer=0x81f1c58) at gstghostpad.c:191
#17 0xb7e5fa49 in gst_pad_chain_unchecked (pad=0x819d2a0, buffer=0x81f1c58) at gstpad.c:3459
#18 0xb7e6013b in gst_pad_push (pad=0x819d380, buffer=0x81f1c58) at gstpad.c:3625
#19 0xb7e5164a in gst_proxy_pad_do_chain (pad=0x819db20, buffer=0x81f1c58) at gstghostpad.c:191
#20 0xb7e5fa49 in gst_pad_chain_unchecked (pad=0x819db20, buffer=0x81f1c58) at gstpad.c:3459
#21 0xb7e6013b in gst_pad_push (pad=0x81b08d0, buffer=0x81f1c58) at gstpad.c:3625
#22 0xb648def3 in ?? () from /usr/lib/gstreamer-0.10/libgstflump3dec.so
#23 0x081b08d0 in ?? ()
#24 0x081f1c58 in ?? ()
#25 0x00000480 in ?? ()
#26 0x00000000 in ?? ()
Thread 4 - GStreamer helper thread running inside a FmInputGst element. Every element of this type will have a similar thread associated with it. Note that GStreamer creates and manages other threads of his own, especially during seek operations.
(gdb) thread 7 [Switching to thread 7 (Thread -1261929584 (LWP 11082))]#0 0xffffe410 in __kernel_vsyscall () (gdb) bt #0 0xffffe410 in __kernel_vsyscall () #1 0xb7b085c6 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib/tls/i686/cmov/libpthread.so.0 #2 0xb7e73dd8 in gst_system_clock_async_thread (clock=0x819de40) at gstsystemclock.c:260 #3 0xb7c5bb7f in g_thread_create_proxy (data=0x81b1b78) at gthread.c:591 #4 0xb7b0431b in start_thread () from /lib/tls/i686/cmov/libpthread.so.0 #5 0xb7a7457e in clone () from /lib/tls/i686/cmov/libc.so.6
Thread 7 - a thread created and managed by GStreamer. We don't need to worry about it.
