refactor(capi): make early returns consistent in C examples (#2812)

- Since the `if` condition already causes the loop to `break`,
  the `else` is not necessary. We wouldn't have reached the `else`
  block, anyway, if the prior `if` condition passed.
- We are more likely to poll a successful chunk than finish
  the request or throw an error. Thus, it is best if we go
  for the optimistic route and check for the successful
  case first.
This commit is contained in:
Basti Ortiz
2022-04-12 08:20:14 +08:00
committed by GitHub
parent e3ee1de32d
commit 1d895b8dfc
2 changed files with 105 additions and 106 deletions

View File

@@ -24,44 +24,42 @@ static size_t read_cb(void *userdata, hyper_context *ctx, uint8_t *buf, size_t b
struct conn_data *conn = (struct conn_data *)userdata; struct conn_data *conn = (struct conn_data *)userdata;
ssize_t ret = read(conn->fd, buf, buf_len); ssize_t ret = read(conn->fd, buf, buf_len);
if (ret < 0) { if (ret >= 0) {
int err = errno;
if (err == EAGAIN) {
// would block, register interest
if (conn->read_waker != NULL) {
hyper_waker_free(conn->read_waker);
}
conn->read_waker = hyper_context_waker(ctx);
return HYPER_IO_PENDING;
} else {
// kaboom
return HYPER_IO_ERROR;
}
} else {
return ret; return ret;
} }
if (errno != EAGAIN) {
// kaboom
return HYPER_IO_ERROR;
}
// would block, register interest
if (conn->read_waker != NULL) {
hyper_waker_free(conn->read_waker);
}
conn->read_waker = hyper_context_waker(ctx);
return HYPER_IO_PENDING;
} }
static size_t write_cb(void *userdata, hyper_context *ctx, const uint8_t *buf, size_t buf_len) { static size_t write_cb(void *userdata, hyper_context *ctx, const uint8_t *buf, size_t buf_len) {
struct conn_data *conn = (struct conn_data *)userdata; struct conn_data *conn = (struct conn_data *)userdata;
ssize_t ret = write(conn->fd, buf, buf_len); ssize_t ret = write(conn->fd, buf, buf_len);
if (ret < 0) { if (ret >= 0) {
int err = errno;
if (err == EAGAIN) {
// would block, register interest
if (conn->write_waker != NULL) {
hyper_waker_free(conn->write_waker);
}
conn->write_waker = hyper_context_waker(ctx);
return HYPER_IO_PENDING;
} else {
// kaboom
return HYPER_IO_ERROR;
}
} else {
return ret; return ret;
} }
if (errno != EAGAIN) {
// kaboom
return HYPER_IO_ERROR;
}
// would block, register interest
if (conn->write_waker != NULL) {
hyper_waker_free(conn->write_waker);
}
conn->write_waker = hyper_context_waker(ctx);
return HYPER_IO_PENDING;
} }
static void free_conn_data(struct conn_data *conn) { static void free_conn_data(struct conn_data *conn) {
@@ -98,9 +96,9 @@ static int connect_to(const char *host, const char *port) {
if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1) { if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1) {
break; break;
} else {
close(sfd);
} }
close(sfd);
} }
freeaddrinfo(result); freeaddrinfo(result);
@@ -142,17 +140,17 @@ typedef enum {
#define STR_ARG(XX) (uint8_t *)XX, strlen(XX) #define STR_ARG(XX) (uint8_t *)XX, strlen(XX)
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
const char *host = argc > 1 ? argv[1] : "httpbin.org"; const char *host = argc > 1 ? argv[1] : "httpbin.org";
const char *port = argc > 2 ? argv[2] : "80"; const char *port = argc > 2 ? argv[2] : "80";
const char *path = argc > 3 ? argv[3] : "/"; const char *path = argc > 3 ? argv[3] : "/";
printf("connecting to port %s on %s...\n", port, host); printf("connecting to port %s on %s...\n", port, host);
int fd = connect_to(host, port); int fd = connect_to(host, port);
if (fd < 0) { if (fd < 0) {
return 1; return 1;
} }
printf("connected to %s, now get %s\n", host, path);
printf("connected to %s, now get %s\n", host, path);
if (fcntl(fd, F_SETFL, O_NONBLOCK) != 0) { if (fcntl(fd, F_SETFL, O_NONBLOCK) != 0) {
printf("failed to set socket to non-blocking\n"); printf("failed to set socket to non-blocking\n");
return 1; return 1;
@@ -168,7 +166,6 @@ int main(int argc, char *argv[]) {
conn->read_waker = NULL; conn->read_waker = NULL;
conn->write_waker = NULL; conn->write_waker = NULL;
// Hookup the IO // Hookup the IO
hyper_io *io = hyper_io_new(); hyper_io *io = hyper_io_new();
hyper_io_set_userdata(io, (void *)conn); hyper_io_set_userdata(io, (void *)conn);
@@ -315,15 +312,16 @@ int main(int argc, char *argv[]) {
if (sel_ret < 0) { if (sel_ret < 0) {
printf("select() error\n"); printf("select() error\n");
return 1; return 1;
} else { }
if (FD_ISSET(conn->fd, &fds_read)) {
hyper_waker_wake(conn->read_waker); if (FD_ISSET(conn->fd, &fds_read)) {
conn->read_waker = NULL; hyper_waker_wake(conn->read_waker);
} conn->read_waker = NULL;
if (FD_ISSET(conn->fd, &fds_write)) { }
hyper_waker_wake(conn->write_waker);
conn->write_waker = NULL; if (FD_ISSET(conn->fd, &fds_write)) {
} hyper_waker_wake(conn->write_waker);
conn->write_waker = NULL;
} }
} }

View File

@@ -24,44 +24,42 @@ static size_t read_cb(void *userdata, hyper_context *ctx, uint8_t *buf, size_t b
struct conn_data *conn = (struct conn_data *)userdata; struct conn_data *conn = (struct conn_data *)userdata;
ssize_t ret = read(conn->fd, buf, buf_len); ssize_t ret = read(conn->fd, buf, buf_len);
if (ret < 0) { if (ret >= 0) {
int err = errno;
if (err == EAGAIN) {
// would block, register interest
if (conn->read_waker != NULL) {
hyper_waker_free(conn->read_waker);
}
conn->read_waker = hyper_context_waker(ctx);
return HYPER_IO_PENDING;
} else {
// kaboom
return HYPER_IO_ERROR;
}
} else {
return ret; return ret;
} }
if (errno != EAGAIN) {
// kaboom
return HYPER_IO_ERROR;
}
// would block, register interest
if (conn->read_waker != NULL) {
hyper_waker_free(conn->read_waker);
}
conn->read_waker = hyper_context_waker(ctx);
return HYPER_IO_PENDING;
} }
static size_t write_cb(void *userdata, hyper_context *ctx, const uint8_t *buf, size_t buf_len) { static size_t write_cb(void *userdata, hyper_context *ctx, const uint8_t *buf, size_t buf_len) {
struct conn_data *conn = (struct conn_data *)userdata; struct conn_data *conn = (struct conn_data *)userdata;
ssize_t ret = write(conn->fd, buf, buf_len); ssize_t ret = write(conn->fd, buf, buf_len);
if (ret < 0) { if (ret >= 0) {
int err = errno;
if (err == EAGAIN) {
// would block, register interest
if (conn->write_waker != NULL) {
hyper_waker_free(conn->write_waker);
}
conn->write_waker = hyper_context_waker(ctx);
return HYPER_IO_PENDING;
} else {
// kaboom
return HYPER_IO_ERROR;
}
} else {
return ret; return ret;
} }
if (errno != EAGAIN) {
// kaboom
return HYPER_IO_ERROR;
}
// would block, register interest
if (conn->write_waker != NULL) {
hyper_waker_free(conn->write_waker);
}
conn->write_waker = hyper_context_waker(ctx);
return HYPER_IO_PENDING;
} }
static void free_conn_data(struct conn_data *conn) { static void free_conn_data(struct conn_data *conn) {
@@ -98,9 +96,9 @@ static int connect_to(const char *host, const char *port) {
if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1) { if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1) {
break; break;
} else {
close(sfd);
} }
close(sfd);
} }
freeaddrinfo(result); freeaddrinfo(result);
@@ -126,17 +124,20 @@ static int poll_req_upload(void *userdata,
struct upload_body* upload = userdata; struct upload_body* upload = userdata;
ssize_t res = read(upload->fd, upload->buf, upload->len); ssize_t res = read(upload->fd, upload->buf, upload->len);
if (res < 0) { if (res > 0) {
printf("error reading upload file: %d", errno);
return HYPER_POLL_ERROR;
} else if (res == 0) {
// All done!
*chunk = NULL;
return HYPER_POLL_READY;
} else {
*chunk = hyper_buf_copy(upload->buf, res); *chunk = hyper_buf_copy(upload->buf, res);
return HYPER_POLL_READY; return HYPER_POLL_READY;
} }
if (res == 0) {
// All done!
*chunk = NULL;
return HYPER_POLL_READY;
}
// Oh no!
printf("error reading upload file: %d", errno);
return HYPER_POLL_ERROR;
} }
static int print_each_header(void *userdata, static int print_each_header(void *userdata,
@@ -348,20 +349,20 @@ int main(int argc, char *argv[]) {
hyper_executor_push(exec, body_data); hyper_executor_push(exec, body_data);
break; break;
} else {
assert(task_type == HYPER_TASK_EMPTY);
hyper_task_free(task);
hyper_body_free(resp_body);
printf("\n -- Done! -- \n");
// Cleaning up before exiting
hyper_executor_free(exec);
free_conn_data(conn);
free(upload.buf);
return 0;
} }
assert(task_type == HYPER_TASK_EMPTY);
hyper_task_free(task);
hyper_body_free(resp_body);
printf("\n -- Done! -- \n");
// Cleaning up before exiting
hyper_executor_free(exec);
free_conn_data(conn);
free(upload.buf);
return 0;
case EXAMPLE_NOT_SET: case EXAMPLE_NOT_SET:
// A background task for hyper completed... // A background task for hyper completed...
hyper_task_free(task); hyper_task_free(task);
@@ -387,17 +388,17 @@ int main(int argc, char *argv[]) {
if (sel_ret < 0) { if (sel_ret < 0) {
printf("select() error\n"); printf("select() error\n");
return 1; return 1;
} else {
if (FD_ISSET(conn->fd, &fds_read)) {
hyper_waker_wake(conn->read_waker);
conn->read_waker = NULL;
}
if (FD_ISSET(conn->fd, &fds_write)) {
hyper_waker_wake(conn->write_waker);
conn->write_waker = NULL;
}
} }
if (FD_ISSET(conn->fd, &fds_read)) {
hyper_waker_wake(conn->read_waker);
conn->read_waker = NULL;
}
if (FD_ISSET(conn->fd, &fds_write)) {
hyper_waker_wake(conn->write_waker);
conn->write_waker = NULL;
}
} }