Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Evergreen:11.1:Test
multipath-tools
multipath-tools-use-lists-for-uevent-processing
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File multipath-tools-use-lists-for-uevent-processing of Package multipath-tools
From 825076f0d9c5c58223dfe0b3336f9cfb9088110e Mon Sep 17 00:00:00 2001 From: Hannes Reinecke <hare@suse.de> Date: Wed, 25 Feb 2009 16:10:16 +0100 Subject: [PATCH] Use lists for uevent processing We now have proper list definitions, so we might as well use them for uevent processing. And we can clean up signalling, too; the pthreads condition signalling is unreliable, as a condition signal might be lost if we're in the middle of processing. So we should rather check the queue status prior to wait for a condition. References: 478874 Signed-off-by: Hannes Reinecke <hare@suse.de> --- libmultipath/uevent.c | 59 ++++++++++++++++++++++-------------------------- libmultipath/uevent.h | 2 +- 2 files changed, 28 insertions(+), 33 deletions(-) diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c index 19a71ad..86d5d11 100644 --- a/libmultipath/uevent.c +++ b/libmultipath/uevent.c @@ -37,15 +37,17 @@ #include <linux/netlink.h> #include <pthread.h> #include <sys/mman.h> +#include <errno.h> #include "memory.h" #include "debug.h" +#include "list.h" #include "uevent.h" typedef int (uev_trigger)(struct uevent *, void * trigger_data); pthread_t uevq_thr; -struct uevent *uevqhp, *uevqtp; +LIST_HEAD(uevq); pthread_mutex_t uevq_lock, *uevq_lockp = &uevq_lock; pthread_mutex_t uevc_lock, *uevc_lockp = &uevc_lock; pthread_cond_t uev_cond, *uev_condp = &uev_cond; @@ -60,29 +62,18 @@ struct uevent * alloc_uevent (void) void service_uevq(void) { - int empty; - struct uevent *uev; + struct uevent *uev, *tmp; - do { - pthread_mutex_lock(uevq_lockp); - empty = (uevqhp == NULL); - if (!empty) { - uev = uevqhp; - uevqhp = uev->next; - if (uevqtp == uev) - uevqtp = uev->next; - pthread_mutex_unlock(uevq_lockp); + list_for_each_entry_safe(uev, tmp, &uevq, node) { + list_del_init(&uev->node); + pthread_mutex_unlock(uevq_lockp); - if (my_uev_trigger && my_uev_trigger(uev, - my_trigger_data)) - condlog(0, "uevent trigger error"); + if (my_uev_trigger && my_uev_trigger(uev, my_trigger_data)) + condlog(0, "uevent trigger error"); - FREE(uev); - } - else { - pthread_mutex_unlock(uevq_lockp); - } - } while (empty == 0); + FREE(uev); + pthread_mutex_lock(uevq_lockp); + } } /* @@ -94,11 +85,20 @@ uevq_thread(void * et) mlockall(MCL_CURRENT | MCL_FUTURE); while (1) { - pthread_mutex_lock(uevc_lockp); - pthread_cond_wait(uev_condp, uevc_lockp); - pthread_mutex_unlock(uevc_lockp); - + pthread_mutex_lock(uevq_lockp); + /* + * Condition signals are unreliable, + * so make sure we only wait if we have to. + */ + if (list_empty(&uevq)) { + pthread_mutex_unlock(uevq_lockp); + pthread_mutex_lock(uevc_lockp); + pthread_cond_wait(uev_condp, uevc_lockp); + pthread_mutex_unlock(uevc_lockp); + pthread_mutex_lock(uevq_lockp); + } service_uevq(); + pthread_mutex_unlock(uevq_lockp); } } @@ -125,7 +125,7 @@ int uevent_listen(int (*uev_trigger)(struct uevent *, void * trigger_data), * thereby not getting to empty the socket's receive buffer queue * often enough. */ - uevqhp = uevqtp = NULL; + INIT_LIST_HEAD(&uevq); pthread_mutex_init(uevq_lockp, NULL); pthread_mutex_init(uevc_lockp, NULL); @@ -274,12 +274,7 @@ int uevent_listen(int (*uev_trigger)(struct uevent *, void * trigger_data), * Queue uevent and poke service pthread. */ pthread_mutex_lock(uevq_lockp); - if (uevqtp) - uevqtp->next = uev; - else - uevqhp = uev; - uevqtp = uev; - uev->next = NULL; + list_add(&uev->node, &uevq); pthread_mutex_unlock(uevq_lockp); pthread_mutex_lock(uevc_lockp); diff --git a/libmultipath/uevent.h b/libmultipath/uevent.h index ec6450b..27f225d 100644 --- a/libmultipath/uevent.h +++ b/libmultipath/uevent.h @@ -11,7 +11,7 @@ #endif struct uevent { - void *next; + struct list_head node; char buffer[HOTPLUG_BUFFER_SIZE + OBJECT_SIZE]; char *devpath; char *action; -- 1.6.0.2
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor