Пример #1
0
static void pse51_shm_put(pse51_shm_t * shm, unsigned dec)
{
	spl_t s;

	xnlock_get_irqsave(&nklock, s);

	while (dec--)
		pse51_node_put(&shm->nodebase);

	if (pse51_node_removed_p(&shm->nodebase)) {
		xnlock_put_irqrestore(&nklock, s);
		pse51_shm_destroy(shm, 0);
		xnfree(shm);
	} else
		xnlock_put_irqrestore(&nklock, s);
}
Пример #2
0
/**
 * Close a named semaphore.
 *
 * This service closes the semaphore @a sm. The semaphore is destroyed only when
 * unlinked with a call to the sem_unlink() service and when each call to
 * sem_open() matches a call to this service.
 *
 * When a semaphore is destroyed, the memory it used is returned to the system
 * heap, so that further references to this semaphore are not guaranteed to
 * fail, as is the case for unnamed semaphores.
 *
 * This service fails if @a sm is an unnamed semaphore.
 *
 * @param sm the semaphore to be closed.
 *
 * @retval 0 on success;
 * @retval -1 with @a errno set if:
 * - EINVAL, the semaphore @a sm is invalid or is an unnamed semaphore.
 *
 * @see
 * <a href="http://www.opengroup.org/onlinepubs/000095399/functions/sem_close.html">
 * Specification.</a>
 *
 */
int sem_close(sem_t * sm)
{
	struct __shadow_sem *shadow = &((union __xeno_sem *)sm)->shadow_sem;
	nsem_t *named_sem;
	spl_t s;
	int err;

	xnlock_get_irqsave(&nklock, s);

	if (shadow->magic != PSE51_NAMED_SEM_MAGIC
	    || shadow->sem->magic != PSE51_SEM_MAGIC) {
		err = EINVAL;
		goto error;
	}

	named_sem = sem2named_sem(shadow->sem);

	err = pse51_node_put(&named_sem->nodebase);

	if (err)
		goto error;

	if (pse51_node_removed_p(&named_sem->nodebase)) {
		/* unlink was called, and this semaphore is no longer referenced. */
		pse51_mark_deleted(shadow);
		pse51_mark_deleted(&named_sem->sembase);
		xnlock_put_irqrestore(&nklock, s);

		sem_destroy_inner(&named_sem->sembase, pse51_kqueues(1));
	} else if (!pse51_node_ref_p(&named_sem->nodebase)) {
		/* this semaphore is no longer referenced, but not unlinked. */
		pse51_mark_deleted(shadow);
		xnlock_put_irqrestore(&nklock, s);
	} else
		xnlock_put_irqrestore(&nklock, s);

	return 0;

      error:
	xnlock_put_irqrestore(&nklock, s);

	thread_set_errno(err);

	return -1;
}