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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Tue Aug  5 21:17:01 2014 +0200

alchemy: do not publish objects to clusters until they are fully built

We must NOT push Alchemy objects to clusters before they have been
fully built, including the registration phase.

Otherwise, a high priority task waiting on the binding service for the
object to appear in a cluster might preempt the creation call
immediately when the latter is updated, then destroy the half-baked
resource being pushed, leading to invalid memory references and all
sorts of unpleasant outcomes.

---

 lib/alchemy/alarm.c  |   16 ++++++++--------
 lib/alchemy/buffer.c |   15 +++++++--------
 lib/alchemy/cond.c   |   20 +++++++++-----------
 lib/alchemy/event.c  |   21 ++++++++++-----------
 lib/alchemy/heap.c   |   14 +++++++-------
 lib/alchemy/mutex.c  |   26 ++++++++++++--------------
 lib/alchemy/queue.c  |   14 +++++++-------
 lib/alchemy/sem.c    |   20 +++++++++-----------
 lib/alchemy/task.c   |   12 ++++++------
 9 files changed, 75 insertions(+), 83 deletions(-)

diff --git a/lib/alchemy/alarm.c b/lib/alchemy/alarm.c
index a443d42..1b16104 100644
--- a/lib/alchemy/alarm.c
+++ b/lib/alchemy/alarm.c
@@ -189,11 +189,15 @@ int rt_alarm_create(RT_ALARM *alarm, const char *name,
        acb->arg = arg;
        acb->expiries = 0;
        memset(&acb->itmspec, 0, sizeof(acb->itmspec));
-       registry_init_file_obstack(&acb->fsobj, &registry_ops);
-
-       alarm->handle = (uintptr_t)acb;
        acb->magic = alarm_magic;
 
+       registry_init_file_obstack(&acb->fsobj, &registry_ops);
+       ret = __bt(registry_add_file(&acb->fsobj, O_RDONLY,
+                                    "/alchemy/alarms/%s", acb->name));
+       if (ret)
+               warning("failed to export alarm %s to registry, %s",
+                       acb->name, symerror(ret));
+
        if (pvcluster_addobj(&alchemy_alarm_table, acb->name, &acb->cobj)) {
                registry_destroy_file(&acb->fsobj);
                timerobj_destroy(&acb->tmobj);
@@ -201,11 +205,7 @@ int rt_alarm_create(RT_ALARM *alarm, const char *name,
                goto fail;
        }
 
-       ret = __bt(registry_add_file(&acb->fsobj, O_RDONLY,
-                                    "/alchemy/alarms/%s", acb->name));
-       if (ret)
-               warning("failed to export alarm %s to registry, %s",
-                       acb->name, symerror(ret));
+       alarm->handle = (uintptr_t)acb;
 
        CANCEL_RESTORE(svc);
 
diff --git a/lib/alchemy/buffer.c b/lib/alchemy/buffer.c
index f70e9f3..ca4817e 100644
--- a/lib/alchemy/buffer.c
+++ b/lib/alchemy/buffer.c
@@ -252,10 +252,15 @@ int rt_buffer_create(RT_BUFFER *bf, const char *name,
        if (ret)
                goto fail_syncinit;
 
-       registry_init_file_obstack(&bcb->fsobj, &registry_ops);
-
        bcb->magic = buffer_magic;
 
+       registry_init_file_obstack(&bcb->fsobj, &registry_ops);
+       ret = __bt(registry_add_file(&bcb->fsobj, O_RDONLY,
+                                    "/alchemy/buffers/%s", bcb->name));
+       if (ret)
+               warning("failed to export buffer %s to registry, %s",
+                       bcb->name, symerror(ret));
+
        if (syncluster_addobj(&alchemy_buffer_table, bcb->name, &bcb->cobj)) {
                ret = -EEXIST;
                goto fail_register;
@@ -263,12 +268,6 @@ int rt_buffer_create(RT_BUFFER *bf, const char *name,
 
        bf->handle = mainheap_ref(bcb, uintptr_t);
 
-       ret = __bt(registry_add_file(&bcb->fsobj, O_RDONLY,
-                                    "/alchemy/buffers/%s", bcb->name));
-       if (ret)
-               warning("failed to export buffer %s to registry, %s",
-                       bcb->name, symerror(ret));
-
        CANCEL_RESTORE(svc);
 
        return 0;
diff --git a/lib/alchemy/cond.c b/lib/alchemy/cond.c
index 79c941d..376189b 100644
--- a/lib/alchemy/cond.c
+++ b/lib/alchemy/cond.c
@@ -131,26 +131,24 @@ int rt_cond_create(RT_COND *cond, const char *name)
        pthread_condattr_setclock(&cattr, CLOCK_COPPERPLATE);
        __RT(pthread_cond_init(&ccb->cond, &cattr));
        pthread_condattr_destroy(&cattr);
+       ccb->magic = cond_magic;
 
        registry_init_file(&ccb->fsobj, &registry_ops, 0);
-
-       ccb->magic = cond_magic;
+       ret = __bt(registry_add_file(&ccb->fsobj, O_RDONLY,
+                                    "/alchemy/condvars/%s", ccb->name));
+       if (ret) {
+               warning("failed to export condvar %s to registry, %s",
+                       ccb->name, symerror(ret));
+               ret = 0;
+       }
 
        if (syncluster_addobj(&alchemy_cond_table, ccb->name, &ccb->cobj)) {
                registry_destroy_file(&ccb->fsobj);
                __RT(pthread_cond_destroy(&ccb->cond));
                xnfree(ccb);
                ret = -EEXIST;
-       } else {
+       } else
                cond->handle = mainheap_ref(ccb, uintptr_t);
-               ret = __bt(registry_add_file(&ccb->fsobj, O_RDONLY,
-                                            "/alchemy/condvars/%s", 
ccb->name));
-               if (ret) {
-                       warning("failed to export condvar %s to registry, %s",
-                               ccb->name, symerror(ret));
-                       ret = 0;
-               }
-       }
 out:
        CANCEL_RESTORE(svc);
 
diff --git a/lib/alchemy/event.c b/lib/alchemy/event.c
index e2b7313..78ddc7a 100644
--- a/lib/alchemy/event.c
+++ b/lib/alchemy/event.c
@@ -197,25 +197,24 @@ int rt_event_create(RT_EVENT *event, const char *name,
                goto out;
        }
 
-       registry_init_file_obstack(&evcb->fsobj, &registry_ops);
-
        evcb->magic = event_magic;
 
+       registry_init_file_obstack(&evcb->fsobj, &registry_ops);
+       ret = __bt(registry_add_file(&evcb->fsobj, O_RDONLY,
+                                    "/alchemy/events/%s", evcb->name));
+       if (ret) {
+               warning("failed to export event %s to registry, %s",
+                       evcb->name, symerror(ret));
+               ret = 0;
+       }
+
        if (syncluster_addobj(&alchemy_event_table, evcb->name, &evcb->cobj)) {
                registry_destroy_file(&evcb->fsobj);
                eventobj_destroy(&evcb->evobj);
                xnfree(evcb);
                ret = -EEXIST;
-       } else {
+       } else
                event->handle = mainheap_ref(evcb, uintptr_t);
-               ret = __bt(registry_add_file(&evcb->fsobj, O_RDONLY,
-                                            "/alchemy/events/%s", evcb->name));
-               if (ret) {
-                       warning("failed to export event %s to registry, %s",
-                               evcb->name, symerror(ret));
-                       ret = 0;
-               }
-       }
 out:
        CANCEL_RESTORE(svc);
 
diff --git a/lib/alchemy/heap.c b/lib/alchemy/heap.c
index a4edf93..38ffc26 100644
--- a/lib/alchemy/heap.c
+++ b/lib/alchemy/heap.c
@@ -255,21 +255,21 @@ int rt_heap_create(RT_HEAP *heap,
        if (ret)
                goto fail_syncinit;
 
-       registry_init_file_obstack(&hcb->fsobj, &registry_ops);
-
        hcb->magic = heap_magic;
 
+       registry_init_file_obstack(&hcb->fsobj, &registry_ops);
+       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));
+
        if (syncluster_addobj(&alchemy_heap_table, hcb->name, &hcb->cobj)) {
                ret = -EEXIST;
                goto fail_register;
        }
 
        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);
 
diff --git a/lib/alchemy/mutex.c b/lib/alchemy/mutex.c
index 466278a..560b3a5 100644
--- a/lib/alchemy/mutex.c
+++ b/lib/alchemy/mutex.c
@@ -121,10 +121,9 @@ int rt_mutex_create(RT_MUTEX *mutex, const char *name)
                goto out;
        }
 
-
        /*
-        * XXX: we can't obtain priority inheritance with syncobj, so
-        * we have to base this code directly over the POSIX layer.
+        * XXX: we can't have priority inheritance with syncobj, so we
+        * have to base this code directly over the POSIX layer.
         */
        generate_name(mcb->name, name, &mutex_namegen);
        mcb->owner = NO_ALCHEMY_TASK;
@@ -138,24 +137,23 @@ int rt_mutex_create(RT_MUTEX *mutex, const char *name)
        __RT(pthread_mutex_init(&mcb->lock, &mattr));
        pthread_mutexattr_destroy(&mattr);
 
-       registry_init_file(&mcb->fsobj, &registry_ops, 0);
-
        mcb->magic = mutex_magic;
 
+       registry_init_file(&mcb->fsobj, &registry_ops, 0);
+       ret = __bt(registry_add_file(&mcb->fsobj, O_RDONLY,
+                                    "/alchemy/mutexes/%s", mcb->name));
+       if (ret) {
+               warning("failed to export mutex %s to registry, %s",
+                       mcb->name, symerror(ret));
+               ret = 0;
+       }
+
        if (syncluster_addobj(&alchemy_mutex_table, mcb->name, &mcb->cobj)) {
                registry_destroy_file(&mcb->fsobj);
                xnfree(mcb);
                ret = -EEXIST;
-       } else {
+       } else
                mutex->handle = mainheap_ref(mcb, uintptr_t);
-               ret = __bt(registry_add_file(&mcb->fsobj, O_RDONLY,
-                                            "/alchemy/mutexes/%s", mcb->name));
-               if (ret) {
-                       warning("failed to export mutex %s to registry, %s",
-                               mcb->name, symerror(ret));
-                       ret = 0;
-               }
-       }
 out:
        CANCEL_RESTORE(svc);
 
diff --git a/lib/alchemy/queue.c b/lib/alchemy/queue.c
index 3d4334c..9f68b05 100644
--- a/lib/alchemy/queue.c
+++ b/lib/alchemy/queue.c
@@ -257,21 +257,21 @@ int rt_queue_create(RT_QUEUE *queue, const char *name,
        if (ret)
                goto fail_syncinit;
 
-       registry_init_file_obstack(&qcb->fsobj, &registry_ops);
-
        qcb->magic = queue_magic;
 
+       registry_init_file_obstack(&qcb->fsobj, &registry_ops);
+       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));
+
        if (syncluster_addobj(&alchemy_queue_table, qcb->name, &qcb->cobj)) {
                ret = -EEXIST;
                goto fail_register;
        }
 
        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);
 
diff --git a/lib/alchemy/sem.c b/lib/alchemy/sem.c
index 320573c..b0ce742 100644
--- a/lib/alchemy/sem.c
+++ b/lib/alchemy/sem.c
@@ -213,26 +213,24 @@ int rt_sem_create(RT_SEM *sem, const char *name,
        }
 
        generate_name(scb->name, name, &sem_namegen);
+       scb->magic = sem_magic;
 
        registry_init_file_obstack(&scb->fsobj, &registry_ops);
-
-       scb->magic = sem_magic;
+       ret = __bt(registry_add_file(&scb->fsobj, O_RDONLY,
+                                    "/alchemy/semaphores/%s", scb->name));
+       if (ret) {
+               warning("failed to export semaphore %s to registry, %s",
+                       scb->name, symerror(ret));
+               ret = 0;
+       }
 
        if (syncluster_addobj(&alchemy_sem_table, scb->name, &scb->cobj)) {
                registry_destroy_file(&scb->fsobj);
                semobj_destroy(&scb->smobj);
                xnfree(scb);
                ret = -EEXIST;
-       } else {
+       } else
                sem->handle = mainheap_ref(scb, uintptr_t);
-               ret = __bt(registry_add_file(&scb->fsobj, O_RDONLY,
-                                            "/alchemy/semaphores/%s", 
scb->name));
-               if (ret) {
-                       warning("failed to export semaphore %s to registry, %s",
-                               scb->name, symerror(ret));
-                       ret = 0;
-               }
-       }
 out:
        CANCEL_RESTORE(svc);
 
diff --git a/lib/alchemy/task.c b/lib/alchemy/task.c
index e8ac1cf..7acdee0 100644
--- a/lib/alchemy/task.c
+++ b/lib/alchemy/task.c
@@ -304,6 +304,11 @@ static int create_tcb(struct alchemy_task **tcbp, RT_TASK 
*task,
        tcb->self.handle = mainheap_ref(tcb, uintptr_t);
 
        registry_init_file_obstack(&tcb->fsobj, &registry_ops);
+       ret = __bt(registry_add_file(&tcb->fsobj, O_RDONLY,
+                                    "/alchemy/tasks/%s", tcb->name));
+       if (ret)
+               warning("failed to export task %s to registry, %s",
+                       tcb->name, symerror(ret));
 
        if (syncluster_addobj(&alchemy_task_table, tcb->name, &tcb->cobj)) {
                ret = -EEXIST;
@@ -313,16 +318,11 @@ static int create_tcb(struct alchemy_task **tcbp, RT_TASK 
*task,
        if (task)
                task->handle = tcb->self.handle;
 
-       ret = __bt(registry_add_file(&tcb->fsobj, O_RDONLY,
-                                    "/alchemy/tasks/%s", tcb->name));
-       if (ret)
-               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);
+       threadobj_uninit(&tcb->thobj);
 fail_threadinit:
        syncobj_uninit(&tcb->sobj_msg);
 fail_syncinit:


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

Reply via email to