[Spice-devel] Some notes on threading and reference counting on spice-server
Frediano Ziglio
fziglio at redhat.com
Fri Aug 25 17:07:17 UTC 2017
How Spice handle threading
--------------------------
Lot of code run in a single thread.
Qemu usually calls Spice from the same thread except on call backs to
code already run in different threads.
Channel run mostly on a single thread except on creation and
destroying which MUST be done in the main thread. Lot of Channels run
on the main thread but currently CursorChannel and DisplayChannel can
be run from within a thread created by Worker. Note that different
CursorChannel/DisplayChannel (they differ by id) run in separate
Worker threads.
ChannelClient runs in the Channel thread. Ever creation is done
in the same thread while destruction can happen in different
phases.
RedClient is bound to ChannelClients that can be in separate threads.
Is one of the cases where mutexes are used.
Another important aspect of dealing with multiple threads are the
dispatchers. Dispatchers are used to send messages/request from one
thread to another. The main dispatcher is used to send requests to
the main thread. The Qxl uses a dispatcher to send requests to the
Worker which will forward to DisplayChannel/CursorChannel.
Client may call some ChannelClient functions using some callbacks
registered inside ClientCbs. Usually these callbacks are functions that
does the job directly if the Channel is running in the main thread or
they use a dispatcher to do the job in the right thread. Currently
there are 3 callbacks: connect, disconnect and migrate. Connect and
migrate are asynchronous (the job is done while the current thread is
doing something else) while disconnect is synchronous (the main thread
will wait for termination).
Reference counting and owning
-----------------------------
-> pointer
---> pointer with owning (mostly GObject ref counting)
ChannelClient -> Client
Client ---> ChannelClient
Client -> MainChannelClient
ChannelClient ---> Channel
Channel -> ChannelClient
In this case the "real" owner is the TCP connection. When a
disconnection is detected the links Channel -> ChannelClient and
Client ----> ChannelClient are removed causing possibly ChannelClient
to be released (the main owner of ChannelClient is Client). When
MainChannelClient is disconnected it disconnects all ChannelClients
connected to the same Client
Who owns Client? Client is released when the MainChannelClient
attached is disconnected. In this case a request is scheduled in the
main thread (even if MainChannelClient run on the main thread too) and
red_client_disconnect is called which calls red_client_destroy which
use g_object_unref to free the object.
Where is freed the MainChannelClient? On disconnection like other
channel clients, currently before Client which will have a dandling
pointer.
More information about the Spice-devel
mailing list