mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2025-12-26 22:48:19 +00:00
-Remove BOM character if exists (this may interfere Static Site Generators) -Use simple titles (SSG may use the title as the html file name) -Fix title which violates the format
81 lines
3.7 KiB
Plaintext
81 lines
3.7 KiB
Plaintext
How does SPICE handle threading
|
|
===============================
|
|
|
|
Lots of code runs 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.
|
|
|
|
One aspect to take into consideration is the event scheduling. SPICE uses some
|
|
`SpiceCoreInterface` to handle events. As the events will be handled from a
|
|
thread based on the core interface you have to use the correct core. Each
|
|
channel has an associated core interface which can be retrieved using
|
|
`red_channel_get_core_interface`. There's also a main core interface you can get
|
|
using `reds_get_core_interface`. `reds_core_timer_*` and `reds_core_watch_*`
|
|
functions use the main core interface.
|
|
Even though multiple channel types run in the main thread and so could use
|
|
directly the main code interface, for coherence, rule simplicity and to allows
|
|
the code to be moved in a separate thread easily if needed, it's advisable to
|
|
use the channel core interface (that will be the main core interface in this
|
|
case).
|
|
Currently character devices and not channel code runs in the main thread.
|
|
|
|
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.
|