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, ®istry_ops); - - alarm->handle = (uintptr_t)acb; acb->magic = alarm_magic; + registry_init_file_obstack(&acb->fsobj, ®istry_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, ®istry_ops); - bcb->magic = buffer_magic; + registry_init_file_obstack(&bcb->fsobj, ®istry_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, ®istry_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, ®istry_ops); - evcb->magic = event_magic; + registry_init_file_obstack(&evcb->fsobj, ®istry_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, ®istry_ops); - hcb->magic = heap_magic; + registry_init_file_obstack(&hcb->fsobj, ®istry_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, ®istry_ops, 0); - mcb->magic = mutex_magic; + registry_init_file(&mcb->fsobj, ®istry_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, ®istry_ops); - qcb->magic = queue_magic; + registry_init_file_obstack(&qcb->fsobj, ®istry_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, ®istry_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, ®istry_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