Example #1
0
int
_sem_wait(sem_t *sem)
{
	struct pthread *curthread;
	int retval;

	if (sem_check_validity(sem) != 0)
		return (-1);

	curthread = _get_curthread();
	if ((*sem)->syssem != 0) {
		_thr_cancel_enter(curthread);
		retval = ksem_wait((*sem)->semid);
		_thr_cancel_leave(curthread, retval != 0);
	}
	else {
		_pthread_testcancel();
		_pthread_mutex_lock(&(*sem)->lock);

		while ((*sem)->count <= 0) {
			(*sem)->nwaiters++;
			THR_CLEANUP_PUSH(curthread, decrease_nwaiters, sem);
			_pthread_cond_wait(&(*sem)->gtzero, &(*sem)->lock);
			THR_CLEANUP_POP(curthread, 0);
			(*sem)->nwaiters--;
		}
		(*sem)->count--;

		_pthread_mutex_unlock(&(*sem)->lock);

		retval = 0;
	}
	return (retval);
}
Example #2
0
/*
 * Fork off a child process.  The child will open the semaphore via
 * the same name.  The child will then block on the semaphore waiting
 * for the parent to post it.
 */
static int
wait_twoproc_child(void *arg)
{
	semid_t id;

	if (ksem_open(&id, TEST_PATH, 0, 0, 0) < 0)
		return (CSTAT(1, errno));
	if (ksem_wait(id) < 0)
		return (CSTAT(2, errno));
	if (ksem_close(id) < 0)
		return (CSTAT(3, errno));
	return (CSTAT(0, 0));
}
Example #3
0
static void
use_after_unlink_test(void)
{
	semid_t id;

	/*
	 * Create named semaphore with value of 1 and then unlink it
	 * while still retaining the initial reference.
	 */
	if (ksem_open(&id, TEST_PATH, O_CREAT | O_EXCL, 0777, 1) < 0) {
		fail_errno("ksem_open(O_CREAT | O_EXCL)");
		return;
	}
	if (ksem_unlink(TEST_PATH) < 0) {
		fail_errno("ksem_unlink");
		ksem_close(id);
		return;
	}
	if (checkvalue(id, 1) < 0) {
		ksem_close(id);
		return;
	}

	/* Post the semaphore to set its value to 2. */
	if (ksem_post(id) < 0) {
		fail_errno("ksem_post");
		ksem_close(id);
		return;
	}
	if (checkvalue(id, 2) < 0) {
		ksem_close(id);
		return;
	}

	/* Wait on the semaphore which should set its value to 1. */
	if (ksem_wait(id) < 0) {
		fail_errno("ksem_wait");
		ksem_close(id);
		return;
	}
	if (checkvalue(id, 1) < 0) {
		ksem_close(id);
		return;
	}

	if (ksem_close(id) < 0) {
		fail_errno("ksem_close");
		return;
	}
	pass();
}
Example #4
0
static void
wait_invalid_semaphore(void)
{

	if (ksem_wait(STDERR_FILENO) >= 0) {
		fail_err("ksem_wait() didn't fail");
		return;
	}
	if (errno != EINVAL) {
		fail_errno("ksem_wait");
		return;
	}
	pass();
}
Example #5
0
static int
testwait(semid_t id, u_int *delta)
{
	struct timespec start, end;

	if (clock_gettime(CLOCK_REALTIME, &start) < 0) {
		fail_errno("clock_gettime(CLOCK_REALTIME)");
		return (-1);
	}
	if (ksem_wait(id) < 0) {
		fail_errno("ksem_wait");
		return (-1);
	}
	if (clock_gettime(CLOCK_REALTIME, &end) < 0) {
		fail_errno("clock_gettime(CLOCK_REALTIME)");
		return (-1);
	}
	timespecsub(&end, &start);
	*delta = end.tv_nsec / 1000000;
	*delta += end.tv_sec * 1000;
	return (0);
}
Example #6
0
static void
busy_destroy_test(void)
{
	char errbuf[_POSIX2_LINE_MAX];
	struct kinfo_proc *kp;
	semid_t id;
	pid_t pid;
	kvm_t *kd;
	int count;

	kd = kvm_openfiles(NULL, "/dev/null", NULL, O_RDONLY, errbuf);
	if (kd == NULL) {
		fail_err("kvm_openfiles: %s", errbuf);
		return;
	}

	if (ksem_init(&id, 0) < 0) {
		fail_errno("ksem_init");
		kvm_close(kd);
		return;
	}

	pid = fork();
	switch (pid) {
	case -1:
		/* Error. */
		fail_errno("fork");
		ksem_destroy(id);
		kvm_close(kd);
		return;
	case 0:
		/* Child. */
		ksem_wait(id);
		exit(0);
	}

	/*
	 * Wait for the child process to block on the semaphore.  This
	 * is a bit gross.
	 */
	for (;;) {
		kp = kvm_getprocs(kd, KERN_PROC_PID, pid, &count);
		if (kp == NULL) {
			fail_err("kvm_getprocs: %s", kvm_geterr(kd));
			kvm_close(kd);
			ksem_destroy(id);
			return;
		}
		if (kp->ki_stat == SSLEEP &&
		    (strcmp(kp->ki_wmesg, "sem") == 0 ||
		    strcmp(kp->ki_wmesg, "ksem") == 0))
			break;
		usleep(1000);
	}
	kvm_close(kd);

	ksem_destroy_should_fail(id, EBUSY);

	/* Cleanup. */
	ksem_post(id);
	waitpid(pid, NULL, 0);
	ksem_destroy(id);
}