inline bool sock_writable(int sock, long seconds = 0, long milliseconds = 0) { udp_sock s(sock); return sock_writable(s, seconds, milliseconds); }
bool connected() { return sock_writable(sock); }
static int exa_select(struct exa_select *sel) { int i; int one=0; int ret = -EFAULT; /* first phase register on each queue */ for (i = 0; i < __FD_SETSIZE; i++) { __FD_CLR(i, &sel->result); if (__FD_ISSET(i, &sel->select)) { sel->elt[i].socket = exa_getsock(i); if (sel->elt[i].socket == NULL) { ret = -EINVAL; continue; } set_callbacks(sel->elt[i].socket, &sel->elt[i]); if (sel->operation == EXA_SELECT_IN) { if (sock_readable(sel->elt[i].socket) == 1) one = 1; } if (sel->operation == EXA_SELECT_OUT) if (sock_writable(sel->elt[i].socket) == 1) one = 1; } } /* second phase : check if nothing arrived and wait if nothing arrived */ if (one==0) { int timeout = SELECT_TIMEOUT ; set_current_state(TASK_INTERRUPTIBLE); for (i = 0; i < __FD_SETSIZE; i++) { if (__FD_ISSET(i, &sel->select) && (sel->elt[i].socket != NULL)) { if (sel->operation == EXA_SELECT_IN) { if (sock_readable(sel->elt[i].socket) == 1) one = 1; } if (sel->operation == EXA_SELECT_OUT) { if (sock_writable(sel->elt[i].socket) == 1) one = 1; } } } if (one == 0) /* if some data already pending, we must not wait (or some race can occur)*/ timeout = schedule_timeout(timeout); set_current_state(TASK_RUNNING); } /* third : find wich socket receive/sent something */ for (i = __FD_SETSIZE - 1; i >= 0; i--) { if (__FD_ISSET(i, &sel->select)) { if (sel->elt[i].socket == NULL) continue; if (sel->operation == EXA_SELECT_IN) { if (sock_readable(sel->elt[i].socket) == 1) __FD_SET(i, &sel->result); } if (sel->operation == EXA_SELECT_OUT) { if (sock_writable(sel->elt[i].socket) == 1) __FD_SET(i, &sel->result); } if ((__FD_ISSET(i, &sel->result)) && (ret == -EFAULT)) ret = 0; restore_callbacks(sel->elt[i].socket, &sel->elt[i]); fput(sel->elt[i].socket->file); sel->elt[i].socket = NULL; } } /* XXX this is not an error, -EFAULT is used here as the timeout return * value.... * FIXME use ETIME to have an explicit timeout. */ if (ret == -EFAULT) __FD_ZERO(&sel->result); return ret; }