mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2025-12-26 06:32:44 +00:00
docs: Add some documentation on spice threading model
Signed-off-by: Frediano Ziglio <fziglio@redhat.com> Acked-by: Christophe Fergeau <cfergeau@redhat.com>
This commit is contained in:
parent
b3d239012a
commit
12da078a9f
1
.gitignore
vendored
1
.gitignore
vendored
@ -35,6 +35,7 @@ INSTALL
|
||||
docs/manual/manual.chunked/
|
||||
docs/manual/manual.html
|
||||
docs/spice_style.html
|
||||
docs/spice_threading_model.html
|
||||
.dirstamp
|
||||
.deps
|
||||
.libs
|
||||
|
||||
@ -4,14 +4,16 @@ ASCIIDOC_FLAGS = -a icons -a toc
|
||||
EXTRA_DIST = \
|
||||
spice_style.html \
|
||||
spice_style.txt \
|
||||
spice_threading_model.html \
|
||||
spice_threading_model.txt \
|
||||
$(NULL)
|
||||
|
||||
if BUILD_MANUAL
|
||||
SUBDIRS = manual
|
||||
|
||||
all-local: spice_style.html
|
||||
all-local: spice_style.html spice_threading_model.html
|
||||
|
||||
spice_style.html: spice_style.txt
|
||||
%.html: %.txt
|
||||
$(AM_V_GEN) $(ASCIIDOC) -n $(ASCIIDOC_FLAGS) -o $@ $<
|
||||
endif
|
||||
|
||||
|
||||
74
docs/spice_threading_model.txt
Normal file
74
docs/spice_threading_model.txt
Normal file
@ -0,0 +1,74 @@
|
||||
How does SPICE handle threading
|
||||
-------------------------------
|
||||
|
||||
Lots of code run in a single thread.
|
||||
|
||||
Qemu usually calls SPICE from its main thread except on callbacks to code
|
||||
already running in different threads.
|
||||
|
||||
Channels (RedChannel/RedChannelClient code) run mostly on a single
|
||||
thread except RedChannels on creation and destruction which MUST be
|
||||
done in the main thread.
|
||||
Lots of channels run in the main thread but currently CursorChannel and
|
||||
DisplayChannel are run from within a thread created by RedWorker.
|
||||
Note that different CursorChannel/DisplayChannel (they differ by id) run in
|
||||
separate RedWorker threads (currently a single RedWorker thread runs a pair
|
||||
of CursorChannel and DisplayChannel).
|
||||
|
||||
RedChannelClient runs in the RedChannel thread. Creation is done in the same
|
||||
thread while destruction can happen in different threads.
|
||||
|
||||
A RedClient instance groups the various RedChannelClient connected to
|
||||
the same remote SPICE client.
|
||||
These RedChannelClient instances can run in separate threads:
|
||||
MainChannelClient and most of the other RedChannelClient will be
|
||||
running in the main thread, while the CursorChannelClient and the
|
||||
DisplayChannelClient usually will be running from a different thread.
|
||||
|
||||
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 RedWorker which will forward
|
||||
to DisplayChannel/CursorChannel.
|
||||
|
||||
RedClient may call some RedChannelClient functions using some callbacks
|
||||
registered inside ClientCbs. Usually these callbacks are functions that do the
|
||||
job directly if the RedChannel 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 ownership
|
||||
--------------------------------
|
||||
-> pointer
|
||||
|
||||
=> pointer with owning (mostly GObject ref counting)
|
||||
|
||||
RedChannelClient::client -> RedClient
|
||||
|
||||
RedClient::channels => RedChannelClient
|
||||
|
||||
RedClient::mcc -> MainChannelClient
|
||||
|
||||
RedChannelClient::channel => RedChannel
|
||||
|
||||
RedChannel::clients -> RedChannelClient
|
||||
|
||||
The RedClient represents a connection from a remote SPICE client,
|
||||
RedClient::channels corresponding to the connections for the individual
|
||||
channels. Their lifetime is tied to the TCP connection to this remote client.
|
||||
When a disconnection is detected, the corresponding RedChannelClient are
|
||||
removed from RedClient::channels and RedChannel::clients (the main owner of
|
||||
RedChannelClient is RedClient).
|
||||
When MainChannelClient is disconnected, all RedChannelClients connected to the
|
||||
same RedClient are automatically disconnected.
|
||||
|
||||
Who owns RedClient? RedClient is released when the MainChannelClient attached
|
||||
to it is disconnected. In this case a request is scheduled in the main thread
|
||||
(even if MainChannelClient runs on the main thread too) and
|
||||
red_client_disconnect is called which calls red_client_destroy which uses
|
||||
g_object_unref to free the object.
|
||||
|
||||
Where is the MainChannelClient freed? On disconnection like other channel
|
||||
clients, currently before RedClient which will have a dangling pointer.
|
||||
Loading…
Reference in New Issue
Block a user