From nobody Wed May 14 16:05:04 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 152087174010221.59809022340221; Mon, 12 Mar 2018 09:22:20 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7437613AAE; Mon, 12 Mar 2018 16:22:17 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 43F7A17140; Mon, 12 Mar 2018 16:22:17 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id EAE2E180BAED; Mon, 12 Mar 2018 16:22:16 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w2CGM0HO025090 for ; Mon, 12 Mar 2018 12:22:00 -0400 Received: by smtp.corp.redhat.com (Postfix) id C1C4D2166BB2; Mon, 12 Mar 2018 16:22:00 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.152]) by smtp.corp.redhat.com (Postfix) with ESMTP id 68FC7215CDAE for ; Mon, 12 Mar 2018 16:22:00 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Mon, 12 Mar 2018 17:21:48 +0100 Message-Id: <57091a3e5e81e11e521fd796da3e2e0c63d624b0.1520871530.git.phrdina@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-loop: libvir-list@redhat.com Subject: [libvirt] [dbus PATCH 18/18] main: introduce threads to process the dbus messages X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Mon, 12 Mar 2018 16:22:17 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" This implements very simple thread pool to process dbus messages in separate threads. We don't need to handle queue for messages because dbus does that for us. The default thread count will be currently 4 and it is also configurable via --threads parameter for the libvirt-dbus daemon. Signed-off-by: Pavel Hrdina --- src/Makefile.am | 1 + src/connect.c | 14 +++++++ src/connect.h | 3 ++ src/main.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++++---= ---- src/util.c | 28 ++++++++++++++ src/util.h | 9 +++++ 6 files changed, 159 insertions(+), 14 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 9e23f1b..73bbfd9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -32,6 +32,7 @@ libvirt_dbus_LDFLAGS =3D \ $(DBUS_LDFLAGS) \ $(RELRO_LDFLAGS) \ $(PID_LDFLAGS) \ + -lpthread \ $(NULL) =20 libvirt_dbus_LDADD =3D \ diff --git a/src/connect.c b/src/connect.c index 2fe305f..41aba5f 100644 --- a/src/connect.c +++ b/src/connect.c @@ -56,10 +56,21 @@ virtDBusConnectClose(virtDBusConnect *connect, connect->connection =3D NULL; } =20 +static void +virtDBusConnectUnlock(pthread_mutex_t **lock) +{ + if (lock) + pthread_mutex_unlock(*lock); +} + int virtDBusConnectOpen(virtDBusConnect *connect, virtDBusMessage *msg) { + _cleanup_(virtDBusConnectUnlock) pthread_mutex_t *lock =3D &connect->l= ock; + + pthread_mutex_lock(lock); + if (connect->connection) { if (virConnectIsAlive(connect->connection)) return 0; @@ -212,6 +223,9 @@ virtDBusConnectNew(virtDBusConnect **connectp, connect->uri =3D uri; connect->connectPath =3D connectPath; =20 + if (virtDBusUtilMutexInit(&connect->lock) !=3D 0) + return -1; + if (virtDBusObjectListRegister(objectList, connect->connectPath, &introspectXML, diff --git a/src/connect.h b/src/connect.h index e685b41..c6026c9 100644 --- a/src/connect.h +++ b/src/connect.h @@ -4,10 +4,13 @@ =20 #include #include +#include =20 #define VIRT_DBUS_CONNECT_INTERFACE "org.libvirt.Connect" =20 struct _virtDBusConnect { + pthread_mutex_t lock; + DBusConnection *bus; const char *uri; const char *connectPath; diff --git a/src/main.c b/src/main.c index bef5dcc..1808620 100644 --- a/src/main.c +++ b/src/main.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -16,21 +17,98 @@ #include #include =20 +#define VIRT_DBUS_THREADS 4 + static int loop_status =3D 0; +static pthread_mutex_t loopStatusLock =3D PTHREAD_MUTEX_INITIALIZER; + +static int +virtDBusLoopStatusGet(void) +{ + int ret; + pthread_mutex_lock(&loopStatusLock); + ret =3D loop_status; + pthread_mutex_unlock(&loopStatusLock); + return ret; +} + +static void +virtDBusLoopStatusSet(int val) +{ + pthread_mutex_lock(&loopStatusLock); + loop_status =3D val; + pthread_mutex_unlock(&loopStatusLock); +} + +struct _virtDBusDispatchData { + DBusConnection *bus; + virtDBusObjectList *objectList; +}; + +static pthread_cond_t threadLoopCond; +static pthread_mutex_t threadLoopLock; =20 static int virtDBusProcessEvents(DBusConnection *bus, virtDBusObjectList *objectList) { for (;;) { - int r; + int r; =20 - r =3D virtDBusDispatchMessage(bus, objectList); - if (r < 0) - return r; + r =3D virtDBusDispatchMessage(bus, objectList); + if (r < 0) + return r; =20 - if (r =3D=3D 0) - break; + if (r =3D=3D 0) + break; + } + + return 0; +} + +static void * +virtDBusDispatchThread(void *opaque) +{ + struct _virtDBusDispatchData *data =3D opaque; + + while(true) { + if (pthread_cond_wait(&threadLoopCond, &threadLoopLock) !=3D 0) { + virtDBusLoopStatusSet(errno); + return NULL; + } + if (virtDBusLoopStatusGet() !=3D 0) + return NULL; + + if (virtDBusProcessEvents(data->bus, data->objectList) < 0) { + virtDBusLoopStatusSet(-ENOMEM); + return NULL; + } + } + + return NULL; +} + +static void +virtDBusDispatch(void) +{ + pthread_cond_broadcast(&threadLoopCond); +} + +static int +virtDBusStartThreads(struct _virtDBusDispatchData *data, + int threads) +{ + if (pthread_cond_init(&threadLoopCond, NULL) !=3D 0) + return -1; + + if (virtDBusUtilMutexInit(&threadLoopLock) !=3D 0) + return -1; + + for (int i =3D 0; i < threads; i++) { + pthread_t thread; + + if (pthread_create(&thread, NULL, virtDBusDispatchThread, data) != =3D 0) + return -1; } =20 return 0; @@ -49,7 +127,7 @@ virtDBusHandleSignal(int watch VIRT_ATTR_UNUSED, int events VIRT_ATTR_UNUSED, void *opaque VIRT_ATTR_UNUSED) { - loop_status =3D -ECANCELED; + virtDBusLoopStatusSet(-ECANCELED); } =20 struct virtDBusDriver { @@ -91,6 +169,7 @@ main(int argc, char *argv[]) { "help", no_argument, NULL, 'h' }, { "system", no_argument, NULL, ARG_SYSTEM }, { "session", no_argument, NULL, ARG_SESSION }, + { "threads", required_argument, NULL, 't' }, {} }; =20 @@ -106,6 +185,7 @@ main(int argc, char *argv[]) sigset_t mask; int c; int r; + int threads =3D VIRT_DBUS_THREADS; =20 if (geteuid() =3D=3D 0) { busType =3D DBUS_BUS_SYSTEM; @@ -113,7 +193,7 @@ main(int argc, char *argv[]) busType =3D DBUS_BUS_SESSION; } =20 - while ((c =3D getopt_long(argc, argv, "hc:", options, NULL)) >=3D 0) { + while ((c =3D getopt_long(argc, argv, "ht:", options, NULL)) >=3D 0) { switch (c) { case 'h': printf("Usage: %s [OPTIONS]\n", program_invocation_short_n= ame); @@ -123,8 +203,16 @@ main(int argc, char *argv[]) printf(" -h, --help Display this help text and exi= t\n"); printf(" --session Connect to the session bus\n"); printf(" --system Connect to the system bus\n"); + printf(" -t, --threads Configure count of worker thre= ads\n"); return 0; =20 + case 't': + if (virtDBusUtilStrToInt(optarg, 10, &threads) < 0) { + fprintf(stderr, "Failed to parse --threads.\n"); + return EXIT_FAILURE; + } + break; + case ARG_SYSTEM: busType =3D DBUS_BUS_SYSTEM; break; @@ -179,11 +267,13 @@ main(int argc, char *argv[]) return EXIT_FAILURE; } =20 - r =3D virtDBusProcessEvents(bus, &objectList); - if (r < 0) - return EXIT_FAILURE; + struct _virtDBusDispatchData data =3D { bus, &objectList }; + + virtDBusStartThreads(&data, threads); + + virtDBusDispatch(); =20 - while (loop_status >=3D 0) { + while ((r =3D virtDBusLoopStatusGet()) >=3D 0) { virEventRunDefaultImpl(); =20 r =3D virtDBusProcessEvents(bus, &objectList); @@ -191,8 +281,8 @@ main(int argc, char *argv[]) return EXIT_FAILURE; } =20 - if (loop_status < 0 && loop_status !=3D -ECANCELED) { - fprintf(stderr, "Error: %s\n", strerror(-loop_status)); + if (r < 0 && r !=3D -ECANCELED) { + fprintf(stderr, "Error: %s\n", strerror(-r)); return EXIT_FAILURE; } =20 diff --git a/src/util.c b/src/util.c index 6f8b7be..fe9e023 100644 --- a/src/util.c +++ b/src/util.c @@ -2,6 +2,7 @@ =20 #include "util.h" =20 +#include #include #include #include @@ -90,6 +91,33 @@ virtDBusUtilSetLastVirtError(virtDBusMessage *msg) virError->message); } =20 +int +virtDBusUtilMutexInit(pthread_mutex_t *mutex) +{ + _cleanup_(pthread_mutexattr_destroy) pthread_mutexattr_t attr; + + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); + return pthread_mutex_init(mutex, &attr); +} + +int +virtDBusUtilStrToInt(char const *string, + int base, + int *result) +{ + long int val; + char *ptr; + + errno =3D 0; + val =3D strtol(string, &ptr, base); + if (errno !=3D 0 || *ptr !=3D 0 || ptr =3D=3D string || (int) val !=3D= val) + return -1; + + *result =3D val; + return 0; +} + char * virtDBusUtilReadFile(const char *filename) { diff --git a/src/util.h b/src/util.h index 16c54df..afb118c 100644 --- a/src/util.h +++ b/src/util.h @@ -3,6 +3,7 @@ #include "dbus.h" =20 #include +#include =20 #define VIRT_DBUS_ERROR_INTERFACE "org.libvirt.Error" =20 @@ -26,6 +27,14 @@ virtDBusUtilMessageAppendTypedParameters(virtDBusMessage= *msg, int virtDBusUtilSetLastVirtError(virtDBusMessage *msg); =20 +int +virtDBusUtilMutexInit(pthread_mutex_t *mutex); + +int +virtDBusUtilStrToInt(char const *string, + int base, + int *result); + char * virtDBusUtilReadFile(const char *filename); =20 --=20 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list