contrary to some comments, condvars are automatically
initialised on signal/wait.
Correct the destroy method to not report an
error on such condvars.

Check whether the condition variable has the
static initializer is now more strict.

Signed-off-by: Norbert Lange <norbert.la...@andritz.com>
---
 lib/cobalt/cond.c | 93 ++++++++++++++++++++++++++---------------------
 1 file changed, 51 insertions(+), 42 deletions(-)

diff --git a/lib/cobalt/cond.c b/lib/cobalt/cond.c
index 00a201855..92eb230ff 100644
--- a/lib/cobalt/cond.c
+++ b/lib/cobalt/cond.c
@@ -142,6 +142,42 @@ COBALT_IMPL(int, pthread_cond_init, (pthread_cond_t *cond,
        return 0;
 }
 
+static int __attribute__((cold)) _cobalt_cond_autoinit_type(const 
pthread_cond_t *cond)
+{
+       static const pthread_cond_t cond_initializers[] = {
+               PTHREAD_COND_INITIALIZER
+       };
+       static const int cond_types[] =
+       {
+               0
+       };
+
+       unsigned i = sizeof(cond_types) / sizeof(cond_types[0]);
+       while (i-- > 0)
+       {
+               if (memcmp(cond, &cond_initializers[i], 
sizeof(cond_initializers[0])) == 0)
+                       return cond_types[i];
+       }
+       return -1;
+}
+
+static int __attribute__((cold)) _cobalt_cond_doautoinit(union 
cobalt_cond_union *ucond)
+{
+       int type;
+       type = _cobalt_cond_autoinit_type(&ucond->native_cond);
+       if (type < 0)
+               return EINVAL;
+
+       return __COBALT(pthread_cond_init(&ucond->native_cond, NULL));
+}
+
+static inline int _cobalt_cond_autoinit(union cobalt_cond_union *ucond)
+{
+       if (unlikely(ucond->shadow_cond.magic != COBALT_COND_MAGIC))
+               return _cobalt_cond_doautoinit(ucond);
+       return 0;
+}
+
 /**
  * @fn int pthread_cond_destroy(pthread_cond_t *cond)
  * @brief Destroy a condition variable
@@ -170,6 +206,9 @@ COBALT_IMPL(int, pthread_cond_destroy, (pthread_cond_t 
*cond))
 {
        struct cobalt_cond_shadow *_cond = &((union cobalt_cond_union 
*)cond)->shadow_cond;
 
+       if (unlikely(_cond->magic != COBALT_COND_MAGIC))
+               return (_cobalt_cond_autoinit_type(cond) < 0) ? EINVAL : 0;
+
        return -XENOMAI_SYSCALL1( sc_cobalt_cond_destroy, _cond);
 }
 
@@ -193,12 +232,6 @@ static void __pthread_cond_cleanup(void *data)
        c->mutex->lockcnt = c->count;
 }
 
-static int __attribute__((cold)) cobalt_cond_autoinit(pthread_cond_t *cond)
-{
-       return __COBALT(pthread_cond_init(cond, NULL));
-}
-
-
 /**
  * Wait on a condition variable.
  *
@@ -262,10 +295,10 @@ COBALT_IMPL(int, pthread_cond_wait, (pthread_cond_t 
*cond, pthread_mutex_t *mute
        if (_mx->magic != COBALT_MUTEX_MAGIC)
                return EINVAL;
 
-       if (_cnd->magic != COBALT_COND_MAGIC)
-               goto autoinit;
+       err = _cobalt_cond_autoinit((union cobalt_cond_union *)cond);
+       if (err)
+               return err;
 
-  cont:
        if (_mx->attr.type == PTHREAD_MUTEX_ERRORCHECK) {
                xnhandle_t cur = cobalt_get_current();
 
@@ -297,12 +330,6 @@ COBALT_IMPL(int, pthread_cond_wait, (pthread_cond_t *cond, 
pthread_mutex_t *mute
        pthread_testcancel();
 
        return -err ?: -c.err;
-
-  autoinit:
-       err = cobalt_cond_autoinit(cond);
-       if (err)
-               return err;
-       goto cont;
 }
 
 /**
@@ -357,10 +384,10 @@ COBALT_IMPL(int, pthread_cond_timedwait, (pthread_cond_t 
*cond,
        if (_mx->magic != COBALT_MUTEX_MAGIC)
                return EINVAL;
 
-       if (_cnd->magic != COBALT_COND_MAGIC)
-               goto autoinit;
+       err = _cobalt_cond_autoinit((union cobalt_cond_union *)cond);
+       if (err)
+               return err;
 
-  cont:
        if (_mx->attr.type == PTHREAD_MUTEX_ERRORCHECK) {
                xnhandle_t cur = cobalt_get_current();
 
@@ -391,12 +418,6 @@ COBALT_IMPL(int, pthread_cond_timedwait, (pthread_cond_t 
*cond,
        pthread_testcancel();
 
        return -err ?: -c.err;
-
-  autoinit:
-       err = cobalt_cond_autoinit(cond);
-       if (err)
-               return err;
-       goto cont;
 }
 
 /**
@@ -431,10 +452,10 @@ COBALT_IMPL(int, pthread_cond_signal, (pthread_cond_t 
*cond))
        __u32 flags;
        int err;
 
-       if (_cnd->magic != COBALT_COND_MAGIC)
-               goto autoinit;
+       err = _cobalt_cond_autoinit((union cobalt_cond_union *)cond);
+       if (err)
+               return err;
 
-  cont:
        mutex_state = get_mutex_state(_cnd);
        if (mutex_state == NULL)
                return 0;       /* Fast path, no waiter. */
@@ -455,12 +476,6 @@ COBALT_IMPL(int, pthread_cond_signal, (pthread_cond_t 
*cond))
                cond_state->pending_signals = pending_signals + 1;
 
        return 0;
-
-  autoinit:
-       err = cobalt_cond_autoinit(cond);
-       if (err)
-               return err;
-       goto cont;
 }
 
 /**
@@ -491,10 +506,10 @@ COBALT_IMPL(int, pthread_cond_broadcast, (pthread_cond_t 
*cond))
        __u32 flags;
        int err;
 
-       if (_cnd->magic != COBALT_COND_MAGIC)
-               goto autoinit;
+       err = _cobalt_cond_autoinit((union cobalt_cond_union *)cond);
+       if (err)
+               return err;
 
-  cont:
        mutex_state = get_mutex_state(_cnd);
        if (mutex_state == NULL)
                return 0;
@@ -513,12 +528,6 @@ COBALT_IMPL(int, pthread_cond_broadcast, (pthread_cond_t 
*cond))
        cond_state->pending_signals = ~0U;
 
        return 0;
-
-  autoinit:
-       err = cobalt_cond_autoinit(cond);
-       if (err)
-               return err;
-       goto cont;
 }
 
 /**
-- 
2.20.1


Reply via email to