Beispiel #1
0
static int
_svcond_signal(svcond_t *cond, int broadcast)
{
	int signals_to_issue;

	if (svsem_wait(cond->unblock_lock) == -1) {
		AMSG("");
		return -1;
	}
	if (cond->waiters_to_unblock) {
		if (cond->waiters_blocked == 0) {
			if (svsem_post(cond->unblock_lock) == -1) {
				AMSG("");
				return -1;
			}
			return 0;
		}
		if (broadcast) {
			cond->waiters_to_unblock += signals_to_issue = cond->waiters_blocked;
			cond->waiters_blocked = 0;
		} else {
			signals_to_issue = 1;
			cond->waiters_to_unblock++;
			cond->waiters_blocked--;
		}
	} else if (cond->waiters_blocked) {
		if (svsem_wait(cond->blocked_lock) == -1) {
			AMSG("");
			return -1;
		}
		if (broadcast) {
			signals_to_issue = cond->waiters_to_unblock = cond->waiters_blocked;
			cond->waiters_blocked = 0;
		} else {
			signals_to_issue = cond->waiters_to_unblock = 1;
			cond->waiters_blocked--;
		}
	} else {
		if (svsem_post(cond->unblock_lock) == -1) {
			AMSG("");
			return -1;
		}
		return 0;
	}
	if (svsem_post(cond->unblock_lock) == -1 ||
			svsem_post_multiple(cond->block_queue, signals_to_issue) == -1) {
		AMSG("");
		return -1;
	}

	return 0;
}
Beispiel #2
0
int
svcond_wait(svcond_t *cond, svsem_t *sem)
{
	int signals_left = 0;

	if (svsem_wait(cond->blocked_lock) == -1) {
		AMSG("");
		return -1;
	}
	cond->waiters_blocked++;
	svsem_post(cond->blocked_lock);

	svsem_post(sem);
	if (svsem_wait(cond->block_queue) == -1) {
		int err = errno;
		AMSG("");
		cond->waiters_blocked--;
		while (svsem_wait(sem) == -1 && errno == EINTR) {
			;
		}
		errno = err;
		return -1;
	}

	if (svsem_wait(cond->unblock_lock) == -1) {
		int err = errno;
		AMSG("");
		while (svsem_wait(sem) == -1 && errno == EINTR) {
			;
		}
		errno = err;
		return -1;
	}
	if ((signals_left = cond->waiters_to_unblock)) {
		cond->waiters_to_unblock--;
	}
	svsem_post(cond->unblock_lock);

	if (signals_left == 1) {
		svsem_post(cond->blocked_lock);
	}

	while (svsem_wait(sem) == -1) {
		if (errno != EINTR) {
			AMSG("");
			return -1;
		}
	}

	return 0;
}
Beispiel #3
0
int
run(void)
{
	int fd, *ptr, i;
	svsem_t sem;

	if ((fd = open("/tmp/SvsemCounter.shm", O_RDWR | O_CREAT, 0600)) == -1 ||
			ftruncate(fd, sizeof *ptr) == -1 ||
			(ptr = (int *)mmap(NULL, sizeof *ptr, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == NULL) {
		return -1;
	}
	close(fd);

	if (svsem_open(&sem, "/tmp/SvsemCounter.sem", SEM_UNDO) == -1) {
		return -1;
	}

	for (i = 0; i < count; i++) {
		svsem_wait(&sem);
		(*ptr)++;
		svsem_post(&sem);
	}

	svsem_close(&sem);
	munmap((void *)ptr, sizeof *ptr);

	return 0;
}
Beispiel #4
0
int
svcond_destroy(svcond_t *cond)
{
	int ret = 0;

	if (svsem_wait(cond->blocked_lock) == -1) {
		AMSG("");
		return -1;
	}
	if (svsem_trywait(cond->unblock_lock) != 0) {
		AMSG("");
		svsem_post(cond->blocked_lock);
		return -1;
	}

	if (cond) {
		if (cond->blocked_lock) {
			ret += pool_release(cond->sempool, cond->blocked_lock);
			if (cond->block_queue) {
				ret += pool_release(cond->sempool, cond->block_queue);
				if (cond->unblock_lock) {
					ret += pool_release(cond->sempool, cond->unblock_lock);
					cond->unblock_lock = NULL;
				}
				cond->block_queue = NULL;
			}
			cond->blocked_lock = NULL;
		}
	}

	return ret ? -1 : 0;
}