[libvirt] PATCH: Remove linked list of clients in favour of an array

More preparation for multi-thread support, this time in the libvirtd daemon. This removes the embedded linked list of 'struct qemud_client' and replaces it with an explicit array of pointers of client objects. This makes per-client locking more practical in a patch to follow. This touches suprisingly little code :-) qemud.c | 43 ++++++++++++++++++++++++------------------- qemud.h | 4 +--- 2 files changed, 25 insertions(+), 22 deletions(-) Daniel diff --git a/qemud/qemud.c b/qemud/qemud.c --- a/qemud/qemud.c +++ b/qemud/qemud.c @@ -1086,6 +1086,12 @@ static int qemudDispatchServer(struct qe return -1; } + if (VIR_REALLOC_N(server->clients, server->nclients+1) < 0) { + qemudLog(QEMUD_ERR, "%s", _("Out of memory allocating clients")); + close(fd); + return -1; + } + /* Disable Nagle. Unix sockets will ignore this. */ setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (void *)&no_slow_start, sizeof no_slow_start); @@ -1165,9 +1171,7 @@ static int qemudDispatchServer(struct qe } } - client->next = server->clients; - server->clients = client; - server->nclients++; + server->clients[server->nclients++] = client; return 0; @@ -1182,19 +1186,19 @@ static int qemudDispatchServer(struct qe static void qemudDispatchClientFailure(struct qemud_server *server, struct qemud_client *client) { - struct qemud_client *tmp = server->clients; - struct qemud_client *prev = NULL; - while (tmp) { - if (tmp == client) { - if (prev == NULL) - server->clients = client->next; - else - prev->next = client->next; - server->nclients--; + int i, n = -1; + for (i = 0 ; i < server->nclients ; i++) { + if (server->clients[i] == client) { + n = i; break; } - prev = tmp; - tmp = tmp->next; + } + if (n != -1) { + if (n < (server->nclients-1)) + memmove(server->clients + n, + server->clients + n + 1, + server->nclients - (n + 1)); + server->nclients--; } virEventRemoveHandleImpl(client->fd); @@ -1554,13 +1558,14 @@ static void qemudDispatchClientWrite(str static void qemudDispatchClientEvent(int fd, int events, void *opaque) { struct qemud_server *server = (struct qemud_server *)opaque; - struct qemud_client *client = server->clients; + struct qemud_client *client = NULL; + int i; - while (client) { - if (client->fd == fd) + for (i = 0 ; i < server->nclients ; i++) { + if (server->clients[i]->fd == fd) { + client = server->clients[i]; break; - - client = client->next; + } } if (!client) diff --git a/qemud/qemud.h b/qemud/qemud.h --- a/qemud/qemud.h +++ b/qemud/qemud.h @@ -131,8 +131,6 @@ struct qemud_client { * called, it will be set back to NULL if that succeeds. */ virConnectPtr conn; - - struct qemud_client *next; }; #define QEMUD_CLIENT_MAGIC 0x7788aaee @@ -152,7 +150,7 @@ struct qemud_server { int nsockets; struct qemud_socket *sockets; int nclients; - struct qemud_client *clients; + struct qemud_client **clients; int sigread; char logDir[PATH_MAX]; unsigned int shutdown : 1; -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

On Fri, Oct 17, 2008 at 11:51:42AM +0100, Daniel P. Berrange wrote:
More preparation for multi-thread support, this time in the libvirtd daemon. This removes the embedded linked list of 'struct qemud_client' and replaces it with an explicit array of pointers of client objects. This makes per-client locking more practical in a patch to follow. This touches suprisingly little code :-)
+1 I still think a bunch of shared macros to do the array allocations would be nice as we convert the structures, with 2 things in mind: - the memmove on removal scares me, it's rather complex, I would prefer to have it good for once and not look at those anymore - would potentially allow to avoid realloc'ing each time we add or remove, I have no doubt glibc works very well in such case, but other implementations may not be that nice. Like for the memory allocations, we went though a lot of churn, and finally settled for macros simplifying everything in the end. Maybe we can avoid the extra steps this time ;-) Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/
participants (2)
-
Daniel P. Berrange
-
Daniel Veillard