mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2025-12-26 14:41:25 +00:00
dispatcher: Reuse base reference counting for Dispatcher hierararchy
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
This commit is contained in:
parent
724f23e4bd
commit
2b9e1dcd55
@ -52,10 +52,9 @@ typedef void (*dispatcher_handle_any_message)(void *opaque,
|
||||
* activity and should call dispatcher_handle_recv_read() to process incoming
|
||||
* messages.
|
||||
*/
|
||||
class Dispatcher
|
||||
class Dispatcher: public red::shared_ptr_counted
|
||||
{
|
||||
public:
|
||||
SPICE_CXX_GLIB_ALLOCATOR
|
||||
/* Create a new Dispatcher object
|
||||
*
|
||||
* @max_message_type: indicates the number of unique message types that can
|
||||
@ -150,9 +149,6 @@ public:
|
||||
*/
|
||||
void set_opaque(void *opaque);
|
||||
|
||||
void ref() { g_atomic_int_inc(&_ref); }
|
||||
void unref() { if (g_atomic_int_dec_and_test(&_ref)) delete this; }
|
||||
|
||||
protected:
|
||||
virtual ~Dispatcher();
|
||||
|
||||
@ -160,7 +156,6 @@ private:
|
||||
static int handle_single_read(Dispatcher *dispatcher);
|
||||
static void handle_event(int fd, int event, Dispatcher* dispatcher);
|
||||
void send_message_internal(const DispatcherMessage*msg, void *payload);
|
||||
gint _ref = 1;
|
||||
red::unique_link<DispatcherPrivate> priv;
|
||||
};
|
||||
|
||||
|
||||
@ -72,7 +72,7 @@ struct RedChannelPrivate
|
||||
handle_acks(!!(flags & RedChannel::HandleAcks)),
|
||||
parser(spice_get_client_channel_parser(type, nullptr)),
|
||||
migration_flags(flags & RedChannel::MigrateAll),
|
||||
dispatcher(red::add_ref(dispatcher)),
|
||||
dispatcher(dispatcher),
|
||||
reds(reds)
|
||||
{
|
||||
thread_id = pthread_self();
|
||||
@ -80,9 +80,6 @@ struct RedChannelPrivate
|
||||
|
||||
~RedChannelPrivate()
|
||||
{
|
||||
if (dispatcher) {
|
||||
dispatcher->unref();
|
||||
}
|
||||
red_channel_capabilities_reset(&local_caps);
|
||||
}
|
||||
|
||||
@ -118,7 +115,7 @@ struct RedChannelPrivate
|
||||
* thread_id will be used to check the channel thread and automatically
|
||||
* use the dispatcher if the thread is different.
|
||||
*/
|
||||
Dispatcher *const dispatcher;
|
||||
const red::shared_ptr<Dispatcher> dispatcher;
|
||||
RedsState *const reds;
|
||||
RedStatNode stat;
|
||||
};
|
||||
@ -351,13 +348,13 @@ static void handle_dispatcher_connect(void *opaque, RedMessageConnect *msg)
|
||||
void RedChannel::connect(RedClient *client, RedStream *stream, int migration,
|
||||
RedChannelCapabilities *caps)
|
||||
{
|
||||
if (priv->dispatcher == NULL ||
|
||||
if (!priv->dispatcher ||
|
||||
pthread_equal(pthread_self(), priv->thread_id)) {
|
||||
on_connect(client, stream, migration, caps);
|
||||
return;
|
||||
}
|
||||
|
||||
Dispatcher *dispatcher = priv->dispatcher;
|
||||
Dispatcher *dispatcher = priv->dispatcher.get();
|
||||
|
||||
// get a reference potentially the main channel can be destroyed in
|
||||
// the main thread causing RedClient to be destroyed before using it
|
||||
@ -560,7 +557,7 @@ static void handle_dispatcher_migrate(void *opaque, RedMessageMigrate *msg)
|
||||
|
||||
void RedChannel::migrate_client(RedChannelClient *rcc)
|
||||
{
|
||||
if (priv->dispatcher == NULL ||
|
||||
if (!priv->dispatcher ||
|
||||
pthread_equal(pthread_self(), priv->thread_id)) {
|
||||
rcc->migrate();
|
||||
return;
|
||||
@ -584,7 +581,7 @@ static void handle_dispatcher_disconnect(void *opaque, RedMessageDisconnect *msg
|
||||
|
||||
void RedChannel::disconnect_client(RedChannelClient *rcc)
|
||||
{
|
||||
if (priv->dispatcher == NULL ||
|
||||
if (!priv->dispatcher ||
|
||||
pthread_equal(pthread_self(), priv->thread_id)) {
|
||||
rcc->disconnect();
|
||||
return;
|
||||
|
||||
@ -42,8 +42,9 @@
|
||||
#define MAX_MONITORS_COUNT 16
|
||||
|
||||
struct QXLState {
|
||||
SPICE_CXX_GLIB_ALLOCATOR
|
||||
QXLInstance *qxl;
|
||||
Dispatcher *dispatcher;
|
||||
red::shared_ptr<Dispatcher> dispatcher;
|
||||
uint32_t pending;
|
||||
int primary_active;
|
||||
int x_res;
|
||||
@ -566,13 +567,13 @@ void red_qxl_init(RedsState *reds, QXLInstance *qxl)
|
||||
|
||||
spice_return_if_fail(qxl != NULL);
|
||||
|
||||
qxl_state = g_new0(QXLState, 1);
|
||||
qxl_state = new QXLState();
|
||||
qxl_state->reds = reds;
|
||||
qxl_state->qxl = qxl;
|
||||
pthread_mutex_init(&qxl_state->scanout_mutex, NULL);
|
||||
qxl_state->scanout.drm_dma_buf_fd = -1;
|
||||
qxl_state->gl_draw_cookie = GL_DRAW_COOKIE_INVALID;
|
||||
qxl_state->dispatcher = new Dispatcher(RED_WORKER_MESSAGE_COUNT);
|
||||
qxl_state->dispatcher = red::make_shared<Dispatcher>(RED_WORKER_MESSAGE_COUNT);
|
||||
|
||||
qxl_state->max_monitors = UINT_MAX;
|
||||
qxl->st = qxl_state;
|
||||
@ -584,7 +585,7 @@ void red_qxl_init(RedsState *reds, QXLInstance *qxl)
|
||||
|
||||
void red_qxl_destroy(QXLInstance *qxl)
|
||||
{
|
||||
spice_return_if_fail(qxl->st != NULL && qxl->st->dispatcher != NULL);
|
||||
spice_return_if_fail(qxl->st != NULL && qxl->st->dispatcher);
|
||||
|
||||
QXLState *qxl_state = qxl->st;
|
||||
|
||||
@ -592,16 +593,15 @@ void red_qxl_destroy(QXLInstance *qxl)
|
||||
RedWorkerMessageClose message;
|
||||
qxl_state->dispatcher->send_message(RED_WORKER_MESSAGE_CLOSE_WORKER, &message);
|
||||
red_worker_free(qxl_state->worker);
|
||||
qxl_state->dispatcher->unref();
|
||||
/* this must be done after calling red_worker_free */
|
||||
qxl->st = NULL;
|
||||
pthread_mutex_destroy(&qxl_state->scanout_mutex);
|
||||
g_free(qxl_state);
|
||||
delete qxl_state;
|
||||
}
|
||||
|
||||
Dispatcher *red_qxl_get_dispatcher(QXLInstance *qxl)
|
||||
{
|
||||
return qxl->st->dispatcher;
|
||||
return qxl->st->dispatcher.get();
|
||||
}
|
||||
|
||||
void red_qxl_clear_pending(QXLState *qxl_state, int pending)
|
||||
|
||||
@ -135,7 +135,7 @@ struct RedsState {
|
||||
|
||||
SpiceCoreInterfaceInternal core;
|
||||
red::safe_list<QXLInstance*> qxl_instances; // XXX owning
|
||||
MainDispatcher *main_dispatcher;
|
||||
red::shared_ptr<MainDispatcher> main_dispatcher;
|
||||
RedRecord *record;
|
||||
};
|
||||
|
||||
|
||||
@ -3428,7 +3428,7 @@ static int do_spice_init(RedsState *reds, SpiceCoreInterface *core_interface)
|
||||
reds->core.public_interface = core_interface;
|
||||
reds->agent_dev = red_char_device_vdi_port_new(reds);
|
||||
reds_update_agent_properties(reds);
|
||||
reds->main_dispatcher = new MainDispatcher(reds);
|
||||
reds->main_dispatcher = red::make_shared<MainDispatcher>(reds);
|
||||
reds->mig_target_clients = NULL;
|
||||
reds->vm_running = TRUE; /* for backward compatibility */
|
||||
|
||||
@ -3795,9 +3795,7 @@ SPICE_GNUC_VISIBLE void spice_server_destroy(SpiceServer *reds)
|
||||
SSL_CTX_free(reds->ctx);
|
||||
}
|
||||
|
||||
if (reds->main_dispatcher) {
|
||||
reds->main_dispatcher->unref();
|
||||
}
|
||||
reds->main_dispatcher.reset();
|
||||
reds_cleanup_net(reds);
|
||||
if (reds->agent_dev) {
|
||||
reds->agent_dev->unref();
|
||||
@ -4489,7 +4487,7 @@ uint32_t reds_qxl_ram_size(RedsState *reds)
|
||||
|
||||
MainDispatcher* reds_get_main_dispatcher(RedsState *reds)
|
||||
{
|
||||
return reds->main_dispatcher;
|
||||
return reds->main_dispatcher.get();
|
||||
}
|
||||
|
||||
static void red_char_device_vdi_port_constructed(GObject *object)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user