This parameter is not necessary because its only purpose is to
avoid the readv(2) system call in case it would likely return EAGAIN
because we just called select(2) which reported that there is no data
to read. Since the parameter is an obstacle for the conversion of
the code base from select(2) to poll(2), get rid of it for the time
being. If needed we can add back an equivalent optimization which
checks for POLLIN after the conversion.
14 files changed:
PARA_EMERG_LOG("para_server died\n");
goto shutdown;
}
PARA_EMERG_LOG("para_server died\n");
goto shutdown;
}
- signum = para_next_signal(&s->rfds);
+ signum = para_next_signal();
if (signum == 0)
return 0;
if (signum == SIGHUP) {
if (signum == 0)
return 0;
if (signum == SIGHUP) {
-static int execute_server_command(fd_set *rfds)
+static int execute_server_command(void)
- int ret = read_nonblock(server_socket, buf, sizeof(buf) - 1, rfds, &n);
+ int ret = read_nonblock(server_socket, buf, sizeof(buf) - 1, &n);
if (ret < 0 || n == 0)
return ret;
if (ret < 0 || n == 0)
return ret;
}
/* returns 0 if no data available, 1 else */
}
/* returns 0 if no data available, 1 else */
-static int execute_afs_command(int fd, fd_set *rfds)
+static int execute_afs_command(int fd)
{
uint32_t cookie;
int query_shmid;
char buf[sizeof(cookie) + sizeof(query_shmid)];
size_t n;
{
uint32_t cookie;
int query_shmid;
char buf[sizeof(cookie) + sizeof(query_shmid)];
size_t n;
- int ret = read_nonblock(fd, buf, sizeof(buf), rfds, &n);
+ int ret = read_nonblock(fd, buf, sizeof(buf), &n);
ret = task_get_notification(ct->task);
if (ret < 0)
return ret;
ret = task_get_notification(ct->task);
if (ret < 0)
return ret;
- ret = execute_server_command(&s->rfds);
+ ret = execute_server_command();
if (ret < 0) {
PARA_EMERG_LOG("%s\n", para_strerror(-ret));
task_notify_all(s, -ret);
if (ret < 0) {
PARA_EMERG_LOG("%s\n", para_strerror(-ret));
task_notify_all(s, -ret);
}
/* Check the list of connected clients. */
list_for_each_entry_safe(client, tmp, &afs_client_list, node) {
}
/* Check the list of connected clients. */
list_for_each_entry_safe(client, tmp, &afs_client_list, node) {
- ret = execute_afs_command(client->fd, &s->rfds);
+ ret = execute_afs_command(client->fd);
if (ret == 0) { /* prevent bogus connection flooding */
struct timeval diff;
tv_diff(now, &client->connect_time, &diff);
if (ret == 0) { /* prevent bogus connection flooding */
struct timeval diff;
tv_diff(now, &client->connect_time, &diff);
ret = task_get_notification(st->task);
if (ret < 0)
return ret;
ret = task_get_notification(st->task);
if (ret < 0)
return ret;
- signum = para_next_signal(&s->rfds);
+ signum = para_next_signal();
switch (signum) {
case SIGINT:
case SIGTERM:
switch (signum) {
case SIGINT:
case SIGTERM:
-static int recv_sb(struct client_task *ct, fd_set *rfds,
- struct sb_buffer *result)
+static int recv_sb(struct client_task *ct, struct sb_buffer *result)
void *trafo_context;
struct iovec iov;
void *trafo_context;
struct iovec iov;
- if (!FD_ISSET(ct->scc.fd, rfds))
- return 0;
if (ct->status < CL_SENT_CH_RESPONSE)
trafo = trafo_context = NULL;
else {
if (ct->status < CL_SENT_CH_RESPONSE)
trafo = trafo_context = NULL;
else {
ct->sbc[0] = sb_new_recv(0, trafo, trafo_context);
again:
sb_get_recv_buffer(ct->sbc[0], &iov);
ct->sbc[0] = sb_new_recv(0, trafo, trafo_context);
again:
sb_get_recv_buffer(ct->sbc[0], &iov);
- ret = read_nonblock(ct->scc.fd, iov.iov_base, iov.iov_len, rfds, &n);
+ ret = read_nonblock(ct->scc.fd, iov.iov_base, iov.iov_len, &n);
if (ret < 0) {
sb_free(ct->sbc[0]);
ct->sbc[0] = NULL;
if (ret < 0) {
sb_free(ct->sbc[0]);
ct->sbc[0] = NULL;
return 0;
switch (ct->status) {
case CL_CONNECTED: /* receive welcome message */
return 0;
switch (ct->status) {
case CL_CONNECTED: /* receive welcome message */
- ret = read_nonblock(ct->scc.fd, buf, sizeof(buf), &s->rfds, &n);
+ ret = read_nonblock(ct->scc.fd, buf, sizeof(buf), &n);
if (ret < 0 || n == 0)
goto out;
ct->features = parse_features(buf);
if (ret < 0 || n == 0)
goto out;
ct->features = parse_features(buf);
unsigned char crypt_buf[1024];
struct sb_buffer sbb;
unsigned char crypt_buf[1024];
struct sb_buffer sbb;
- ret = recv_sb(ct, &s->rfds, &sbb);
+ ret = recv_sb(ct, &sbb);
if (ret <= 0)
goto out;
if (sbb.band != SBD_CHALLENGE) {
if (ret <= 0)
goto out;
if (sbb.band != SBD_CHALLENGE) {
case CL_SENT_CH_RESPONSE: /* read server response */
{
struct sb_buffer sbb;
case CL_SENT_CH_RESPONSE: /* read server response */
{
struct sb_buffer sbb;
- ret = recv_sb(ct, &s->rfds, &sbb);
+ ret = recv_sb(ct, &sbb);
if (ret <= 0)
goto out;
free(sbb.iov.iov_base);
if (ret <= 0)
goto out;
free(sbb.iov.iov_base);
goto close0;
if (ret > 0 && FD_ISSET(ct->scc.fd, &s->rfds)) {
struct sb_buffer sbb;
goto close0;
if (ret > 0 && FD_ISSET(ct->scc.fd, &s->rfds)) {
struct sb_buffer sbb;
- ret = recv_sb(ct, &s->rfds, &sbb);
+ ret = recv_sb(ct, &sbb);
if (ret < 0)
goto close0;
if (ret > 0) {
if (ret < 0)
goto close0;
if (ret > 0) {
para_fd_set(rn->fd, &s->rfds, &s->max_fileno);
}
para_fd_set(rn->fd, &s->rfds, &s->max_fileno);
}
-static int dccp_recv_post_select(struct sched *s, void *context)
+static int dccp_recv_post_select(__a_unused struct sched *s, void *context)
{
struct receiver_node *rn = context;
struct btr_node *btrn = rn->btrn;
{
struct receiver_node *rn = context;
struct btr_node *btrn = rn->btrn;
ret = -E_DCCP_OVERRUN;
if (iovcnt == 0)
goto out;
ret = -E_DCCP_OVERRUN;
if (iovcnt == 0)
goto out;
- ret = readv_nonblock(rn->fd, iov, iovcnt, &s->rfds, &num_bytes);
+ ret = readv_nonblock(rn->fd, iov, iovcnt, &num_bytes);
if (num_bytes == 0)
goto out;
if (num_bytes <= iov[0].iov_len) /* only the first buffer was filled */
if (num_bytes == 0)
goto out;
if (num_bytes <= iov[0].iov_len) /* only the first buffer was filled */
* \param fd The file descriptor to read from.
* \param iov Scatter/gather array used in readv().
* \param iovcnt Number of elements in \a iov.
* \param fd The file descriptor to read from.
* \param iov Scatter/gather array used in readv().
* \param iovcnt Number of elements in \a iov.
- * \param rfds An optional fd set pointer.
* \param num_bytes Result pointer. Contains the number of bytes read from \a fd.
*
* \param num_bytes Result pointer. Contains the number of bytes read from \a fd.
*
- * If rfds is not NULL and the (non-blocking) file descriptor fd is not set in
- * rfds, this function returns early without doing anything. Otherwise it tries
- * to read up to sz bytes from fd, where sz is the sum of the lengths of all
- * vectors in iov. Like \ref xwrite(), EAGAIN and EINTR are not considered
- * error conditions. However, EOF is.
+ * This function tries to read up to sz bytes from fd, where sz is the sum of
+ * the lengths of all vectors in iov. Like \ref xwrite(), EAGAIN and EINTR are
+ * not considered error conditions. However, EOF is.
*
* \return Zero or a negative error code. If the underlying call to readv(2)
* returned zero (indicating an end of file condition) or failed for some
*
* \return Zero or a negative error code. If the underlying call to readv(2)
* returned zero (indicating an end of file condition) or failed for some
*
* \sa \ref xwrite(), read(2), readv(2).
*/
*
* \sa \ref xwrite(), read(2), readv(2).
*/
-int readv_nonblock(int fd, struct iovec *iov, int iovcnt, fd_set *rfds,
- size_t *num_bytes)
+int readv_nonblock(int fd, struct iovec *iov, int iovcnt, size_t *num_bytes)
{
int ret, i, j;
*num_bytes = 0;
{
int ret, i, j;
*num_bytes = 0;
- /*
- * Avoid a shortcoming of select(): Reads from a non-blocking fd might
- * return EAGAIN even if FD_ISSET() returns true. However, FD_ISSET()
- * returning false definitely means that no data can currently be read.
- * This is the common case, so it is worth to avoid the overhead of the
- * read() system call in this case.
- */
- if (rfds && !FD_ISSET(fd, rfds))
- return 0;
-
for (i = 0, j = 0; i < iovcnt;) {
for (i = 0, j = 0; i < iovcnt;) {
/* fix up the first iov */
assert(j < iov[i].iov_len);
iov[i].iov_base += j;
/* fix up the first iov */
assert(j < iov[i].iov_len);
iov[i].iov_base += j;
* \param fd The file descriptor to read from.
* \param buf The buffer to read data to.
* \param sz The size of \a buf.
* \param fd The file descriptor to read from.
* \param buf The buffer to read data to.
* \param sz The size of \a buf.
- * \param rfds \see \ref readv_nonblock().
* \param num_bytes \see \ref readv_nonblock().
*
* This is a simple wrapper for readv_nonblock() which uses an iovec with a single
* \param num_bytes \see \ref readv_nonblock().
*
* This is a simple wrapper for readv_nonblock() which uses an iovec with a single
*
* \return The return value of the underlying call to readv_nonblock().
*/
*
* \return The return value of the underlying call to readv_nonblock().
*/
-int read_nonblock(int fd, void *buf, size_t sz, fd_set *rfds, size_t *num_bytes)
+int read_nonblock(int fd, void *buf, size_t sz, size_t *num_bytes)
{
struct iovec iov = {.iov_base = buf, .iov_len = sz};
{
struct iovec iov = {.iov_base = buf, .iov_len = sz};
- return readv_nonblock(fd, &iov, 1, rfds, num_bytes);
+ return readv_nonblock(fd, &iov, 1, num_bytes);
* \param fd The file descriptor to receive from.
* \param pattern The expected pattern.
* \param bufsize The size of the internal buffer.
* \param fd The file descriptor to receive from.
* \param pattern The expected pattern.
* \param bufsize The size of the internal buffer.
- * \param rfds Passed to read_nonblock().
*
* This function tries to read at most \a bufsize bytes from the non-blocking
* file descriptor \a fd. If at least \p strlen(\a pattern) bytes have been
*
* This function tries to read at most \a bufsize bytes from the non-blocking
* file descriptor \a fd. If at least \p strlen(\a pattern) bytes have been
*
* \sa \ref read_nonblock(), \sa strncasecmp(3).
*/
*
* \sa \ref read_nonblock(), \sa strncasecmp(3).
*/
-int read_pattern(int fd, const char *pattern, size_t bufsize, fd_set *rfds)
+int read_pattern(int fd, const char *pattern, size_t bufsize)
{
size_t n, len;
char *buf = para_malloc(bufsize + 1);
{
size_t n, len;
char *buf = para_malloc(bufsize + 1);
- int ret = read_nonblock(fd, buf, bufsize, rfds, &n);
+ int ret = read_nonblock(fd, buf, bufsize, &n);
buf[n] = '\0';
if (ret < 0)
buf[n] = '\0';
if (ret < 0)
int read_ok(int fd);
int write_ok(int fd);
void valid_fd_012(void);
int read_ok(int fd);
int write_ok(int fd);
void valid_fd_012(void);
-int readv_nonblock(int fd, struct iovec *iov, int iovcnt, fd_set *rfds,
- size_t *num_bytes);
-int read_nonblock(int fd, void *buf, size_t sz, fd_set *rfds, size_t *num_bytes);
-int read_pattern(int fd, const char *pattern, size_t bufsize, fd_set *rfds);
+int readv_nonblock(int fd, struct iovec *iov, int iovcnt, size_t *num_bytes);
+int read_nonblock(int fd, void *buf, size_t sz, size_t *num_bytes);
+int read_pattern(int fd, const char *pattern, size_t bufsize);
int xwrite(int fd, const char *buf, size_t len);
int xwritev(int fd, struct iovec *iov, int iovcnt);
int for_each_file_in_dir(const char *dirname,
int xwrite(int fd, const char *buf, size_t len);
int xwritev(int fd, struct iovec *iov, int iovcnt);
int for_each_file_in_dir(const char *dirname,
sched_request_barrier_or_min_delay(&st->next_exec, s);
}
sched_request_barrier_or_min_delay(&st->next_exec, s);
}
-static int status_post_select(struct sched *s, void *context)
+static int status_post_select(__a_unused struct sched *s, void *context)
{
struct status_task *st = context;
size_t sz;
{
struct status_task *st = context;
size_t sz;
}
assert(st->loaded < st->bufsize);
ret = read_nonblock(st->fd, st->buf + st->loaded,
}
assert(st->loaded < st->bufsize);
ret = read_nonblock(st->fd, st->buf + st->loaded,
- st->bufsize - st->loaded, &s->rfds, &sz);
+ st->bufsize - st->loaded, &sz);
st->loaded += sz;
ret2 = for_each_stat_item(st->buf, st->loaded, update_item);
if (ret < 0 || ret2 < 0) {
st->loaded += sz;
ret2 = for_each_stat_item(st->buf, st->loaded, update_item);
if (ret < 0 || ret2 < 0) {
/* React to various signal-related events. */
static int signal_post_select(struct sched *s, __a_unused void *context)
{
/* React to various signal-related events. */
static int signal_post_select(struct sched *s, __a_unused void *context)
{
- int ret = para_next_signal(&s->rfds);
+ int ret = para_next_signal();
-static int exec_post_select(struct sched *s, void *context)
+static int exec_post_select(__a_unused struct sched *s, void *context)
{
struct exec_task *ct = context;
int i, ret;
{
struct exec_task *ct = context;
int i, ret;
continue;
ret = read_nonblock(exec_fds[i],
ct->command_buf[i] + ct->cbo[i],
continue;
ret = read_nonblock(exec_fds[i],
ct->command_buf[i] + ct->cbo[i],
- COMMAND_BUF_SIZE - 1 - ct->cbo[i], &s->rfds, &sz);
+ COMMAND_BUF_SIZE - 1 - ct->cbo[i], &sz);
ct->cbo[i] += sz;
sz = ct->cbo[i];
ct->cbo[i] = for_each_line(ct->flags[i], ct->command_buf[i],
ct->cbo[i] += sz;
sz = ct->cbo[i];
ct->cbo[i] = for_each_line(ct->flags[i], ct->command_buf[i],
return 0;
}
if (phd->status == HTTP_SENT_GET_REQUEST) {
return 0;
}
if (phd->status == HTTP_SENT_GET_REQUEST) {
- ret = read_pattern(rn->fd, HTTP_OK_MSG, strlen(HTTP_OK_MSG), &s->rfds);
+ ret = read_pattern(rn->fd, HTTP_OK_MSG, strlen(HTTP_OK_MSG));
if (ret < 0) {
PARA_ERROR_LOG("did not receive HTTP OK message\n");
goto out;
if (ret < 0) {
PARA_ERROR_LOG("did not receive HTTP OK message\n");
goto out;
iovcnt = btr_pool_get_buffers(rn->btrp, iov);
if (iovcnt == 0)
goto out;
iovcnt = btr_pool_get_buffers(rn->btrp, iov);
if (iovcnt == 0)
goto out;
- ret = readv_nonblock(rn->fd, iov, iovcnt, &s->rfds, &num_bytes);
+ ret = readv_nonblock(rn->fd, iov, iovcnt, &num_bytes);
if (num_bytes == 0)
goto out;
if (num_bytes <= iov[0].iov_len) /* only the first buffer was filled */
if (num_bytes == 0)
goto out;
if (num_bytes <= iov[0].iov_len) /* only the first buffer was filled */
case HTTP_STREAMING: /* nothing to do */
break;
case HTTP_CONNECTED: /* need to recv get request */
case HTTP_STREAMING: /* nothing to do */
break;
case HTTP_CONNECTED: /* need to recv get request */
- ret = read_pattern(sc->fd, HTTP_GET_MSG, MAXLINE, rfds);
+ ret = read_pattern(sc->fd, HTTP_GET_MSG, MAXLINE);
if (ret < 0)
phsd->status = HTTP_INVALID_GET_REQUEST;
else if (ret > 0) {
if (ret < 0)
phsd->status = HTTP_INVALID_GET_REQUEST;
else if (ret > 0) {
ret = task_get_notification(signal_task->task);
if (ret < 0)
return ret;
ret = task_get_notification(signal_task->task);
if (ret < 0)
return ret;
- signum = para_next_signal(&s->rfds);
+ signum = para_next_signal();
switch (signum) {
case 0:
return 0;
switch (signum) {
case 0:
return 0;
/**
* Return the number of the next pending signal.
*
/**
* Return the number of the next pending signal.
*
- * \param rfds The fd_set containing the signal pipe.
- *
* \return On success, the number of the received signal is returned. If there
* is no signal currently pending, the function returns zero. On read errors
* from the signal pipe, the process is terminated.
*/
* \return On success, the number of the received signal is returned. If there
* is no signal currently pending, the function returns zero. On read errors
* from the signal pipe, the process is terminated.
*/
-int para_next_signal(fd_set *rfds)
+int para_next_signal(void)
- int s, ret = read_nonblock(signal_pipe[0], &s, sizeof(s), rfds, &n);
+ int s, ret = read_nonblock(signal_pipe[0], &s, sizeof(s), &n);
if (ret < 0) {
PARA_EMERG_LOG("%s\n", para_strerror(-ret));
if (ret < 0) {
PARA_EMERG_LOG("%s\n", para_strerror(-ret));
void para_sigaction(int sig, void (*handler)(int));
void para_install_sighandler(int);
int para_reap_child(pid_t *pid);
void para_sigaction(int sig, void (*handler)(int));
void para_install_sighandler(int);
int para_reap_child(pid_t *pid);
-int para_next_signal(fd_set *rfds);
+int para_next_signal(void);
void signal_shutdown(struct signal_task *st);
void para_block_signal(int sig);
void para_unblock_signal(int sig);
void signal_shutdown(struct signal_task *st);
void para_block_signal(int sig);
void para_unblock_signal(int sig);
* during the previous pre_select call. If so, and if STDIN_FILENO is readable,
* data is read from stdin and fed into the buffer tree.
*/
* during the previous pre_select call. If so, and if STDIN_FILENO is readable,
* data is read from stdin and fed into the buffer tree.
*/
-static int stdin_post_select(struct sched *s, void *context)
+static int stdin_post_select(__a_unused struct sched *s, void *context)
{
struct stdin_task *sit = context;
ssize_t ret;
{
struct stdin_task *sit = context;
ssize_t ret;
* reference can not be freed, we're stuck.
*/
sz = PARA_MIN(sz, btr_pool_size(sit->btrp) / 2);
* reference can not be freed, we're stuck.
*/
sz = PARA_MIN(sz, btr_pool_size(sit->btrp) / 2);
- ret = read_nonblock(STDIN_FILENO, buf, sz, &s->rfds, &n);
+ ret = read_nonblock(STDIN_FILENO, buf, sz, &n);
if (n > 0)
btr_add_output_pool(sit->btrp, n, sit->btrn);
if (ret >= 0)
if (n > 0)
btr_add_output_pool(sit->btrp, n, sit->btrn);
if (ret >= 0)
ret = -E_UDP_OVERRUN;
if (iovcnt == 0)
goto out;
ret = -E_UDP_OVERRUN;
if (iovcnt == 0)
goto out;
- ret = readv_nonblock(rn->fd, iov, iovcnt, &s->rfds, &num_bytes);
+ ret = readv_nonblock(rn->fd, iov, iovcnt, &num_bytes);
if (num_bytes == 0)
goto out;
readv_ret = ret;
if (num_bytes == 0)
goto out;
readv_ret = ret;