rem: sync.sem = create_sem(1, "select");
add: sync.sem = create_sem(0, "select");
context: common_select(int numfds, fd_set *readSet, fd_set *writeSet, fd_set *errorSet,	bigtime_t timeout, const sigset_t *sigMask, bool kernel){	struct select_sync sync;	status_t status = B_OK;	int count = 0;	int fd;	FUNCTION(("common_select(%d, %p, %p, %p, %lld, %p, %d)\n", numfds, readSet,		writeSet, errorSet, timeout, sigMask, kernel));	// ToDo: set sigMask to make pselect() functional different from select()	// check if fds are valid before doing anything	for (fd = 0; fd < numfds; fd++) {		if (((readSet && FD_ISSET(fd, readSet))			|| (writeSet && FD_ISSET(fd, writeSet))			|| (errorSet && FD_ISSET(fd, errorSet)))			&& !fd_is_valid(fd, kernel))			return B_FILE_ERROR;	}	// allocate resources	memset(&sync, 0, sizeof(select_sync));	sync.sem = create_sem(1, "select");	if (sync.sem < B_OK)		return sync.sem;	set_sem_owner(sync.sem, B_SYSTEM_TEAM);	sync.set = (select_info*)malloc(sizeof(select_info) * numfds);	if (sync.set == NULL) {		delete_sem(sync.sem);		return B_NO_MEMORY;	}	sync.count = numfds;	// start selecting file descriptors	for (fd = 0; fd < numfds; fd++) {		sync.set[fd].selected_events = 0;		sync.set[fd].events = 0;		if (readSet && FD_ISSET(fd, readSet))			sync.set[fd].selected_events = SELECT_FLAG(B_SELECT_READ);		if (writeSet && FD_ISSET(fd, writeSet))			sync.set[fd].selected_events |= SELECT_FLAG(B_SELECT_WRITE);		if (errorSet && FD_ISSET(fd, errorSet))			sync.set[fd].selected_events |= SELECT_FLAG(B_SELECT_ERROR);		count += select_events(&sync, fd, fd, sync.set[fd].selected_events, kernel);			// array position is the same as the fd for select()	}	if (count < 1) {		count = B_BAD_VALUE;		goto err;	}	status = acquire_sem_etc(sync.sem, 1,		B_CAN_INTERRUPT | (timeout != -1 ? B_RELATIVE_TIMEOUT : 0), timeout);	// deselect file descriptors	for (fd = 0; fd < numfds; fd++)		deselect_events(&sync, fd, sync.set[fd].selected_events, kernel);	// collect the events that are happened in the meantime	switch (status) {		case B_OK:			// Clear sets to store the received events			// (we don't use the macros, because we have variable sized arrays;			// the other FD_xxx() macros are safe, though).			fd_zero(readSet, numfds);			fd_zero(writeSet, numfds);			fd_zero(errorSet, numfds);			for (count = 0, fd = 0;fd < numfds; fd++) {				if (readSet && sync.set[fd].events & SELECT_FLAG(B_SELECT_READ)) {					FD_SET(fd, readSet);					count++;				}				if (writeSet && sync.set[fd].events & SELECT_FLAG(B_SELECT_WRITE)) {					FD_SET(fd, writeSet);					count++;				}				if (errorSet && sync.set[fd].events & SELECT_FLAG(B_SELECT_ERROR)) {					FD_SET(fd, errorSet);					count++;				}			}			break;		case B_INTERRUPTED:			count = B_INTERRUPTED;			break;		default:			// B_TIMED_OUT, and B_WOULD_BLOCK			count = 0;	}err:	delete_sem(sync.sem);	free(sync.set);	return count;}