[Xenomai-git] Philippe Gerum : cobalt/posix/thread: fix error handling upon failure to map shadow

2015-02-12 Thread git repository hosting
Module: xenomai-3
Branch: master
Commit: 7a81ea81d92e33ff4d78b01646ebb8af070d7e4a
URL:
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=7a81ea81d92e33ff4d78b01646ebb8af070d7e4a

Author: Philippe Gerum 
Date:   Thu Nov 27 22:02:32 2014 +0100

cobalt/posix/thread: fix error handling upon failure to map shadow

---

 include/cobalt/kernel/thread.h |2 ++
 kernel/cobalt/posix/thread.c   |   36 +++-
 kernel/cobalt/thread.c |   19 +++
 3 files changed, 48 insertions(+), 9 deletions(-)

diff --git a/include/cobalt/kernel/thread.h b/include/cobalt/kernel/thread.h
index 72168f4..535489b 100644
--- a/include/cobalt/kernel/thread.h
+++ b/include/cobalt/kernel/thread.h
@@ -332,6 +332,8 @@ void __xnthread_test_cancel(struct xnthread *curr);
 
 void __xnthread_cleanup(struct xnthread *curr);
 
+void __xnthread_discard(struct xnthread *thread);
+
 /**
  * @fn struct xnthread *xnthread_current(void)
  * @brief Retrieve the current Cobalt core TCB.
diff --git a/kernel/cobalt/posix/thread.c b/kernel/cobalt/posix/thread.c
index 3ab20f6..7c78405 100644
--- a/kernel/cobalt/posix/thread.c
+++ b/kernel/cobalt/posix/thread.c
@@ -345,10 +345,10 @@ unlock_and_exit:
return 0;
 }
 
-static inline int pthread_create(struct cobalt_thread **thread_p,
-int policy,
-const struct sched_param_ex *param_ex,
-struct task_struct *task)
+static int pthread_create(struct cobalt_thread **thread_p,
+ int policy,
+ const struct sched_param_ex *param_ex,
+ struct task_struct *task)
 {
struct xnsched_class *sched_class;
union xnsched_policy_param param;
@@ -416,6 +416,20 @@ static inline int pthread_create(struct cobalt_thread 
**thread_p,
return 0;
 }
 
+static void pthread_discard(struct cobalt_thread *thread)
+{
+   spl_t s;
+
+   xnsynch_destroy(&thread->monitor_synch);
+   xnsynch_destroy(&thread->sigwait);
+
+   xnlock_get_irqsave(&nklock, s);
+   list_del(&thread->link);
+   xnlock_put_irqrestore(&nklock, s);
+   __xnthread_discard(&thread->threadbase);
+   xnfree(thread);
+}
+
 static inline int pthread_setmode_np(int clrmask, int setmask, int *mode_r)
 {
const int valid_flags = XNLOCK|XNWARN|XNTRAPLB;
@@ -566,8 +580,10 @@ int __cobalt_thread_create(unsigned long pth, int policy,
return ret;
 
ret = cobalt_map_user(&thread->threadbase, u_winoff);
-   if (ret)
-   goto fail;
+   if (ret) {
+   pthread_discard(thread);
+   return ret;
+   }
 
if (!thread_hash(&hkey, thread, task_pid_vnr(p))) {
ret = -EAGAIN;
@@ -617,11 +633,13 @@ cobalt_thread_shadow(struct task_struct *p,
trace_cobalt_pthread_create(hkey->u_pth, SCHED_NORMAL, ¶m_ex);
ret = pthread_create(&thread, SCHED_NORMAL, ¶m_ex, p);
if (ret)
-   return ERR_PTR(-ret);
+   return ERR_PTR(ret);
 
ret = cobalt_map_user(&thread->threadbase, u_winoff);
-   if (ret)
-   goto fail;
+   if (ret) {
+   pthread_discard(thread);
+   return ERR_PTR(ret);
+   }
 
if (!thread_hash(hkey, thread, task_pid_vnr(p))) {
ret = -EAGAIN;
diff --git a/kernel/cobalt/thread.c b/kernel/cobalt/thread.c
index f5444d3..e7726dd 100644
--- a/kernel/cobalt/thread.c
+++ b/kernel/cobalt/thread.c
@@ -492,6 +492,25 @@ void __xnthread_cleanup(struct xnthread *curr)
wake_up(&nkjoinq);
 }
 
+/*
+ * Unwinds xnthread_init() ops for an unmapped thread.  Since the
+ * latter must be dormant, it can't be part of any runqueue.
+ */
+void __xnthread_discard(struct xnthread *thread)
+{
+   spl_t s;
+
+   xntimer_destroy(&thread->rtimer);
+   xntimer_destroy(&thread->ptimer);
+
+   xnlock_get_irqsave(&nklock, s);
+   list_del(&thread->glink);
+   nknrthreads--;
+   xnvfile_touch_tag(&nkthreadlist_tag);
+   xnthread_deregister(thread);
+   xnlock_put_irqrestore(&nklock, s);
+}
+
 /**
  * @fn void xnthread_init(struct xnthread *thread,const struct 
xnthread_init_attr *attr,struct xnsched_class *sched_class,const union 
xnsched_policy_param *sched_param)
  * @brief Initialize a new thread.


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


[Xenomai-git] Philippe Gerum : cobalt/posix/thread: fix error handling upon failure to map shadow

2014-11-27 Thread git repository hosting
Module: xenomai-3
Branch: next
Commit: 7a81ea81d92e33ff4d78b01646ebb8af070d7e4a
URL:
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=7a81ea81d92e33ff4d78b01646ebb8af070d7e4a

Author: Philippe Gerum 
Date:   Thu Nov 27 22:02:32 2014 +0100

cobalt/posix/thread: fix error handling upon failure to map shadow

---

 include/cobalt/kernel/thread.h |2 ++
 kernel/cobalt/posix/thread.c   |   36 +++-
 kernel/cobalt/thread.c |   19 +++
 3 files changed, 48 insertions(+), 9 deletions(-)

diff --git a/include/cobalt/kernel/thread.h b/include/cobalt/kernel/thread.h
index 72168f4..535489b 100644
--- a/include/cobalt/kernel/thread.h
+++ b/include/cobalt/kernel/thread.h
@@ -332,6 +332,8 @@ void __xnthread_test_cancel(struct xnthread *curr);
 
 void __xnthread_cleanup(struct xnthread *curr);
 
+void __xnthread_discard(struct xnthread *thread);
+
 /**
  * @fn struct xnthread *xnthread_current(void)
  * @brief Retrieve the current Cobalt core TCB.
diff --git a/kernel/cobalt/posix/thread.c b/kernel/cobalt/posix/thread.c
index 3ab20f6..7c78405 100644
--- a/kernel/cobalt/posix/thread.c
+++ b/kernel/cobalt/posix/thread.c
@@ -345,10 +345,10 @@ unlock_and_exit:
return 0;
 }
 
-static inline int pthread_create(struct cobalt_thread **thread_p,
-int policy,
-const struct sched_param_ex *param_ex,
-struct task_struct *task)
+static int pthread_create(struct cobalt_thread **thread_p,
+ int policy,
+ const struct sched_param_ex *param_ex,
+ struct task_struct *task)
 {
struct xnsched_class *sched_class;
union xnsched_policy_param param;
@@ -416,6 +416,20 @@ static inline int pthread_create(struct cobalt_thread 
**thread_p,
return 0;
 }
 
+static void pthread_discard(struct cobalt_thread *thread)
+{
+   spl_t s;
+
+   xnsynch_destroy(&thread->monitor_synch);
+   xnsynch_destroy(&thread->sigwait);
+
+   xnlock_get_irqsave(&nklock, s);
+   list_del(&thread->link);
+   xnlock_put_irqrestore(&nklock, s);
+   __xnthread_discard(&thread->threadbase);
+   xnfree(thread);
+}
+
 static inline int pthread_setmode_np(int clrmask, int setmask, int *mode_r)
 {
const int valid_flags = XNLOCK|XNWARN|XNTRAPLB;
@@ -566,8 +580,10 @@ int __cobalt_thread_create(unsigned long pth, int policy,
return ret;
 
ret = cobalt_map_user(&thread->threadbase, u_winoff);
-   if (ret)
-   goto fail;
+   if (ret) {
+   pthread_discard(thread);
+   return ret;
+   }
 
if (!thread_hash(&hkey, thread, task_pid_vnr(p))) {
ret = -EAGAIN;
@@ -617,11 +633,13 @@ cobalt_thread_shadow(struct task_struct *p,
trace_cobalt_pthread_create(hkey->u_pth, SCHED_NORMAL, ¶m_ex);
ret = pthread_create(&thread, SCHED_NORMAL, ¶m_ex, p);
if (ret)
-   return ERR_PTR(-ret);
+   return ERR_PTR(ret);
 
ret = cobalt_map_user(&thread->threadbase, u_winoff);
-   if (ret)
-   goto fail;
+   if (ret) {
+   pthread_discard(thread);
+   return ERR_PTR(ret);
+   }
 
if (!thread_hash(hkey, thread, task_pid_vnr(p))) {
ret = -EAGAIN;
diff --git a/kernel/cobalt/thread.c b/kernel/cobalt/thread.c
index f5444d3..e7726dd 100644
--- a/kernel/cobalt/thread.c
+++ b/kernel/cobalt/thread.c
@@ -492,6 +492,25 @@ void __xnthread_cleanup(struct xnthread *curr)
wake_up(&nkjoinq);
 }
 
+/*
+ * Unwinds xnthread_init() ops for an unmapped thread.  Since the
+ * latter must be dormant, it can't be part of any runqueue.
+ */
+void __xnthread_discard(struct xnthread *thread)
+{
+   spl_t s;
+
+   xntimer_destroy(&thread->rtimer);
+   xntimer_destroy(&thread->ptimer);
+
+   xnlock_get_irqsave(&nklock, s);
+   list_del(&thread->glink);
+   nknrthreads--;
+   xnvfile_touch_tag(&nkthreadlist_tag);
+   xnthread_deregister(thread);
+   xnlock_put_irqrestore(&nklock, s);
+}
+
 /**
  * @fn void xnthread_init(struct xnthread *thread,const struct 
xnthread_init_attr *attr,struct xnsched_class *sched_class,const union 
xnsched_policy_param *sched_param)
  * @brief Initialize a new thread.


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