From: agk@sourceware.org
To: dm-cvs@sourceware.org, dm-devel@redhat.com
Subject: device-mapper/dmeventd dmeventd.c
Date: 16 Jan 2007 20:27:08 -0000 [thread overview]
Message-ID: <20070116202708.9667.qmail@sourceware.org> (raw)
CVSROOT: /cvs/dm
Module name: device-mapper
Changes by: agk@sourceware.org 2007-01-16 20:27:08
Modified files:
dmeventd : dmeventd.c
Log message:
clean up global mutex usage and fix a race in thread finalisation code
properly clean up thread status when thread terminates from within
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/device-mapper/dmeventd/dmeventd.c.diff?cvsroot=dm&r1=1.36&r2=1.37
--- device-mapper/dmeventd/dmeventd.c 2007/01/16 20:13:04 1.36
+++ device-mapper/dmeventd/dmeventd.c 2007/01/16 20:27:07 1.37
@@ -59,14 +59,21 @@
#define DAEMON_NAME "dmeventd"
-/* Global mutex for list accesses. */
+/*
+ Global mutex for thread list access. Has to be held when:
+ - iterating thread list
+ - adding or removing elements from thread list
+ - changing or reading thread_status's fields:
+ processing, status, events
+ Use _lock_mutex() and _unlock_mutex() to hold/release it
+*/
static pthread_mutex_t _global_mutex;
#define DM_THREAD_RUNNING 0
#define DM_THREAD_SHUTDOWN 1
#define DM_THREAD_DONE 2
-#define THREAD_STACK_SIZE 300*1024
+#define THREAD_STACK_SIZE (300*1024)
/* Data kept about a DSO. */
struct dso_data {
@@ -220,6 +227,9 @@
{
pthread_attr_t attr;
pthread_attr_init(&attr);
+ /*
+ * We use a smaller stack since it gets preallocated in its entirety
+ */
pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE);
return pthread_create(t, &attr, fun, arg);
}
@@ -318,7 +328,8 @@
return ret;
};
-/* Global mutex to lock access to lists et al. */
+/* Global mutex to lock access to lists et al. See _global_mutex
+ above. */
static int _lock_mutex(void)
{
return pthread_mutex_lock(&_global_mutex);
@@ -612,7 +623,7 @@
/* Thread cleanup handler to unregister device. */
static void _monitor_unregister(void *arg)
{
- struct thread_status *thread = arg;
+ struct thread_status *thread = arg, *thread_iter;
if (!_do_unregister_device(thread))
syslog(LOG_ERR, "%s: %s unregister failed\n", __func__,
@@ -620,6 +631,28 @@
if (thread->current_task)
dm_task_destroy(thread->current_task);
thread->current_task = NULL;
+
+ _lock_mutex();
+ if (thread->events & DM_EVENT_TIMEOUT) {
+ /* _unregister_for_timeout locks another mutex, we
+ don't want to deadlock so we release our mutex for
+ a bit */
+ _unlock_mutex();
+ _unregister_for_timeout(thread);
+ _lock_mutex();
+ }
+ /* we may have been relinked to unused registry since we were
+ called, so check that */
+ list_iterate_items(thread_iter, &_thread_registry_unused)
+ if (thread_iter == thread) {
+ thread->status = DM_THREAD_DONE;
+ _unlock_mutex();
+ return;
+ }
+ thread->status = DM_THREAD_DONE;
+ UNLINK_THREAD(thread);
+ LINK(thread, &_thread_registry_unused);
+ _unlock_mutex();
}
/* Device monitoring thread. */
@@ -686,10 +719,6 @@
}
}
- _lock_mutex();
- thread->status = DM_THREAD_DONE;
- _unlock_mutex();
-
pthread_cleanup_pop(1);
return NULL;
@@ -711,7 +740,7 @@
return pthread_kill(thread->thread, SIGALRM);
}
-/* DSO reference counting. */
+/* DSO reference counting. Call with _global_mutex locked! */
static void _lib_get(struct dso_data *data)
{
data->ref_count++;
@@ -731,8 +760,6 @@
{
struct dso_data *dso_data, *ret = NULL;
- _lock_mutex();
-
list_iterate_items(dso_data, &_dso_registry)
if (!strcmp(data->dso_name, dso_data->dso_name)) {
_lib_get(dso_data);
@@ -740,8 +767,6 @@
break;
}
- _unlock_mutex();
-
return ret;
}
@@ -922,6 +947,13 @@
goto out;
}
+ if (thread->status == DM_THREAD_DONE) {
+ /* the thread has terminated while we were not
+ watching */
+ _unlock_mutex();
+ return 0;
+ }
+
thread->events &= ~message_data->events.field;
if (!(thread->events & DM_EVENT_TIMEOUT))
next reply other threads:[~2007-01-16 20:27 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-01-16 20:27 agk [this message]
-- strict thread matches above, loose matches on Subject: below --
2008-07-09 13:26 device-mapper/dmeventd dmeventd.c mornfall
2007-04-24 13:29 mornfall
2007-01-19 18:08 agk
2007-01-16 20:13 agk
2007-01-15 22:37 agk
2007-01-15 19:19 agk
2007-01-15 18:58 agk
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070116202708.9667.qmail@sourceware.org \
--to=agk@sourceware.org \
--cc=dm-cvs@sourceware.org \
--cc=dm-devel@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox