[Spice-commits] 5 commits - server/inputs_channel.c server/main_channel.c server/red_channel.c server/red_channel.h server/red_dispatcher.c server/red_tunnel_worker.c server/red_worker.c server/smartcard.c server/snd_worker.c server/spicevmc.c

Hans de Goede jwrdegoede at kemper.freedesktop.org
Mon Mar 12 04:11:54 PDT 2012


 server/inputs_channel.c    |    7 -
 server/main_channel.c      |    2 
 server/red_channel.c       |    9 +-
 server/red_channel.h       |    1 
 server/red_dispatcher.c    |    2 
 server/red_tunnel_worker.c |    4 
 server/red_worker.c        |  198 +++++++++++++++++----------------------------
 server/smartcard.c         |    7 -
 server/snd_worker.c        |    4 
 server/spicevmc.c          |    4 
 10 files changed, 94 insertions(+), 144 deletions(-)

New commits:
commit 9a41e552962cb0cc0694a205988197a84914a2d6
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Sat Mar 10 15:29:26 2012 +0100

    red_channel: remove pre_disconnect hook
    
    Now that red_worker's EventListener is gone there are no more users of it.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/server/red_channel.c b/server/red_channel.c
index 5f906e6..ecb512d 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -1191,9 +1191,6 @@ void red_channel_client_disconnect(RedChannelClient *rcc)
         return;
     }
     red_channel_client_pipe_clear(rcc);
-    if (rcc->channel->channel_cbs.pre_disconnect) {
-        rcc->channel->channel_cbs.pre_disconnect(rcc);
-    }
     if (rcc->stream->watch) {
         rcc->channel->core->watch_remove(rcc->stream->watch);
         rcc->stream->watch = NULL;
diff --git a/server/red_channel.h b/server/red_channel.h
index ce534ca..5dfd187 100644
--- a/server/red_channel.h
+++ b/server/red_channel.h
@@ -187,7 +187,6 @@ typedef void (*channel_client_migrate_proc)(RedChannelClient *base);
  */
 typedef struct {
     channel_configure_socket_proc config_socket;
-    channel_disconnect_proc pre_disconnect;
     channel_disconnect_proc on_disconnect;
     channel_send_pipe_item_proc send_item;
     channel_hold_pipe_item_proc hold_item;
commit a7841325b22af56355ba353842d3c01b407f26d9
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Sat Mar 10 15:22:49 2012 +0100

    red_worker: Rework poll code to use the watch interface
    
    Commit 143a1df24e83e9c1e173c16aeb76d61ffdce9598 changed red_worker_main
    from epoll to poll. But epoll has edge triggered semantics (when requested
    and we requested them), where as poll is always level triggered. And
    red_worker was relying on the edge triggered semantics, as it was always
    polling for POLLOUT, which, when edge triggered, would only cause poll
    to register an event after we had blocked on a write. But after the
    switch to regular poll, with its level triggered semantics, the POLLOUT
    condition would almost always be true, causing red_worker_main to not
    block on the poll and burn CPU as fast as it can as soon as a client was
    connected.
    
    Luckily we already have a mechanism to switch from polling for read only
    to polling for read+write and back again in the form of watches. So this
    patch changes the red_worker dummy watch implementation into a proper watch
    implementation, and drops the entire EventListener concept since that then is
    no longer needed.
    
    This fixes spice-server using 400% CPU on my quad core machine as soon as
    a client was connected to a multi head vm, and as an added bonus is a nice
    cleanup IMHO.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/server/red_worker.c b/server/red_worker.c
index 3da5161..f7c6ccb 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -234,12 +234,11 @@ double inline stat_byte_to_mega(uint64_t size)
 #define MAX_EVENT_SOURCES 20
 #define INF_EVENT_WAIT ~0
 
-
-typedef struct EventListener EventListener;
-typedef void (*event_listener_action_proc)(EventListener *ctx, struct pollfd *pfd);
-struct EventListener {
-    event_listener_action_proc action;
-};
+typedef struct SpiceWatch {
+    struct RedWorker *worker;
+    SpiceWatchFunc watch_func;
+    void *watch_func_opaque;
+} SpiceWatch;
 
 enum {
     BUF_TYPE_RAW = 1,
@@ -577,7 +576,6 @@ typedef struct GlzSharedDictionary {
 
 typedef struct CommonChannel {
     RedChannel base; // Must be the first thing
-    event_listener_action_proc listener_action;
     struct RedWorker *worker;
     uint8_t recv_buf[RECIVE_BUF_SIZE];
     uint32_t id_alloc; // bitfield. TODO - use this instead of shift scheme.
@@ -585,7 +583,6 @@ typedef struct CommonChannel {
 
 typedef struct CommonChannelClient {
     RedChannelClient base;
-    EventListener listener;
     uint32_t id;
     struct RedWorker *worker;
 } CommonChannelClient;
@@ -864,7 +861,6 @@ typedef struct ItemTrace {
 #define NUM_CURSORS 100
 
 typedef struct RedWorker {
-    EventListener dev_listener;
     DisplayChannel *display_channel;
     CursorChannel *cursor_channel;
     QXLInstance *qxl;
@@ -875,7 +871,7 @@ typedef struct RedWorker {
     int running;
     uint32_t *pending;
     struct pollfd poll_fds[MAX_EVENT_SOURCES];
-    EventListener *listeners[MAX_EVENT_SOURCES];
+    struct SpiceWatch watches[MAX_EVENT_SOURCES];
     unsigned int event_timeout;
     uint32_t repoll_cmd_ring;
     uint32_t repoll_cursor_ring;
@@ -8719,22 +8715,6 @@ void red_show_tree(RedWorker *worker)
     }
 }
 
-static void poll_channel_client_pre_disconnect(RedChannelClient *rcc)
-{
-    CommonChannel *common;
-    int i;
-
-    common = SPICE_CONTAINEROF(rcc->channel, CommonChannel, base);
-    for (i = 0; i < MAX_EVENT_SOURCES; i++) {
-        struct pollfd *pfd = common->worker->poll_fds + i;
-        if (pfd->fd == rcc->stream->socket) {
-            pfd->fd = -1;
-            common->worker->listeners[i] = NULL;
-            break;
-        }
-    }
-}
-
 static void display_channel_client_on_disconnect(RedChannelClient *rcc)
 {
     DisplayChannel *display_channel;
@@ -9534,15 +9514,61 @@ static int common_channel_config_socket(RedChannelClient *rcc)
 
 static void worker_watch_update_mask(SpiceWatch *watch, int event_mask)
 {
+    struct RedWorker *worker = watch->worker;
+    int i = watch - worker->watches;
+
+    worker->poll_fds[i].events = 0;
+    if (event_mask & SPICE_WATCH_EVENT_READ) {
+        worker->poll_fds[i].events |= POLLIN;
+    }
+    if (event_mask & SPICE_WATCH_EVENT_WRITE) {
+        worker->poll_fds[i].events |= POLLOUT;
+    }
 }
 
 static SpiceWatch *worker_watch_add(int fd, int event_mask, SpiceWatchFunc func, void *opaque)
 {
-    return NULL; // apparently allowed?
+    /* Since we are a channel core implementation, we always get called from
+       red_channel_client_create(), so opaque always is our rcc */
+    RedChannelClient *rcc = opaque;
+    struct RedWorker *worker;
+    int i;
+
+    /* Since we are called from red_channel_client_create()
+       CommonChannelClient->worker has not been set yet! */
+    worker = SPICE_CONTAINEROF(rcc->channel, CommonChannel, base)->worker;
+
+    /* Search for a free slot in our poll_fds & watches arrays */
+    for (i = 0; i < MAX_EVENT_SOURCES; i++) {
+        if (worker->poll_fds[i].fd == -1) {
+            break;
+        }
+    }
+    if (i == MAX_EVENT_SOURCES) {
+        red_printf("ERROR could not add a watch for channel type %u id %u",
+                   rcc->channel->type, rcc->channel->id);
+        return NULL;
+    }
+
+    worker->poll_fds[i].fd = fd;
+    worker->watches[i].worker = worker;
+    worker->watches[i].watch_func = func;
+    worker->watches[i].watch_func_opaque = opaque;
+    worker_watch_update_mask(&worker->watches[i], event_mask);
+
+    return &worker->watches[i];
 }
 
 static void worker_watch_remove(SpiceWatch *watch)
 {
+    /* Note we don't touch the poll_fd here, to avoid the
+       poll_fds/watches table entry getting re-used in the same
+       red_worker_main loop over the fds as it is removed.
+
+       This is done because re-using it while events were pending on
+       the fd previously occupying the slot would lead to incorrectly
+       calling the watch_func for the new fd. */
+    memset(watch, 0, sizeof(SpiceWatch));
 }
 
 SpiceCoreInterface worker_core = {
@@ -9566,6 +9592,7 @@ static CommonChannelClient *common_channel_client_create(int size,
                                   num_common_caps, common_caps, num_caps, caps);
     CommonChannelClient *common_cc = (CommonChannelClient*)rcc;
     common_cc->worker = common->worker;
+    common_cc->id = common->worker->id;
 
     // TODO: move wide/narrow ack setting to red_channel.
     red_channel_client_ack_set_client_window(rcc,
@@ -9615,32 +9642,7 @@ CursorChannelClient *cursor_channel_create_rcc(CommonChannel *common,
     return ccc;
 }
 
-static int listen_to_new_client_channel(CommonChannel *common,
-    CommonChannelClient *common_cc, RedsStream *stream)
-{
-    int i;
-
-    common_cc->listener.action = common->listener_action;
-    ASSERT(common->base.clients_num);
-    common_cc->id = common->worker->id;
-    red_printf("NEW ID = %d", common_cc->id);
-
-    for (i = 0; i < MAX_EVENT_SOURCES; i++) {
-        struct pollfd *pfd = common->worker->poll_fds + i;
-        if (pfd->fd < 0) {
-            red_printf("new poll event %d (fd %d)", i, stream->socket);
-            pfd->fd = stream->socket;
-            pfd->events = POLLIN | POLLOUT;
-            common->worker->listeners[i] = &common_cc->listener;
-            return TRUE;
-        }
-    }
-    return FALSE;
-}
-
 static RedChannel *__new_channel(RedWorker *worker, int size, uint32_t channel_type, int migrate,
-                                 event_listener_action_proc handler,
-                                 channel_disconnect_proc pre_disconnect,
                                  channel_disconnect_proc on_disconnect,
                                  channel_send_pipe_item_proc send_item,
                                  channel_hold_pipe_item_proc hold_item,
@@ -9655,7 +9657,6 @@ static RedChannel *__new_channel(RedWorker *worker, int size, uint32_t channel_t
     ChannelCbs channel_cbs = { NULL, };
 
     channel_cbs.config_socket = common_channel_config_socket;
-    channel_cbs.pre_disconnect = pre_disconnect;
     channel_cbs.on_disconnect = on_disconnect;
     channel_cbs.send_item = send_item;
     channel_cbs.hold_item = hold_item;
@@ -9678,7 +9679,6 @@ static RedChannel *__new_channel(RedWorker *worker, int size, uint32_t channel_t
         goto error;
     }
     common->worker = worker;
-    common->listener_action = handler;
     return channel;
 
 error:
@@ -9686,20 +9686,6 @@ error:
     return NULL;
 }
 
-static void handle_channel_events(EventListener *in_listener, struct pollfd *pfd)
-{
-    CommonChannelClient *common_cc = SPICE_CONTAINEROF(in_listener, CommonChannelClient, listener);
-    RedChannelClient *rcc = &common_cc->base;
-
-    if ((pfd->events & POLLIN) && red_channel_client_is_connected(rcc)) {
-        red_channel_client_receive(rcc);
-    }
-
-    if (rcc->send_data.blocked && red_channel_client_is_connected(rcc)) {
-        red_channel_client_push(rcc);
-    }
-}
-
 static void display_channel_hold_pipe_item(RedChannelClient *rcc, PipeItem *item)
 {
     ASSERT(item);
@@ -9845,8 +9831,6 @@ static void display_channel_create(RedWorker *worker, int migrate)
     if (!(worker->display_channel = (DisplayChannel *)__new_channel(
             worker, sizeof(*display_channel),
             SPICE_CHANNEL_DISPLAY, migrate,
-            handle_channel_events,
-            poll_channel_client_pre_disconnect,
             display_channel_client_on_disconnect,
             display_channel_send_item,
             display_channel_hold_pipe_item,
@@ -9934,15 +9918,8 @@ static void handle_new_display_channel(RedWorker *worker, RedClient *client, Red
 
     // todo: tune level according to bandwidth
     display_channel->zlib_level = ZLIB_DEFAULT_COMPRESSION_LEVEL;
-    if (!listen_to_new_client_channel(&display_channel->common, &dcc->common, stream)) {
-        goto error;
-    }
     red_display_client_init_streams(dcc);
     on_new_display_channel_client(dcc);
-    return;
-
-error:
-    red_channel_client_destroy(&dcc->common.base);
 }
 
 static void cursor_channel_client_on_disconnect(RedChannelClient *rcc)
@@ -10060,8 +10037,6 @@ static void cursor_channel_create(RedWorker *worker, int migrate)
     worker->cursor_channel = (CursorChannel *)__new_channel(
         worker, sizeof(*worker->cursor_channel),
         SPICE_CHANNEL_CURSOR, migrate,
-        handle_channel_events,
-        poll_channel_client_pre_disconnect,
         cursor_channel_client_on_disconnect,
         cursor_channel_send_item,
         cursor_channel_hold_pipe_item,
@@ -10096,7 +10071,6 @@ static void red_connect_cursor(RedWorker *worker, RedClient *client, RedsStream
     channel->stat = stat_add_node(worker->stat, "cursor_channel", TRUE);
     channel->common.base.out_bytes_counter = stat_add_counter(channel->stat, "out_bytes", TRUE);
 #endif
-    listen_to_new_client_channel(&channel->common, &ccc->common, stream);
     on_new_cursor_channel(worker, &ccc->common.base);
 }
 
@@ -11040,9 +11014,9 @@ static void register_callbacks(Dispatcher *dispatcher)
 
 
 
-static void handle_dev_input(EventListener *listener, struct pollfd *pfd)
+static void handle_dev_input(int fd, int event, void *opaque)
 {
-    RedWorker *worker = SPICE_CONTAINEROF(listener, RedWorker, dev_listener);
+    RedWorker *worker = opaque;
 
     dispatcher_handle_recv_read(red_dispatcher_get_dispatcher(worker->red_dispatcher));
 }
@@ -11064,7 +11038,6 @@ static void red_init(RedWorker *worker, WorkerInitData *init_data)
     worker->channel = dispatcher_get_recv_fd(dispatcher);
     register_callbacks(dispatcher);
     worker->pending = init_data->pending;
-    worker->dev_listener.action = handle_dev_input;
     worker->cursor_visible = TRUE;
     ASSERT(init_data->num_renderers > 0);
     worker->num_renderers = init_data->num_renderers;
@@ -11097,7 +11070,9 @@ static void red_init(RedWorker *worker, WorkerInitData *init_data)
 
     worker->poll_fds[0].fd = worker->channel;
     worker->poll_fds[0].events = POLLIN;
-    worker->listeners[0] = &worker->dev_listener;
+    worker->watches[0].worker = worker;
+    worker->watches[0].watch_func = handle_dev_input;
+    worker->watches[0].watch_func_opaque = worker;
 
     red_memslot_info_init(&worker->mem_slots,
                           init_data->num_memslots_groups,
@@ -11160,17 +11135,30 @@ void *red_worker_main(void *arg)
             if (errno != EINTR) {
                 red_error("poll failed, %s", strerror(errno));
             }
-            num_events = 0;
         }
 
         for (i = 0; i < MAX_EVENT_SOURCES; i++) {
-            struct pollfd *pfd = worker.poll_fds + i;
-            if (pfd->revents) {
-                EventListener *evt_listener = worker.listeners[i];
-
-                if (evt_listener) {
-                    evt_listener->action(evt_listener, pfd);
+            /* The watch may have been removed by the watch-func from
+               another fd (ie a disconnect through the dispatcher),
+               in this case watch_func is NULL. */
+            if (worker.poll_fds[i].revents && worker.watches[i].watch_func) {
+                int events = 0;
+                if (worker.poll_fds[i].revents & POLLIN) {
+                    events |= SPICE_WATCH_EVENT_READ;
+                }
+                if (worker.poll_fds[i].revents & POLLOUT) {
+                    events |= SPICE_WATCH_EVENT_WRITE;
                 }
+                worker.watches[i].watch_func(worker.poll_fds[i].fd, events,
+                                        worker.watches[i].watch_func_opaque);
+            }
+        }
+
+        /* Clear the poll_fd for any removed watches, see the comment in
+           watch_remove for why we don't do this there. */
+        for (i = 0; i < MAX_EVENT_SOURCES; i++) {
+            if (!worker.watches[i].watch_func) {
+                worker.poll_fds[i].fd = -1;
             }
         }
 
commit b023f85ebda1e077d2456ce9e443ea6b3904d58f
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Sat Mar 10 13:59:30 2012 +0100

    red_channel: Use the channel core to remove the stream watch on disconnect
    
    We allow channels to have different core implementations, but we were
    relying on reds_stream_free to remove the stream watch on disconnect,
    and reds_stream_free always uses the qemu core implementation.
    
    So far we were getting away with this since all the alternative core
    implementations always return NULL from watch_add.
    
    But:
    1) The code before this patch clearly was not correct, since it was matching
       a channel-core watch_add with a qemu-core watch_remove
    2) I plan to move red_worker over to actually using an alternative watch
       implementation at which point this becomes a real problem
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/server/red_channel.c b/server/red_channel.c
index 13cc525..5f906e6 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -1194,6 +1194,10 @@ void red_channel_client_disconnect(RedChannelClient *rcc)
     if (rcc->channel->channel_cbs.pre_disconnect) {
         rcc->channel->channel_cbs.pre_disconnect(rcc);
     }
+    if (rcc->stream->watch) {
+        rcc->channel->core->watch_remove(rcc->stream->watch);
+        rcc->stream->watch = NULL;
+    }
     reds_stream_free(rcc->stream);
     rcc->stream = NULL;
     red_channel_remove_client(rcc);
commit 63e1514ccbcdbf122c4f61f5a9511db586b7ae0d
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Sat Mar 10 12:06:39 2012 +0100

    red_worker: Remove ref counting from the EventListener struct
    
    The red_worker EventListener struct is either embedded in one of:
    1) DisplayChannelClient
    2) CursorChannelClient
    3) RedWorker
    
    And as such gets destroyed when these get destroyed, in case 1 & 2 through
    a call to red_channel_client_destroy().
    
    So free-ing it when the ref-count becomes 0 is wrong, for cases:
    1) and 2) this will lead to a double free;
    3) this will lead to passing memory to free which was not returned by malloc.
    
    This is not causing any issues as the ref-count never gets decremented, other
    then in red_worker_main where it gets incremented before it gets decremented,
    so it never becomes 0.
    
    So we might just as well completely remove it.
    
    Notes:
    1) This is mainly a preparation patch for fixing issues introduced by
       the move from epoll to poll
    2) Since removing the ref-counting removes the one code path where listeners
       would get set to NULL, this patch moves the setting of NULL to
       pre_disconnect, where it should have been done in the first place since
       red_client_destroy calls red_channel_client_disconnect
       (through the dispatcher) followed by red_channel_client_destroy, so
       after pre_disconnect the listener may be gone.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/server/red_worker.c b/server/red_worker.c
index 6de95cb..3da5161 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -237,11 +237,8 @@ double inline stat_byte_to_mega(uint64_t size)
 
 typedef struct EventListener EventListener;
 typedef void (*event_listener_action_proc)(EventListener *ctx, struct pollfd *pfd);
-typedef void (*event_listener_free_proc)(EventListener *ctx);
 struct EventListener {
-    uint32_t refs;
     event_listener_action_proc action;
-    event_listener_free_proc free;
 };
 
 enum {
@@ -8732,6 +8729,7 @@ static void poll_channel_client_pre_disconnect(RedChannelClient *rcc)
         struct pollfd *pfd = common->worker->poll_fds + i;
         if (pfd->fd == rcc->stream->socket) {
             pfd->fd = -1;
+            common->worker->listeners[i] = NULL;
             break;
         }
     }
@@ -9534,14 +9532,6 @@ static int common_channel_config_socket(RedChannelClient *rcc)
     return TRUE;
 }
 
-static void free_common_cc_from_listener(EventListener *ctx)
-{
-    CommonChannelClient* common_cc = SPICE_CONTAINEROF(ctx, CommonChannelClient, listener);
-
-    red_printf("");
-    free(common_cc);
-}
-
 static void worker_watch_update_mask(SpiceWatch *watch, int event_mask)
 {
 }
@@ -9630,9 +9620,7 @@ static int listen_to_new_client_channel(CommonChannel *common,
 {
     int i;
 
-    common_cc->listener.refs = 1;
     common_cc->listener.action = common->listener_action;
-    common_cc->listener.free = free_common_cc_from_listener;
     ASSERT(common->base.clients_num);
     common_cc->id = common->worker->id;
     red_printf("NEW ID = %d", common_cc->id);
@@ -11059,11 +11047,6 @@ static void handle_dev_input(EventListener *listener, struct pollfd *pfd)
     dispatcher_handle_recv_read(red_dispatcher_get_dispatcher(worker->red_dispatcher));
 }
 
-static void handle_dev_free(EventListener *ctx)
-{
-    free(ctx);
-}
-
 static void red_init(RedWorker *worker, WorkerInitData *init_data)
 {
     RedWorkerMessage message;
@@ -11081,9 +11064,7 @@ static void red_init(RedWorker *worker, WorkerInitData *init_data)
     worker->channel = dispatcher_get_recv_fd(dispatcher);
     register_callbacks(dispatcher);
     worker->pending = init_data->pending;
-    worker->dev_listener.refs = 1;
     worker->dev_listener.action = handle_dev_input;
-    worker->dev_listener.free = handle_dev_free;
     worker->cursor_visible = TRUE;
     ASSERT(init_data->num_renderers > 0);
     worker->num_renderers = init_data->num_renderers;
@@ -11185,24 +11166,11 @@ void *red_worker_main(void *arg)
         for (i = 0; i < MAX_EVENT_SOURCES; i++) {
             struct pollfd *pfd = worker.poll_fds + i;
             if (pfd->revents) {
-                worker.listeners[i]->refs++;
-            }
-        }
-
-        for (i = 0; i < MAX_EVENT_SOURCES; i++) {
-            struct pollfd *pfd = worker.poll_fds + i;
-            if (pfd->revents) {
                 EventListener *evt_listener = worker.listeners[i];
 
-                if (evt_listener && evt_listener->refs > 1) {
+                if (evt_listener) {
                     evt_listener->action(evt_listener, pfd);
-                    if (--evt_listener->refs) {
-                        continue;
-                    }
                 }
-                red_printf("freeing event listener");
-                evt_listener->free(evt_listener);
-                worker.listeners[i] = NULL;
             }
         }
 
commit f24203e122c756e3b3ee540c718409451e4f9458
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Fri Mar 9 12:49:26 2012 +0100

    Ensure all members of ChannelCbs and ClientCbs are either assigned or NULL
    
    While git-bisecting another issue I ended up hitting and not recognizing
    the bug fixed by commit 7a079b452b026d6ce38f95dcc397fa64b059fffb.
    
    While fixing this (again) I noticed that (even after the fix) not all
    users of ChannelCbs first zero it. So this patch ensures that all users of
    ChannelCbs first zero it, and does the same for ClientCbs while at it.
    
    Since before this patch there were multiple zero-ing styles, some using
    memset and other using a zero initializer this patch also unifies all
    the zero-ing to use a NULL initializer for the first element.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/server/inputs_channel.c b/server/inputs_channel.c
index a3f26c0..932ead7 100644
--- a/server/inputs_channel.c
+++ b/server/inputs_channel.c
@@ -525,14 +525,11 @@ static void key_modifiers_sender(void *opaque)
 
 void inputs_init(void)
 {
-    ChannelCbs channel_cbs;
-    ClientCbs client_cbs;
+    ChannelCbs channel_cbs = { NULL, };
+    ClientCbs client_cbs = { NULL, };
 
     ASSERT(!g_inputs_channel);
 
-    memset(&channel_cbs, 0, sizeof(channel_cbs));
-    memset(&client_cbs, 0, sizeof(client_cbs));
-
     channel_cbs.config_socket = inputs_channel_config_socket;
     channel_cbs.on_disconnect = inputs_channel_on_disconnect;
     channel_cbs.send_item = inputs_channel_send_item;
diff --git a/server/main_channel.c b/server/main_channel.c
index a871bc8..a9fd24e 100644
--- a/server/main_channel.c
+++ b/server/main_channel.c
@@ -1062,7 +1062,7 @@ uint64_t main_channel_client_get_bitrate_per_sec(MainChannelClient *mcc)
 MainChannel* main_channel_init(void)
 {
     RedChannel *channel;
-    ChannelCbs channel_cbs = {0,};
+    ChannelCbs channel_cbs = { NULL, };
 
     channel_cbs.config_socket = main_channel_config_socket;
     channel_cbs.on_disconnect = main_channel_client_on_disconnect;
diff --git a/server/red_channel.c b/server/red_channel.c
index 2cd98da..13cc525 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -601,7 +601,7 @@ RedChannel *red_channel_create(int size,
                                ChannelCbs *channel_cbs)
 {
     RedChannel *channel;
-    ClientCbs client_cbs;
+    ClientCbs client_cbs = { NULL, };
 
     ASSERT(size >= sizeof(*channel));
     ASSERT(channel_cbs->config_socket && channel_cbs->on_disconnect && handle_message &&
@@ -668,7 +668,7 @@ SpiceCoreInterface dummy_core = {
 RedChannel *red_channel_create_dummy(int size, uint32_t type, uint32_t id)
 {
     RedChannel *channel;
-    ClientCbs client_cbs;
+    ClientCbs client_cbs = { NULL, };
 
     ASSERT(size >= sizeof(*channel));
     channel = spice_malloc0(size);
diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c
index 321232b..1aa619c 100644
--- a/server/red_dispatcher.c
+++ b/server/red_dispatcher.c
@@ -984,7 +984,7 @@ RedDispatcher *red_dispatcher_init(QXLInstance *qxl)
     RedChannel *cursor_channel;
     sigset_t thread_sig_mask;
     sigset_t curr_sig_mask;
-    ClientCbs client_cbs = {0,};
+    ClientCbs client_cbs = { NULL, };
 
     quic_init();
     sw_canvas_init();
diff --git a/server/red_tunnel_worker.c b/server/red_tunnel_worker.c
index 9162da4..80e0721 100644
--- a/server/red_tunnel_worker.c
+++ b/server/red_tunnel_worker.c
@@ -3474,8 +3474,8 @@ static void handle_tunnel_channel_client_migrate(RedChannelClient *rcc)
 static void red_tunnel_channel_create(TunnelWorker *worker)
 {
     RedChannel *channel;
-    ChannelCbs channel_cbs;
-    ClientCbs client_cbs = {0,};
+    ChannelCbs channel_cbs = { NULL, };
+    ClientCbs client_cbs = { NULL, };
 
     channel_cbs.config_socket = tunnel_channel_config_socket;
     channel_cbs.on_disconnect = tunnel_channel_client_on_disconnect;
diff --git a/server/red_worker.c b/server/red_worker.c
index a2f31c0..6de95cb 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -9664,7 +9664,7 @@ static RedChannel *__new_channel(RedWorker *worker, int size, uint32_t channel_t
 {
     RedChannel *channel = NULL;
     CommonChannel *common;
-    ChannelCbs channel_cbs;
+    ChannelCbs channel_cbs = { NULL, };
 
     channel_cbs.config_socket = common_channel_config_socket;
     channel_cbs.pre_disconnect = pre_disconnect;
diff --git a/server/smartcard.c b/server/smartcard.c
index facc4b3..84aa18b 100644
--- a/server/smartcard.c
+++ b/server/smartcard.c
@@ -512,14 +512,11 @@ SmartCardChannel *g_smartcard_channel;
 
 static void smartcard_init(void)
 {
-    ChannelCbs channel_cbs;
-    ClientCbs client_cbs;
+    ChannelCbs channel_cbs = { NULL, };
+    ClientCbs client_cbs = { NULL, };
 
     ASSERT(!g_smartcard_channel);
 
-    memset(&channel_cbs, 0, sizeof(channel_cbs));
-    memset(&client_cbs, 0, sizeof(client_cbs));
-
     channel_cbs.config_socket = smartcard_channel_client_config_socket;
     channel_cbs.on_disconnect = smartcard_channel_on_disconnect;
     channel_cbs.send_item = smartcard_channel_send_item;
diff --git a/server/snd_worker.c b/server/snd_worker.c
index aa1ceb7..4c51190 100644
--- a/server/snd_worker.c
+++ b/server/snd_worker.c
@@ -1464,7 +1464,7 @@ void snd_attach_playback(SpicePlaybackInstance *sin)
 {
     SndWorker *playback_worker;
     RedChannel *channel;
-    ClientCbs client_cbs = {0,};
+    ClientCbs client_cbs = { NULL, };
 
     sin->st = spice_new0(SpicePlaybackState, 1);
     sin->st->sin = sin;
@@ -1491,7 +1491,7 @@ void snd_attach_record(SpiceRecordInstance *sin)
 {
     SndWorker *record_worker;
     RedChannel *channel;
-    ClientCbs client_cbs = {0,};
+    ClientCbs client_cbs = { NULL, };
 
     sin->st = spice_new0(SpiceRecordState, 1);
     sin->st->sin = sin;
diff --git a/server/spicevmc.c b/server/spicevmc.c
index 30aaf2f..ea9271c 100644
--- a/server/spicevmc.c
+++ b/server/spicevmc.c
@@ -255,8 +255,8 @@ void spicevmc_device_connect(SpiceCharDeviceInstance *sin,
 {
     static uint8_t id[256] = { 0, };
     SpiceVmcState *state;
-    ChannelCbs channel_cbs = {0,};
-    ClientCbs client_cbs = {0,};
+    ChannelCbs channel_cbs = { NULL, };
+    ClientCbs client_cbs = { NULL, };
 
     channel_cbs.config_socket = spicevmc_red_channel_client_config_socket;
     channel_cbs.on_disconnect = spicevmc_red_channel_client_on_disconnect;


More information about the Spice-commits mailing list