Module: xenomai-forge
Branch: next
Commit: edc7d53bffecfb2dc860bf770e88155e90cee506
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=edc7d53bffecfb2dc860bf770e88155e90cee506

Author: Philippe Gerum <r...@xenomai.org>
Date:   Wed May 14 14:42:12 2014 +0200

copperplate: systematically check basic IPC inits

As Cobalt might fail allocating resources for any basic IPC object
(i.e. mutex, sem, condvar, event or monitor), we should check the
return value of each of the related init call.

Very nasty bugs might surface otherwise, haunting the code undetected
until the core falls short of a critical runtime resource (e.g. heap
memory shared between the Cobalt core and userland).

---

 include/boilerplate/compiler.h    |    4 +++
 include/copperplate/registry.h    |    6 ++---
 include/copperplate/syncobj.h     |    5 ++--
 include/copperplate/threadobj.h   |   13 +++++++---
 include/copperplate/traceobj.h    |    4 +--
 lib/alchemy/buffer.c              |    9 ++++---
 lib/alchemy/heap.c                |   51 +++++++++++++++++++++----------------
 lib/alchemy/queue.c               |   49 ++++++++++++++++++++---------------
 lib/alchemy/task.c                |   26 ++++++++++++++-----
 lib/copperplate/clockobj.c        |    5 +++-
 lib/copperplate/cluster.c         |   10 +++-----
 lib/copperplate/eventobj.c        |    8 +++---
 lib/copperplate/heapobj-malloc.c  |    8 +++++-
 lib/copperplate/heapobj-pshared.c |   34 ++++++++++++++++++++-----
 lib/copperplate/init.c            |    7 ++++-
 lib/copperplate/internal.c        |   17 +++++++++----
 lib/copperplate/registry.c        |   17 ++++++++-----
 lib/copperplate/semobj.c          |    9 ++++---
 lib/copperplate/syncobj.c         |   44 ++++++++++++++++++++------------
 lib/copperplate/threadobj.c       |   47 ++++++++++++++++++++++++----------
 lib/copperplate/timerobj.c        |    8 +++---
 lib/copperplate/traceobj.c        |   17 ++++++++++---
 lib/psos/queue.c                  |   31 +++++++++++++++-------
 lib/psos/rn.c                     |   10 +++++++-
 lib/psos/task.c                   |   26 +++++++++++--------
 lib/vxworks/msgQLib.c             |   31 ++++++++++++++--------
 lib/vxworks/semLib.c              |   11 +++++---
 lib/vxworks/taskLib.c             |   30 ++++++++++++----------
 28 files changed, 358 insertions(+), 179 deletions(-)

diff --git a/include/boilerplate/compiler.h b/include/boilerplate/compiler.h
index 85e8846..f73b326 100644
--- a/include/boilerplate/compiler.h
+++ b/include/boilerplate/compiler.h
@@ -35,4 +35,8 @@
 #define __noreturn     __attribute__((__noreturn__))
 #endif
 
+#ifndef __must_check
+#define __must_check   __attribute__((__warn_unused_result__))
+#endif
+
 #endif /* _BOILERPLATE_COMPILER_H */
diff --git a/include/copperplate/registry.h b/include/copperplate/registry.h
index 2de86a6..0cba3d5 100644
--- a/include/copperplate/registry.h
+++ b/include/copperplate/registry.h
@@ -64,9 +64,9 @@ extern "C" {
 
 int registry_add_dir(const char *fmt, ...);
 
-void registry_init_file(struct fsobj *fsobj,
-                       const struct registry_operations *ops,
-                       size_t privsz);
+int registry_init_file(struct fsobj *fsobj,
+                      const struct registry_operations *ops,
+                      size_t privsz);
 
 int registry_add_file(struct fsobj *fsobj,
                      int mode,
diff --git a/include/copperplate/syncobj.h b/include/copperplate/syncobj.h
index 88321ad..d8a6ade 100644
--- a/include/copperplate/syncobj.h
+++ b/include/copperplate/syncobj.h
@@ -130,8 +130,9 @@ int __syncobj_broadcast_drain(struct syncobj *sobj, int 
reason);
 
 int __syncobj_broadcast_grant(struct syncobj *sobj, int reason);
 
-void syncobj_init(struct syncobj *sobj, clockid_t clk_id, int flags,
-                 fnref_type(void (*)(struct syncobj *sobj)) finalizer);
+int __must_check
+syncobj_init(struct syncobj *sobj, clockid_t clk_id, int flags,
+            fnref_type(void (*)(struct syncobj *sobj)) finalizer);
 
 int syncobj_wait_grant(struct syncobj *sobj,
                 const struct timespec *timeout,
diff --git a/include/copperplate/threadobj.h b/include/copperplate/threadobj.h
index fa9b226..5ca753c 100644
--- a/include/copperplate/threadobj.h
+++ b/include/copperplate/threadobj.h
@@ -280,13 +280,18 @@ void *__threadobj_alloc(size_t tcb_struct_size,
                        size_t wait_union_size,
                        int thobj_offset);
 
+static inline void __threadobj_free(void *p)
+{
+       xnfree(p);
+}
+
 static inline void threadobj_free(struct threadobj *thobj)
 {
-       xnfree((unsigned char *)thobj - thobj->core_offset);
+       __threadobj_free((unsigned char *)thobj - thobj->core_offset);
 }
 
-void threadobj_init(struct threadobj *thobj,
-                   struct threadobj_init_data *idata);
+int __must_check threadobj_init(struct threadobj *thobj,
+                               struct threadobj_init_data *idata);
 
 int threadobj_start(struct threadobj *thobj);
 
@@ -359,7 +364,7 @@ static inline int threadobj_local_p(struct threadobj *thobj)
 
 void threadobj_init_key(void);
 
-void threadobj_pkg_init(void);
+int threadobj_pkg_init(void);
 
 #ifdef __cplusplus
 }
diff --git a/include/copperplate/traceobj.h b/include/copperplate/traceobj.h
index 71901b5..613b043 100644
--- a/include/copperplate/traceobj.h
+++ b/include/copperplate/traceobj.h
@@ -47,8 +47,8 @@ do {                                                          
        \
 extern "C" {
 #endif
 
-void traceobj_init(struct traceobj *trobj,
-                  const char *label, int nr_marks);
+int traceobj_init(struct traceobj *trobj,
+                 const char *label, int nr_marks);
 
 void traceobj_verify(struct traceobj *trobj, int tseq[], int nr_seq);
 
diff --git a/lib/alchemy/buffer.c b/lib/alchemy/buffer.c
index f648114..b025a35 100644
--- a/lib/alchemy/buffer.c
+++ b/lib/alchemy/buffer.c
@@ -248,10 +248,12 @@ int rt_buffer_create(RT_BUFFER *bf, const char *name,
        if (mode & B_PRIO)
                sobj_flags = SYNCOBJ_PRIO;
 
-       registry_init_file_obstack(&bcb->fsobj, &registry_ops);
+       ret = syncobj_init(&bcb->sobj, CLOCK_COPPERPLATE, sobj_flags,
+                          fnref_put(libalchemy, buffer_finalize));
+       if (ret)
+               goto fail_syncinit;
 
-       syncobj_init(&bcb->sobj, CLOCK_COPPERPLATE, sobj_flags,
-                    fnref_put(libalchemy, buffer_finalize));
+       registry_init_file_obstack(&bcb->fsobj, &registry_ops);
 
        bcb->magic = buffer_magic;
 
@@ -275,6 +277,7 @@ int rt_buffer_create(RT_BUFFER *bf, const char *name,
 fail_register:
        registry_destroy_file(&bcb->fsobj);
        syncobj_uninit(&bcb->sobj);
+fail_syncinit:
        xnfree(bcb->buf);
 fail_bufalloc:
        xnfree(bcb);
diff --git a/lib/alchemy/heap.c b/lib/alchemy/heap.c
index 734c809..a828bd5 100644
--- a/lib/alchemy/heap.c
+++ b/lib/alchemy/heap.c
@@ -233,16 +233,14 @@ int rt_heap_create(RT_HEAP *heap,
        ret = -ENOMEM;
        hcb = xnmalloc(sizeof(*hcb));
        if (hcb == NULL)
-               goto out;
+               goto fail_cballoc;
 
        /*
         * The memory pool has to be part of the main heap for proper
         * sharing between processes.
         */
-       if (heapobj_init(&hcb->hobj, NULL, heapsz)) {
-               xnfree(hcb);
-               goto out;
-       }
+       if (heapobj_init(&hcb->hobj, NULL, heapsz))
+               goto fail_bufalloc;
 
        generate_name(hcb->name, name, &heap_namegen);
        hcb->mode = mode;
@@ -252,30 +250,39 @@ int rt_heap_create(RT_HEAP *heap,
        if (mode & H_PRIO)
                sobj_flags = SYNCOBJ_PRIO;
 
-       registry_init_file_obstack(&hcb->fsobj, &registry_ops);
+       ret = syncobj_init(&hcb->sobj, CLOCK_COPPERPLATE, sobj_flags,
+                          fnref_put(libalchemy, heap_finalize));
+       if (ret)
+               goto fail_syncinit;
 
-       syncobj_init(&hcb->sobj, CLOCK_COPPERPLATE, sobj_flags,
-                    fnref_put(libalchemy, heap_finalize));
+       registry_init_file_obstack(&hcb->fsobj, &registry_ops);
 
        hcb->magic = heap_magic;
 
        if (syncluster_addobj(&alchemy_heap_table, hcb->name, &hcb->cobj)) {
-               registry_destroy_file(&hcb->fsobj);
-               syncobj_uninit(&hcb->sobj);
-               heapobj_destroy(&hcb->hobj);
-               xnfree(hcb);
                ret = -EEXIST;
-       } else {
-               heap->handle = mainheap_ref(hcb, uintptr_t);
-               ret = __bt(registry_add_file(&hcb->fsobj, O_RDONLY,
-                                            "/alchemy/heaps/%s", hcb->name));
-               if (ret) {
-                       warning("failed to export heap %s to registry, %s",
-                               hcb->name, symerror(ret));
-                       ret = 0;
-               }
+               goto fail_register;
        }
-out:
+
+       heap->handle = mainheap_ref(hcb, uintptr_t);
+       ret = __bt(registry_add_file(&hcb->fsobj, O_RDONLY,
+                                    "/alchemy/heaps/%s", hcb->name));
+       if (ret)
+               warning("failed to export heap %s to registry, %s",
+                       hcb->name, symerror(ret));
+
+       CANCEL_RESTORE(svc);
+
+       return 0;
+
+fail_register:
+       registry_destroy_file(&hcb->fsobj);
+       syncobj_uninit(&hcb->sobj);
+fail_syncinit:
+       heapobj_destroy(&hcb->hobj);
+fail_bufalloc:
+       xnfree(hcb);
+fail_cballoc:
        CANCEL_RESTORE(svc);
 
        return ret;
diff --git a/lib/alchemy/queue.c b/lib/alchemy/queue.c
index 4432c40..8510aef 100644
--- a/lib/alchemy/queue.c
+++ b/lib/alchemy/queue.c
@@ -219,7 +219,7 @@ int rt_queue_create(RT_QUEUE *queue, const char *name,
        ret = -ENOMEM;
        qcb = xnmalloc(sizeof(*qcb));
        if (qcb == NULL)
-               goto out;
+               goto fail_cballoc;
 
        generate_name(qcb->name, name, &queue_namegen);
        /*
@@ -238,10 +238,8 @@ int rt_queue_create(RT_QUEUE *queue, const char *name,
                                         (poolsize / qlimit) *
                                         sizeof(struct alchemy_queue_msg),
                                         qlimit);
-       if (ret) {
-               xnfree(qcb);
-               goto out;
-       }
+       if (ret)
+               goto fail_bufalloc;
 
        qcb->mode = mode;
        qcb->limit = qlimit;
@@ -251,30 +249,39 @@ int rt_queue_create(RT_QUEUE *queue, const char *name,
        if (mode & Q_PRIO)
                sobj_flags = SYNCOBJ_PRIO;
 
-       syncobj_init(&qcb->sobj, CLOCK_COPPERPLATE, sobj_flags,
-                    fnref_put(libalchemy, queue_finalize));
+       ret = syncobj_init(&qcb->sobj, CLOCK_COPPERPLATE, sobj_flags,
+                          fnref_put(libalchemy, queue_finalize));
+       if (ret)
+               goto fail_syncinit;
 
        registry_init_file_obstack(&qcb->fsobj, &registry_ops);
 
        qcb->magic = queue_magic;
 
        if (syncluster_addobj(&alchemy_queue_table, qcb->name, &qcb->cobj)) {
-               registry_destroy_file(&qcb->fsobj);
-               heapobj_destroy(&qcb->hobj);
-               syncobj_uninit(&qcb->sobj);
-               xnfree(qcb);
                ret = -EEXIST;
-       } else {
-               queue->handle = mainheap_ref(qcb, uintptr_t);
-               ret = __bt(registry_add_file(&qcb->fsobj, O_RDONLY,
-                                            "/alchemy/queues/%s", qcb->name));
-               if (ret) {
-                       warning("failed to export queue %s to registry, %s",
-                               qcb->name, symerror(ret));
-                       ret = 0;
-               }
+               goto fail_register;
        }
-out:
+
+       queue->handle = mainheap_ref(qcb, uintptr_t);
+       ret = __bt(registry_add_file(&qcb->fsobj, O_RDONLY,
+                                    "/alchemy/queues/%s", qcb->name));
+       if (ret)
+               warning("failed to export queue %s to registry, %s",
+                       qcb->name, symerror(ret));
+
+       CANCEL_RESTORE(svc);
+
+       return 0;
+
+fail_register:
+       registry_destroy_file(&qcb->fsobj);
+       syncobj_uninit(&qcb->sobj);
+fail_syncinit:
+       heapobj_destroy(&qcb->hobj);
+fail_bufalloc:
+       xnfree(qcb);
+fail_cballoc:
        CANCEL_RESTORE(svc);
 
        return ret;
diff --git a/lib/alchemy/task.c b/lib/alchemy/task.c
index eaedc18..86ffb68 100644
--- a/lib/alchemy/task.c
+++ b/lib/alchemy/task.c
@@ -256,15 +256,20 @@ static int create_tcb(struct alchemy_task **tcbp, RT_TASK 
*task,
 
        CPU_ZERO(&tcb->affinity);
 
+       ret = syncobj_init(&tcb->sobj_msg, CLOCK_COPPERPLATE,
+                          SYNCOBJ_PRIO, fnref_null);
+       if (ret)
+               goto fail_syncinit;
+
        tcb->suspends = 0;
-       syncobj_init(&tcb->sobj_msg, CLOCK_COPPERPLATE,
-                    SYNCOBJ_PRIO, fnref_null);
        tcb->flowgen = 0;
 
        idata.magic = task_magic;
        idata.finalizer = task_finalizer;
        idata.priority = prio;
-       threadobj_init(&tcb->thobj, &idata);
+       ret = threadobj_init(&tcb->thobj, &idata);
+       if (ret)
+               goto fail_threadinit;
 
        *tcbp = tcb;
 
@@ -280,9 +285,8 @@ static int create_tcb(struct alchemy_task **tcbp, RT_TASK 
*task,
        registry_init_file_obstack(&tcb->fsobj, &registry_ops);
 
        if (syncluster_addobj(&alchemy_task_table, tcb->name, &tcb->cobj)) {
-               registry_destroy_file(&tcb->fsobj);
-               delete_tcb(tcb);
-               return -EEXIST;
+               ret = -EEXIST;
+               goto fail_register;
        }
 
        if (task)
@@ -294,6 +298,16 @@ static int create_tcb(struct alchemy_task **tcbp, RT_TASK 
*task,
                warning("failed to export task %s to registry, %s",
                        tcb->name, symerror(ret));
        return 0;
+
+fail_register:
+       threadobj_uninit(&tcb->thobj);
+       registry_destroy_file(&tcb->fsobj);
+fail_threadinit:
+       syncobj_uninit(&tcb->sobj_msg);
+fail_syncinit:
+       delete_tcb(tcb);
+
+       return ret;
 }
 
 /**
diff --git a/lib/copperplate/clockobj.c b/lib/copperplate/clockobj.c
index 4f5541d..6ef0b97 100644
--- a/lib/copperplate/clockobj.c
+++ b/lib/copperplate/clockobj.c
@@ -401,8 +401,11 @@ int clockobj_init(struct clockobj *clkobj,
        __RT(pthread_mutexattr_settype(&mattr, mutex_type_attribute));
        __RT(pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT));
        __RT(pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_PRIVATE));
-       __RT(pthread_mutex_init(&clkobj->lock, &mattr));
+       ret = __bt(-__RT(pthread_mutex_init(&clkobj->lock, &mattr)));
        __RT(pthread_mutexattr_destroy(&mattr));
+       if (ret)
+               return ret;
+
        __RT(clock_gettime(CLOCK_COPPERPLATE, &now));
        timespec_sub(&clkobj->offset, &clkobj->epoch, &now);
        clkobj->name = name;
diff --git a/lib/copperplate/cluster.c b/lib/copperplate/cluster.c
index 30d50c1..c6bec97 100644
--- a/lib/copperplate/cluster.c
+++ b/lib/copperplate/cluster.c
@@ -219,9 +219,8 @@ int syncluster_init(struct syncluster *sc, const char *name)
        if (sc->sobj == NULL)
                return -ENOMEM;
 
-       syncobj_init(sc->sobj, CLOCK_COPPERPLATE, SYNCOBJ_FIFO, fnref_null);
-
-       return 0;
+       return syncobj_init(sc->sobj, CLOCK_COPPERPLATE,
+                           SYNCOBJ_FIFO, fnref_null);
 }
 
 int syncluster_addobj(struct syncluster *sc, const char *name,
@@ -373,9 +372,8 @@ int pvsyncluster_init(struct pvsyncluster *sc, const char 
*name)
         * Assuming pvcluster_destroy() is a nop, so we don't need to
         * run any finalizer.
         */
-       syncobj_init(&sc->sobj, CLOCK_COPPERPLATE, SYNCOBJ_FIFO, fnref_null);
-
-       return 0;
+       return syncobj_init(&sc->sobj, CLOCK_COPPERPLATE,
+                           SYNCOBJ_FIFO, fnref_null);
 }
 
 void pvsyncluster_destroy(struct pvsyncluster *sc)
diff --git a/lib/copperplate/eventobj.c b/lib/copperplate/eventobj.c
index e0c2e2b..e68ec4a 100644
--- a/lib/copperplate/eventobj.c
+++ b/lib/copperplate/eventobj.c
@@ -154,13 +154,15 @@ fnref_register(libcopperplate, eventobj_finalize);
 int eventobj_init(struct eventobj *evobj, unsigned long value, int flags,
                  fnref_type(void (*)(struct eventobj *evobj)) finalizer)
 {
-       int sobj_flags = 0;
+       int sobj_flags = 0, ret;
 
        if (flags & EVOBJ_PRIO)
                sobj_flags = SYNCOBJ_PRIO;
 
-       syncobj_init(&evobj->core.sobj, CLOCK_COPPERPLATE, sobj_flags,
-                    fnref_put(libcopperplate, eventobj_finalize));
+       ret = syncobj_init(&evobj->core.sobj, CLOCK_COPPERPLATE, sobj_flags,
+                          fnref_put(libcopperplate, eventobj_finalize));
+       if (ret)
+               return __bt(ret);
 
        evobj->core.flags = flags;
        evobj->core.value = value;
diff --git a/lib/copperplate/heapobj-malloc.c b/lib/copperplate/heapobj-malloc.c
index 57dca08..739ac44 100644
--- a/lib/copperplate/heapobj-malloc.c
+++ b/lib/copperplate/heapobj-malloc.c
@@ -43,6 +43,7 @@ int __heapobj_init_private(struct heapobj *hobj, const char 
*name,
 {
        pthread_mutexattr_t mattr;
        struct pool_header *ph;
+       int ret;
 
        /*
         * There is no local pool when working with malloc, we just
@@ -61,8 +62,13 @@ int __heapobj_init_private(struct heapobj *hobj, const char 
*name,
        __RT(pthread_mutexattr_settype(&mattr, mutex_type_attribute));
        __RT(pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT));
        __RT(pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_PRIVATE));
-       __RT(pthread_mutex_init(&ph->lock, &mattr));
+       ret = __bt(-__RT(pthread_mutex_init(&ph->lock, &mattr)));
        __RT(pthread_mutexattr_destroy(&mattr));
+       if (ret) {
+               free(ph);
+               return ret;
+       }
+
        ph->used = 0;
 
        hobj->pool = ph;
diff --git a/lib/copperplate/heapobj-pshared.c 
b/lib/copperplate/heapobj-pshared.c
index 6cde6ad..32d5203 100644
--- a/lib/copperplate/heapobj-pshared.c
+++ b/lib/copperplate/heapobj-pshared.c
@@ -150,11 +150,12 @@ static void init_extent(struct shared_heap *heap, struct 
shared_extent *extent)
        extent->freelist = extent->membase;
 }
 
-static void init_heap(struct shared_heap *heap, const char *name,
-                     void *mem, size_t size)
+static int init_heap(struct shared_heap *heap, const char *name,
+                    void *mem, size_t size)
 {
        struct shared_extent *extent;
        pthread_mutexattr_t mattr;
+       int ret;
 
        strncpy(heap->name, name, sizeof(heap->name) - 1);
        heap->name[sizeof(heap->name) - 1] = '\0';
@@ -178,34 +179,46 @@ static void init_heap(struct shared_heap *heap, const 
char *name,
        __RT(pthread_mutexattr_settype(&mattr, mutex_type_attribute));
        __RT(pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT));
        __RT(pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED));
-       __RT(pthread_mutex_init(&heap->lock, &mattr));
+       ret = __bt(-__RT(pthread_mutex_init(&heap->lock, &mattr)));
        __RT(pthread_mutexattr_destroy(&mattr));
+       if (ret)
+               return ret;
 
        memset(heap->buckets, 0, sizeof(heap->buckets));
        extent = mem;
        init_extent(heap, extent);
        __list_append(heap, &extent->link, &heap->extents);
+
+       return 0;
 }
 
-static void init_main_heap(struct session_heap *m_heap, void *mem, size_t size)
+static int init_main_heap(struct session_heap *m_heap, void *mem, size_t size)
 {
        pthread_mutexattr_t mattr;
+       int ret;
+
+       ret = init_heap(&m_heap->base, "main", mem, size);
+       if (ret)
+               return __bt(ret);
 
-       init_heap(&m_heap->base, "main", mem, size);
        m_heap->cpid = copperplate_get_tid();
 
        __RT(pthread_mutexattr_init(&mattr));
        __RT(pthread_mutexattr_settype(&mattr, mutex_type_attribute));
        __RT(pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT));
        __RT(pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED));
-       __RT(pthread_mutex_init(&m_heap->sysgroup.lock, &mattr));
+       ret = __bt(-__RT(pthread_mutex_init(&m_heap->sysgroup.lock, &mattr)));
        __RT(pthread_mutexattr_destroy(&mattr));
+       if (ret)
+               return ret;
 
        __hash_init(m_heap, &m_heap->catalog, hash_compare_strings);
        m_heap->sysgroup.thread_count = 0;
        __list_init(m_heap, &m_heap->sysgroup.thread_list);
        m_heap->sysgroup.heap_count = 0;
        __list_init(m_heap, &m_heap->sysgroup.heap_list);
+
+       return 0;
 }
 
 static caddr_t get_free_range(struct shared_heap *heap, size_t bsize, int 
log2size)
@@ -645,7 +658,12 @@ static int create_main_heap(void)
 
        m_heap->maplen = len;
        hobj->pool = &m_heap->base; /* Must be set prior to calling 
init_main_heap() */
-       init_main_heap(m_heap, (caddr_t)m_heap + sizeof(*m_heap), size);
+       ret = init_main_heap(m_heap, (caddr_t)m_heap + sizeof(*m_heap), size);
+       if (ret) {
+               errno = -ret;
+               goto unmap_fail;
+       }
+
        /* We need these globals set up before updating a sysgroup. */
        __main_heap = m_heap;
        __main_sysgroup = &m_heap->sysgroup;
@@ -657,6 +675,8 @@ done:
        __main_catalog = &m_heap->catalog;
 
        return 0;
+unmap_fail:
+       munmap(m_heap, len);
 unlink_fail:
        ret = __bt(-errno);
        shm_unlink(hobj->fsname);
diff --git a/lib/copperplate/init.c b/lib/copperplate/init.c
index 0603a51..362e9c5 100644
--- a/lib/copperplate/init.c
+++ b/lib/copperplate/init.c
@@ -571,7 +571,12 @@ void copperplate_init(int *argcp, char *const **argvp)
                        goto fail;
        }
 
-       threadobj_pkg_init();
+       ret = threadobj_pkg_init();
+       if (ret) {
+               warning("failed to initialize multi-threading package");
+               goto fail;
+       }
+
        ret = timerobj_pkg_init();
        if (ret) {
                warning("failed to initialize timer support");
diff --git a/lib/copperplate/internal.c b/lib/copperplate/internal.c
index 3a12c72..89957a8 100644
--- a/lib/copperplate/internal.c
+++ b/lib/copperplate/internal.c
@@ -156,7 +156,7 @@ static int thread_spawn_prologue(struct 
corethread_attributes *cta)
 
        ret = __RT(sem_init(&cta->__reserved.warm, 0, 0));
        if (ret)
-               return __bt(ret);
+               return __bt(-errno);
 
        cta->__reserved.status = -ENOSYS;
 
@@ -192,14 +192,16 @@ static void *thread_trampoline(void *arg)
        _cta = *cta;
        ret = cta->prologue(cta->arg);
        cta->__reserved.status = ret;
+       if (ret)
+               goto fail;
 
+       ret = __bt(-__RT(sem_init(&released, 0, 0)));
        if (ret) {
-               backtrace_check();
-               __RT(sem_post(&cta->__reserved.warm));
-               return (void *)(long)ret;
+               ret = -errno;
+               cta->__reserved.status = ret;
+               goto fail;
        }
 
-       __RT(sem_init(&released, 0, 0));
        cta->__reserved.released = &released;
        /*
         * CAUTION: over Cobalt, we have to switch back to primary
@@ -215,6 +217,11 @@ static void *thread_trampoline(void *arg)
                warning("cannot renice core thread, %s", symerror(ret));
 
        return _cta.run(_cta.arg);
+fail:
+       backtrace_check();
+       __RT(sem_post(&cta->__reserved.warm));
+
+       return (void *)(long)ret;
 }
 
 static int thread_spawn_epilogue(struct corethread_attributes *cta)
diff --git a/lib/copperplate/registry.c b/lib/copperplate/registry.c
index f6bb148..4e91b8d 100644
--- a/lib/copperplate/registry.c
+++ b/lib/copperplate/registry.c
@@ -150,14 +150,15 @@ done:
        return __bt(ret);
 }
 
-void registry_init_file(struct fsobj *fsobj, 
-                       const struct registry_operations *ops,
-                       size_t privsz)
+int registry_init_file(struct fsobj *fsobj, 
+                      const struct registry_operations *ops,
+                      size_t privsz)
 {
        pthread_mutexattr_t mattr;
+       int ret;
 
        if (__node_info.no_registry)
-               return;
+               return 0;
 
        fsobj->path = NULL;
        fsobj->ops = ops;
@@ -168,8 +169,10 @@ void registry_init_file(struct fsobj *fsobj,
        __RT(pthread_mutexattr_settype(&mattr, mutex_type_attribute));
        __RT(pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT));
        __RT(pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_PRIVATE));
-       __RT(pthread_mutex_init(&fsobj->lock, &mattr));
+       ret = __bt(-__RT(pthread_mutex_init(&fsobj->lock, &mattr)));
        __RT(pthread_mutexattr_destroy(&mattr));
+
+       return ret;
 }
 
 int registry_add_file(struct fsobj *fsobj, int mode, const char *fmt, ...)
@@ -713,8 +716,10 @@ int __registry_pkg_init(const char *arg0, char *mountpt)
        __RT(pthread_mutexattr_settype(&mattr, mutex_type_attribute));
        __RT(pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT));
        __RT(pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_PRIVATE));
-       __RT(pthread_mutex_init(&p->lock, &mattr));
+       ret = __bt(-__RT(pthread_mutex_init(&p->lock, &mattr)));
        __RT(pthread_mutexattr_destroy(&mattr));
+       if (ret)
+               return ret;
 
        pvhash_init(&p->files, pvhash_compare_strings);
        pvhash_init(&p->dirs, pvhash_compare_strings);
diff --git a/lib/copperplate/semobj.c b/lib/copperplate/semobj.c
index 97338e2..cec9ff7 100644
--- a/lib/copperplate/semobj.c
+++ b/lib/copperplate/semobj.c
@@ -181,7 +181,7 @@ fnref_register(libcopperplate, semobj_finalize);
 int semobj_init(struct semobj *smobj, int flags, int value,
                fnref_type(void (*)(struct semobj *smobj)) finalizer)
 {
-       int sobj_flags = 0;
+       int sobj_flags = 0, ret;
 
        if (flags & SEMOBJ_PRIO)
                sobj_flags = SYNCOBJ_PRIO;
@@ -190,8 +190,11 @@ int semobj_init(struct semobj *smobj, int flags, int value,
         * We need a trampoline for finalizing a semobj, to escalate
         * from a basic syncobj we receive to the semobj container.
         */
-       syncobj_init(&smobj->core.sobj, CLOCK_COPPERPLATE, sobj_flags,
-                    fnref_put(libcopperplate, semobj_finalize));
+       ret = syncobj_init(&smobj->core.sobj, CLOCK_COPPERPLATE, sobj_flags,
+                          fnref_put(libcopperplate, semobj_finalize));
+       if (ret)
+               return __bt(ret);
+
        smobj->core.flags = flags;
        smobj->core.value = value;
        smobj->finalizer = finalizer;
diff --git a/lib/copperplate/syncobj.c b/lib/copperplate/syncobj.c
index 5aee1a2..56c0025 100644
--- a/lib/copperplate/syncobj.c
+++ b/lib/copperplate/syncobj.c
@@ -106,13 +106,12 @@ void monitor_drain_all(struct syncobj *sobj)
        cobalt_monitor_drain_all(&sobj->core.monitor);
 }
 
-static inline void syncobj_init_corespec(struct syncobj *sobj,
-                                        clockid_t clk_id)
+static inline int syncobj_init_corespec(struct syncobj *sobj,
+                                       clockid_t clk_id)
 {
-       int flags = monitor_scope_attribute, ret;
-       ret = cobalt_monitor_init(&sobj->core.monitor, clk_id, flags);
-       assert(ret == 0);
-       (void)ret;
+       int flags = monitor_scope_attribute;
+
+       return __bt(cobalt_monitor_init(&sobj->core.monitor, clk_id, flags));
 }
 
 static inline void syncobj_cleanup_corespec(struct syncobj *sobj)
@@ -181,26 +180,38 @@ void monitor_drain_all(struct syncobj *sobj)
  * couple of condvars, one in the syncobj and the other owned by the
  * thread object.
  */
-static inline void syncobj_init_corespec(struct syncobj *sobj,
-                                        clockid_t clk_id)
+static inline int syncobj_init_corespec(struct syncobj *sobj,
+                                       clockid_t clk_id)
 {
        pthread_mutexattr_t mattr;
        pthread_condattr_t cattr;
        int ret;
 
        pthread_mutexattr_init(&mattr);
-       __RT(pthread_mutexattr_settype(&mattr, mutex_type_attribute));
+       pthread_mutexattr_settype(&mattr, mutex_type_attribute);
        pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT);
-       ret = pthread_mutexattr_setpshared(&mattr, mutex_scope_attribute);
-       assert(ret == 0); (void)ret;
-       pthread_mutex_init(&sobj->core.lock, &mattr);
+       ret = __bt(-pthread_mutexattr_setpshared(&mattr, 
mutex_scope_attribute));
+       if (ret) {
+               pthread_mutexattr_destroy(&mattr);
+               return ret;
+       }
+
+       ret = __bt(-pthread_mutex_init(&sobj->core.lock, &mattr));
        pthread_mutexattr_destroy(&mattr);
+       if (ret)
+               return ret;
 
        pthread_condattr_init(&cattr);
        pthread_condattr_setpshared(&cattr, mutex_scope_attribute);
        pthread_condattr_setclock(&cattr, clk_id);
-       pthread_cond_init(&sobj->core.drain_sync, &cattr);
+       ret = __bt(-pthread_cond_init(&sobj->core.drain_sync, &cattr));
        pthread_condattr_destroy(&cattr);
+       if (ret) {
+               pthread_mutex_destroy(&sobj->core.lock);
+               return ret;
+       }
+
+       return 0;
 }
 
 static inline void syncobj_cleanup_corespec(struct syncobj *sobj)
@@ -212,8 +223,8 @@ static inline void syncobj_cleanup_corespec(struct syncobj 
*sobj)
 
 #endif /* CONFIG_XENO_MERCURY */
 
-void syncobj_init(struct syncobj *sobj, clockid_t clk_id, int flags,
-                 fnref_type(void (*)(struct syncobj *sobj)) finalizer)
+int syncobj_init(struct syncobj *sobj, clockid_t clk_id, int flags,
+                fnref_type(void (*)(struct syncobj *sobj)) finalizer)
 {
        sobj->flags = flags;
        list_init(&sobj->grant_list);
@@ -223,7 +234,8 @@ void syncobj_init(struct syncobj *sobj, clockid_t clk_id, 
int flags,
        sobj->wait_count = 0;
        sobj->finalizer = finalizer;
        sobj->magic = SYNCOBJ_MAGIC;
-       syncobj_init_corespec(sobj, clk_id);
+
+       return __bt(syncobj_init_corespec(sobj, clk_id));
 }
 
 int syncobj_lock(struct syncobj *sobj, struct syncstate *syns)
diff --git a/lib/copperplate/threadobj.c b/lib/copperplate/threadobj.c
index bdffdc9..b58bcdb 100644
--- a/lib/copperplate/threadobj.c
+++ b/lib/copperplate/threadobj.c
@@ -237,8 +237,9 @@ static inline void pkg_init_corespec(void)
 {
 }
 
-static inline void threadobj_init_corespec(struct threadobj *thobj)
+static inline int threadobj_init_corespec(struct threadobj *thobj)
 {
+       return 0;
 }
 
 static inline void threadobj_uninit_corespec(struct threadobj *thobj)
@@ -613,9 +614,12 @@ static inline void pkg_init_corespec(void)
        sigaction(SIGRESM, &sa, NULL);
 }
 
-static inline void threadobj_init_corespec(struct threadobj *thobj)
+static inline int threadobj_init_corespec(struct threadobj *thobj)
 {
        pthread_condattr_t cattr;
+       int ret;
+
+       thobj->core.rr_timer = NULL;
        /*
         * Over Mercury, we need an additional per-thread condvar to
         * implement the complex monitor for the syncobj abstraction.
@@ -623,9 +627,10 @@ static inline void threadobj_init_corespec(struct 
threadobj *thobj)
        pthread_condattr_init(&cattr);
        pthread_condattr_setpshared(&cattr, mutex_scope_attribute);
        pthread_condattr_setclock(&cattr, CLOCK_COPPERPLATE);
-       pthread_cond_init(&thobj->core.grant_sync, &cattr);
+       ret = __bt(-pthread_cond_init(&thobj->core.grant_sync, &cattr));
        pthread_condattr_destroy(&cattr);
-       thobj->core.rr_timer = NULL;
+
+       return ret;
 }
 
 static inline void threadobj_uninit_corespec(struct threadobj *thobj)
@@ -1125,11 +1130,12 @@ void *__threadobj_alloc(size_t tcb_struct_size,
        return p;
 }
 
-void threadobj_init(struct threadobj *thobj,
-                   struct threadobj_init_data *idata)
+int threadobj_init(struct threadobj *thobj,
+                  struct threadobj_init_data *idata)
 {
        pthread_mutexattr_t mattr;
        pthread_condattr_t cattr;
+       int ret;
 
        thobj->magic = idata->magic;
        thobj->tid = 0;
@@ -1155,16 +1161,22 @@ void threadobj_init(struct threadobj *thobj,
        __RT(pthread_mutexattr_settype(&mattr, mutex_type_attribute));
        __RT(pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT));
        __RT(pthread_mutexattr_setpshared(&mattr, mutex_scope_attribute));
-       __RT(pthread_mutex_init(&thobj->lock, &mattr));
+       ret = __bt(-__RT(pthread_mutex_init(&thobj->lock, &mattr)));
        __RT(pthread_mutexattr_destroy(&mattr));
+       if (ret)
+               return ret;
 
        __RT(pthread_condattr_init(&cattr));
        __RT(pthread_condattr_setpshared(&cattr, mutex_scope_attribute));
        __RT(pthread_condattr_setclock(&cattr, CLOCK_COPPERPLATE));
-       __RT(pthread_cond_init(&thobj->barrier, &cattr));
+       ret = __bt(-__RT(pthread_cond_init(&thobj->barrier, &cattr)));
        __RT(pthread_condattr_destroy(&cattr));
+       if (ret) {
+               __RT(pthread_mutex_destroy(&thobj->lock));
+               return ret;
+       }
 
-       threadobj_init_corespec(thobj);
+       return threadobj_init_corespec(thobj);
 }
 
 static void uninit_thread(struct threadobj *thobj)
@@ -1620,10 +1632,11 @@ int threadobj_set_rr(struct threadobj *thobj, const 
struct timespec *quantum)
        return __bt(set_rr(thobj, quantum));
 }
 
-static inline void main_overlay(void)
+static inline int main_overlay(void)
 {
        struct threadobj_init_data idata;
        struct threadobj *tcb;
+       int ret;
 
        /*
         * Make the main() context a basic yet complete thread object,
@@ -1639,13 +1652,20 @@ static inline void main_overlay(void)
        idata.magic = 0x0;
        idata.finalizer = NULL;
        idata.priority = 0;
-       threadobj_init(tcb, &idata);
+       ret = threadobj_init(tcb, &idata);
+       if (ret) {
+               __threadobj_free(tcb);
+               return __bt(ret);
+       }
+
        tcb->status = __THREAD_S_STARTED|__THREAD_S_ACTIVE;
        threadobj_prologue(tcb, "main");
        pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
+
+       return 0;
 }
 
-void threadobj_pkg_init(void)
+int threadobj_pkg_init(void)
 {
        threadobj_irq_prio = __RT(sched_get_priority_max(SCHED_RT));
        threadobj_high_prio = threadobj_irq_prio - 1;
@@ -1653,5 +1673,6 @@ void threadobj_pkg_init(void)
 
        pkg_init_corespec();
        start_agent();
-       main_overlay();
+
+       return main_overlay();
 }
diff --git a/lib/copperplate/timerobj.c b/lib/copperplate/timerobj.c
index 51f6b41..d69e346 100644
--- a/lib/copperplate/timerobj.c
+++ b/lib/copperplate/timerobj.c
@@ -210,10 +210,10 @@ int timerobj_init(struct timerobj *tmobj)
        __RT(pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT));
        ret = __RT(pthread_mutexattr_setpshared(&mattr, mutex_scope_attribute));
        assert(ret == 0);
-       __RT(pthread_mutex_init(&tmobj->lock, &mattr));
+       ret = __bt(-__RT(pthread_mutex_init(&tmobj->lock, &mattr)));
        __RT(pthread_mutexattr_destroy(&mattr));
 
-       return 0;
+       return ret;
 }
 
 void timerobj_destroy(struct timerobj *tmobj) /* lock held, dropped */
@@ -285,8 +285,8 @@ int timerobj_pkg_init(void)
        __RT(pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE));
        __RT(pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT));
        __RT(pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_PRIVATE));
-       ret = __RT(pthread_mutex_init(&svlock, &mattr));
+       ret = __bt(-__RT(pthread_mutex_init(&svlock, &mattr)));
        __RT(pthread_mutexattr_destroy(&mattr));
 
-       return __bt(-ret);
+       return ret;
 }
diff --git a/lib/copperplate/traceobj.c b/lib/copperplate/traceobj.c
index 1a01cd0..24c3997 100644
--- a/lib/copperplate/traceobj.c
+++ b/lib/copperplate/traceobj.c
@@ -42,22 +42,31 @@ struct tracemark {
        int mark;
 };
 
-void traceobj_init(struct traceobj *trobj, const char *label, int nr_marks)
+int traceobj_init(struct traceobj *trobj, const char *label, int nr_marks)
 {
        pthread_mutexattr_t mattr;
        pthread_condattr_t cattr;
+       int ret;
 
        __RT(pthread_mutexattr_init(&mattr));
        __RT(pthread_mutexattr_settype(&mattr, mutex_type_attribute));
        __RT(pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT));
        __RT(pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_PRIVATE));
-       __RT(pthread_mutex_init(&trobj->lock, &mattr));
+       ret = __bt(-__RT(pthread_mutex_init(&trobj->lock, &mattr)));
        __RT(pthread_mutexattr_destroy(&mattr));
+       if (ret)
+               return ret;
+
        __RT(pthread_condattr_init(&cattr));
        __RT(pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_PRIVATE));
        __RT(pthread_condattr_setclock(&cattr, CLOCK_COPPERPLATE));
-       __RT(pthread_cond_init(&trobj->join, &cattr));
+       ret = __bt(-__RT(pthread_cond_init(&trobj->join, &cattr)));
        __RT(pthread_condattr_destroy(&cattr));
+       if (ret) {
+               __RT(pthread_mutex_destroy(&trobj->lock));
+               return ret;
+       }
+
        /*
         * We make sure not to unblock from threadobj_join() until at
         * least one thread has called trace_enter() for this trace
@@ -74,6 +83,8 @@ void traceobj_init(struct traceobj *trobj, const char *label, 
int nr_marks)
                if (trobj->marks == NULL)
                        panic("cannot allocate mark table for tracing");
        }
+
+       return 0;
 }
 
 static void compare_marks(struct traceobj *trobj, int tseq[], int nr_seq) /* 
lock held */
diff --git a/lib/psos/queue.c b/lib/psos/queue.c
index e61d34e..2b74191 100644
--- a/lib/psos/queue.c
+++ b/lib/psos/queue.c
@@ -103,25 +103,38 @@ static u_long __q_create(const char *name, u_long count,
                q->name[sizeof(q->name) - 1] = '\0';
        }
 
-       if (cluster_addobj_dup(&psos_queue_table, q->name, &q->cobj)) {
-               warning("cannot register queue: %s", q->name);
-               xnfree(q);
-               ret = ERR_OBJID;
-               goto out;
-       }
-
        if (flags & Q_PRIOR)
                sobj_flags = SYNCOBJ_PRIO;
 
        q->flags = flags;
        q->maxmsg = (flags & Q_LIMIT) ? count : 0;
        q->maxlen = maxlen;
-       syncobj_init(&q->sobj, CLOCK_COPPERPLATE, sobj_flags,
-                    fnref_put(libpsos, queue_finalize));
+       ret = syncobj_init(&q->sobj, CLOCK_COPPERPLATE, sobj_flags,
+                          fnref_put(libpsos, queue_finalize));
+       if (ret) {
+               ret = ERR_NOQCB;
+               goto fail_syncinit;
+       }
+
        list_init(&q->msg_list);
        q->msgcount = 0;
        q->magic = queue_magic;
        *qid_r = mainheap_ref(q, u_long);
+
+       if (cluster_addobj_dup(&psos_queue_table, q->name, &q->cobj)) {
+               warning("cannot register queue: %s", q->name);
+               ret = ERR_OBJID;
+               goto fail_register;
+       }
+
+       CANCEL_RESTORE(svc);
+
+       return 0;
+
+fail_register:
+       syncobj_uninit(&q->sobj);
+fail_syncinit:
+       xnfree(q);
 out:
        CANCEL_RESTORE(svc);
 
diff --git a/lib/psos/rn.c b/lib/psos/rn.c
index ca404ee..952ddfd 100644
--- a/lib/psos/rn.c
+++ b/lib/psos/rn.c
@@ -128,6 +128,7 @@ u_long rn_create(const char *name, void *saddr, u_long 
length,
 
        ret = __heapobj_init(&rn->hobj, name, length, saddr);
        if (ret) {
+               pvcluster_delobj(&psos_rn_table, &rn->cobj);
                ret = ERR_TINYRN;
                xnfree(rn);
                goto out;
@@ -141,7 +142,14 @@ u_long rn_create(const char *name, void *saddr, u_long 
length,
        rn->flags = flags;
        rn->busynr = 0;
        rn->usedmem = 0;
-       syncobj_init(&rn->sobj, CLOCK_COPPERPLATE, sobj_flags, fnref_null);
+       ret = syncobj_init(&rn->sobj, CLOCK_COPPERPLATE, sobj_flags, 
fnref_null);
+       if (ret) {
+               heapobj_destroy(&rn->hobj);
+               pvcluster_delobj(&psos_rn_table, &rn->cobj);
+               xnfree(rn);
+               goto out;
+       }
+
        rn->magic = rn_magic;
        *asize_r = rn->hobj.size;
        *rnid_r = mainheap_ref(rn, u_long);
diff --git a/lib/psos/task.c b/lib/psos/task.c
index 13d78a8..de7c295 100644
--- a/lib/psos/task.c
+++ b/lib/psos/task.c
@@ -311,23 +311,27 @@ u_long t_create(const char *name, u_long prio,
        task->flags = flags;    /* We don't do much with those. */
        task->mode = 0; /* Not yet known. */
        task->events = 0;
-       syncobj_init(&task->sobj, CLOCK_COPPERPLATE, 0, fnref_null);
+       ret = syncobj_init(&task->sobj, CLOCK_COPPERPLATE, 0, fnref_null);
+       if (ret)
+               goto fail_syncinit;
+
        memset(task->notepad, 0, sizeof(task->notepad));
        pvlist_init(&task->timer_list);
        *tid_r = mainheap_ref(task, u_long);
 
+       idata.magic = task_magic;
+       idata.finalizer = task_finalizer;
+       idata.priority = cprio;
+       ret = threadobj_init(&task->thobj, &idata);
+       if (ret)
+               goto fail_threadinit;
+
        ret = __bt(cluster_addobj_dup(&psos_task_table, task->name, 
&task->cobj));
        if (ret) {
                warning("cannot register task: %s", task->name);
-               ret = ERR_OBJID;
-               goto fail;
+               goto fail_register;
        }
 
-       idata.magic = task_magic;
-       idata.finalizer = task_finalizer;
-       idata.priority = cprio;
-       threadobj_init(&task->thobj, &idata);
-
        cta.sched.policy = SCHED_RT;
        cta.sched.param.sched_priority = cprio;
        cta.prologue = task_prologue;
@@ -339,10 +343,12 @@ u_long t_create(const char *name, u_long prio,
        ret = __bt(copperplate_create_thread(&cta, &task->thobj.tid));
        if (ret) {
                cluster_delobj(&psos_task_table, &task->cobj);
+       fail_register:
                threadobj_uninit(&task->thobj);
-               ret = ERR_NOTCB;
-       fail:
+       fail_threadinit:
                syncobj_uninit(&task->sobj);
+       fail_syncinit:
+               ret = ERR_NOTCB;
                threadobj_free(&task->thobj);
        }
 out:
diff --git a/lib/vxworks/msgQLib.c b/lib/vxworks/msgQLib.c
index 78a7317..087dbf6 100644
--- a/lib/vxworks/msgQLib.c
+++ b/lib/vxworks/msgQLib.c
@@ -65,8 +65,8 @@ fnref_register(libvxworks, mq_finalize);
 
 MSG_Q_ID msgQCreate(int maxMsgs, int maxMsgLength, int options)
 {
+       int sobj_flags = 0, ret;
        struct wind_mq *mq;
-       int sobj_flags = 0;
        struct service svc;
 
        if (threadobj_irq_p()) {
@@ -88,7 +88,7 @@ MSG_Q_ID msgQCreate(int maxMsgs, int maxMsgLength, int 
options)
 
        mq = xnmalloc(sizeof(*mq));
        if (mq == NULL)
-               goto no_mem;
+               goto fail_cballoc;
 
        /*
         * The message pool must come from the main heap because of
@@ -97,19 +97,17 @@ MSG_Q_ID msgQCreate(int maxMsgs, int maxMsgLength, int 
options)
         * object accordingly.
         */
        if (heapobj_init_array(&mq->pool, NULL, maxMsgLength +
-                              sizeof(struct msgholder), maxMsgs)) {
-               xnfree(mq);
-       no_mem:
-               errno = S_memLib_NOT_ENOUGH_MEMORY;
-               CANCEL_RESTORE(svc);
-               return (MSG_Q_ID)0;
-       }
+                              sizeof(struct msgholder), maxMsgs))
+               goto fail_bufalloc;
 
        if (options & MSG_Q_PRIORITY)
                sobj_flags = SYNCOBJ_PRIO;
 
-       syncobj_init(&mq->sobj, CLOCK_COPPERPLATE, sobj_flags,
-                    fnref_put(libvxworks, mq_finalize));
+       ret = syncobj_init(&mq->sobj, CLOCK_COPPERPLATE, sobj_flags,
+                          fnref_put(libvxworks, mq_finalize));
+       if (ret)
+               goto fail_syncinit;
+               
        mq->options = options;
        mq->maxmsg = maxMsgs;
        mq->msgsize = maxMsgLength;
@@ -121,6 +119,17 @@ MSG_Q_ID msgQCreate(int maxMsgs, int maxMsgLength, int 
options)
        CANCEL_RESTORE(svc);
 
        return mainheap_ref(mq, MSG_Q_ID);
+
+fail_syncinit:
+       heapobj_destroy(&mq->pool);
+fail_bufalloc:
+       xnfree(mq);
+fail_cballoc:
+       errno = S_memLib_NOT_ENOUGH_MEMORY;
+
+       CANCEL_RESTORE(svc);
+
+       return (MSG_Q_ID)0;
 }
 
 STATUS msgQDelete(MSG_Q_ID msgQId)
diff --git a/lib/vxworks/semLib.c b/lib/vxworks/semLib.c
index c7e0b26..fcbecc5 100644
--- a/lib/vxworks/semLib.c
+++ b/lib/vxworks/semLib.c
@@ -195,8 +195,8 @@ static const struct wind_sem_ops xsem_ops = {
 
 static SEM_ID alloc_xsem(int options, int initval, int maxval)
 {
+       int sobj_flags = 0, ret;
        struct wind_sem *sem;
-       int sobj_flags = 0;
 
        if (options & ~SEM_Q_PRIORITY) {
                errno = S_semLib_INVALID_OPTION;
@@ -214,8 +214,13 @@ static SEM_ID alloc_xsem(int options, int initval, int 
maxval)
 
        sem->u.xsem.value = initval;
        sem->u.xsem.maxvalue = maxval;
-       syncobj_init(&sem->u.xsem.sobj, CLOCK_COPPERPLATE, sobj_flags,
-                    fnref_put(libvxworks, sem_finalize));
+       ret = syncobj_init(&sem->u.xsem.sobj, CLOCK_COPPERPLATE, sobj_flags,
+                          fnref_put(libvxworks, sem_finalize));
+       if (ret) {
+               xnfree(sem);
+               errno = S_memLib_NOT_ENOUGH_MEMORY;
+               return (SEM_ID)0;
+       }
 
        return mainheap_ref(sem, SEM_ID);
 }
diff --git a/lib/vxworks/taskLib.c b/lib/vxworks/taskLib.c
index b793c54..f574157 100644
--- a/lib/vxworks/taskLib.c
+++ b/lib/vxworks/taskLib.c
@@ -335,6 +335,14 @@ static STATUS __taskInit(struct wind_task *task,
                return ERROR;
        }
 
+       task->tcb = tcb;
+       initpvh(&task->next);
+       tcb->opaque = task;
+       tcb->status = WIND_SUSPEND;
+       tcb->safeCnt = 0;
+       tcb->flags = flags;
+       tcb->entry = entry;
+
        if (name == NULL || *name == '\0')
                sprintf(task->name, "t%lu", ++anon_tids);
        else {
@@ -342,6 +350,15 @@ static STATUS __taskInit(struct wind_task *task,
                task->name[sizeof(task->name) - 1] = '\0';
        }
 
+       idata.magic = task_magic;
+       idata.finalizer = task_finalizer;
+       idata.priority = cprio;
+       ret = threadobj_init(&task->thobj, &idata);
+       if (ret) {
+               errno = S_memLib_NOT_ENOUGH_MEMORY;
+               return ERROR;
+       }
+
        __RT(pthread_mutexattr_init(&mattr));
        __RT(pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE));
        __RT(pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT));
@@ -349,19 +366,6 @@ static STATUS __taskInit(struct wind_task *task,
        __RT(pthread_mutex_init(&task->safelock, &mattr));
        __RT(pthread_mutexattr_destroy(&mattr));
 
-       task->tcb = tcb;
-       tcb->opaque = task;
-       tcb->status = WIND_SUSPEND;
-       tcb->safeCnt = 0;
-       tcb->flags = flags;
-       tcb->entry = entry;
-
-       idata.magic = task_magic;
-       idata.finalizer = task_finalizer;
-       idata.priority = cprio;
-       threadobj_init(&task->thobj, &idata);
-       initpvh(&task->next);
-
        ret = __bt(cluster_addobj(&wind_task_table, task->name, &task->cobj));
        if (ret) {
                warning("duplicate task name: %s", task->name);


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

Reply via email to