[Xenomai-git] Philippe Gerum : copperplate/threadobj: fix suspend vs deletion race ( mercury)

2014-01-09 Thread git repository hosting
Module: xenomai-forge
Branch: next
Commit: 0b0888a2022a3acd215992b03262c32ca6ad7c36
URL:
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=0b0888a2022a3acd215992b03262c32ca6ad7c36

Author: Philippe Gerum r...@xenomai.org
Date:   Thu Jan  9 10:47:22 2014 +0100

copperplate/threadobj: fix suspend vs deletion race (mercury)

Over Mercury, the notifier wait action should not be entered if a
cancellation request is pending. Otherwise, the thread pending
deletion would sleep in notifier_wait(), with the requestor waiting in
cancel_sync(), both indefinitely.

---

 include/copperplate/threadobj.h |1 +
 lib/copperplate/threadobj.c |   19 ++-
 2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/include/copperplate/threadobj.h b/include/copperplate/threadobj.h
index 184c711..218c274 100644
--- a/include/copperplate/threadobj.h
+++ b/include/copperplate/threadobj.h
@@ -124,6 +124,7 @@ void threadobj_save_timeout(struct threadobj_corespec 
*corespec,
 #define __THREAD_S_ACTIVE  (1  5)/* Running user code. */
 #define __THREAD_S_SUSPENDED   (1  6)/* Suspended via 
threadobj_suspend(). */
 #define __THREAD_S_SAFE(1  7)/* TCB release 
deferred. */
+#define __THREAD_S_ZOMBIE  (1  8)/* Deletion process ongoing. */
 #define __THREAD_S_DEBUG   (1  31)   /* Debug mode enabled. */
 /*
  * threadobj-run_state, locklessly updated by current, merged
diff --git a/lib/copperplate/threadobj.c b/lib/copperplate/threadobj.c
index a31479c..c54cdf8 100644
--- a/lib/copperplate/threadobj.c
+++ b/lib/copperplate/threadobj.c
@@ -420,11 +420,13 @@ static void notifier_callback(const struct notifier *nf)
 * threadobj_suspend().
 */
threadobj_lock(current);
-   current-status |= __THREAD_S_SUSPENDED;
-   threadobj_unlock(current);
-   notifier_wait(nf); /* Wait for threadobj_resume(). */
-   threadobj_lock(current);
-   current-status = ~__THREAD_S_SUSPENDED;
+   if ((current-status  __THREAD_S_ZOMBIE) == 0) {
+   current-status |= __THREAD_S_SUSPENDED;
+   threadobj_unlock(current);
+   notifier_wait(nf); /* Wait for threadobj_resume(). */
+   threadobj_lock(current);
+   current-status = ~__THREAD_S_SUSPENDED;
+   }
threadobj_unlock(current);
 }
 
@@ -488,7 +490,7 @@ static inline void threadobj_run_corespec(struct threadobj 
*thobj)
 {
 }
 
-static inline void threadobj_cancel_corespec(struct threadobj *thobj)
+static inline void threadobj_cancel_corespec(struct threadobj *thobj) /* 
thobj-lock held */
 {
 }
 
@@ -872,9 +874,9 @@ void threadobj_init(struct threadobj *thobj,
 
 static void destroy_thread(struct threadobj *thobj)
 {
+   threadobj_cleanup_corespec(thobj);
__RT(pthread_cond_destroy(thobj-barrier));
__RT(pthread_mutex_destroy(thobj-lock));
-   threadobj_cleanup_corespec(thobj);
 }
 
 void threadobj_destroy(struct threadobj *thobj) /* thobj-lock free */
@@ -1089,8 +1091,6 @@ static void cancel_sync(struct threadobj *thobj) /* 
thobj-lock held */
int oldstate, ret = 0;
sem_t *sem;
 
-   __threadobj_check_locked(thobj);
-
/*
 * We have to allocate the cancel sync sema4 in the main heap
 * dynamically, so that it always live in valid memory when we
@@ -1106,6 +1106,7 @@ static void cancel_sync(struct threadobj *thobj) /* 
thobj-lock held */
__STD(sem_init(sem, sem_scope_attribute, 0));
 
thobj-cancel_sem = sem;
+   thobj-status |= __THREAD_S_ZOMBIE;
 
/*
 * If the thread to delete is warming up, wait until it


___
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git


[Xenomai-git] Philippe Gerum : copperplate/threadobj: fix suspend vs deletion race ( mercury)

2014-01-09 Thread git repository hosting
Module: xenomai-forge
Branch: master
Commit: 0b0888a2022a3acd215992b03262c32ca6ad7c36
URL:
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=0b0888a2022a3acd215992b03262c32ca6ad7c36

Author: Philippe Gerum r...@xenomai.org
Date:   Thu Jan  9 10:47:22 2014 +0100

copperplate/threadobj: fix suspend vs deletion race (mercury)

Over Mercury, the notifier wait action should not be entered if a
cancellation request is pending. Otherwise, the thread pending
deletion would sleep in notifier_wait(), with the requestor waiting in
cancel_sync(), both indefinitely.

---

 include/copperplate/threadobj.h |1 +
 lib/copperplate/threadobj.c |   19 ++-
 2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/include/copperplate/threadobj.h b/include/copperplate/threadobj.h
index 184c711..218c274 100644
--- a/include/copperplate/threadobj.h
+++ b/include/copperplate/threadobj.h
@@ -124,6 +124,7 @@ void threadobj_save_timeout(struct threadobj_corespec 
*corespec,
 #define __THREAD_S_ACTIVE  (1  5)/* Running user code. */
 #define __THREAD_S_SUSPENDED   (1  6)/* Suspended via 
threadobj_suspend(). */
 #define __THREAD_S_SAFE(1  7)/* TCB release 
deferred. */
+#define __THREAD_S_ZOMBIE  (1  8)/* Deletion process ongoing. */
 #define __THREAD_S_DEBUG   (1  31)   /* Debug mode enabled. */
 /*
  * threadobj-run_state, locklessly updated by current, merged
diff --git a/lib/copperplate/threadobj.c b/lib/copperplate/threadobj.c
index a31479c..c54cdf8 100644
--- a/lib/copperplate/threadobj.c
+++ b/lib/copperplate/threadobj.c
@@ -420,11 +420,13 @@ static void notifier_callback(const struct notifier *nf)
 * threadobj_suspend().
 */
threadobj_lock(current);
-   current-status |= __THREAD_S_SUSPENDED;
-   threadobj_unlock(current);
-   notifier_wait(nf); /* Wait for threadobj_resume(). */
-   threadobj_lock(current);
-   current-status = ~__THREAD_S_SUSPENDED;
+   if ((current-status  __THREAD_S_ZOMBIE) == 0) {
+   current-status |= __THREAD_S_SUSPENDED;
+   threadobj_unlock(current);
+   notifier_wait(nf); /* Wait for threadobj_resume(). */
+   threadobj_lock(current);
+   current-status = ~__THREAD_S_SUSPENDED;
+   }
threadobj_unlock(current);
 }
 
@@ -488,7 +490,7 @@ static inline void threadobj_run_corespec(struct threadobj 
*thobj)
 {
 }
 
-static inline void threadobj_cancel_corespec(struct threadobj *thobj)
+static inline void threadobj_cancel_corespec(struct threadobj *thobj) /* 
thobj-lock held */
 {
 }
 
@@ -872,9 +874,9 @@ void threadobj_init(struct threadobj *thobj,
 
 static void destroy_thread(struct threadobj *thobj)
 {
+   threadobj_cleanup_corespec(thobj);
__RT(pthread_cond_destroy(thobj-barrier));
__RT(pthread_mutex_destroy(thobj-lock));
-   threadobj_cleanup_corespec(thobj);
 }
 
 void threadobj_destroy(struct threadobj *thobj) /* thobj-lock free */
@@ -1089,8 +1091,6 @@ static void cancel_sync(struct threadobj *thobj) /* 
thobj-lock held */
int oldstate, ret = 0;
sem_t *sem;
 
-   __threadobj_check_locked(thobj);
-
/*
 * We have to allocate the cancel sync sema4 in the main heap
 * dynamically, so that it always live in valid memory when we
@@ -1106,6 +1106,7 @@ static void cancel_sync(struct threadobj *thobj) /* 
thobj-lock held */
__STD(sem_init(sem, sem_scope_attribute, 0));
 
thobj-cancel_sem = sem;
+   thobj-status |= __THREAD_S_ZOMBIE;
 
/*
 * If the thread to delete is warming up, wait until it


___
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git