refactor: make code a bit cleaner n stuff
parent
2ff70c02c6
commit
6d45ec59dc
|
@ -14,47 +14,46 @@
|
||||||
|
|
||||||
#include "event_loop_internal.h"
|
#include "event_loop_internal.h"
|
||||||
|
|
||||||
const char http_200_ok[] = "HTTP/1.1 200 OK\nContent-Length: 5\n\nhello";
|
void event_loop_conn_io_res(event_loop_conn *conn) {
|
||||||
|
while (1) {
|
||||||
|
ssize_t res = 0;
|
||||||
|
size_t remain = conn->wbuf_size - conn->wbuf_sent;
|
||||||
|
|
||||||
bool event_loop_conn_io_res(event_loop_conn *conn) {
|
do {
|
||||||
ssize_t res = 0;
|
res = write(conn->fd, &conn->wbuf[conn->wbuf_sent], remain);
|
||||||
size_t remain = conn->wbuf_size - conn->wbuf_sent;
|
} while (res < 0 && errno == EINTR);
|
||||||
|
|
||||||
do {
|
// EAGAIN doesn't mean there was an error, but rather that there's no more
|
||||||
res = write(conn->fd, &conn->wbuf[conn->wbuf_sent], remain);
|
// data right now, but there might be more later, aka "try again later"
|
||||||
} while (res < 0 && errno == EINTR);
|
if (res < 0 && errno == EAGAIN) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// EAGAIN doesn't mean there was an error, but rather that there's no more
|
// If it's not EGAIN, there was an error writing so we simply end the
|
||||||
// data right now, but there might be more later, aka "try again later"
|
// request
|
||||||
if (res < 0 && errno == EAGAIN) {
|
if (res < 0) {
|
||||||
return false;
|
conn->state = event_loop_conn_state_end;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
conn->wbuf_sent += (size_t)res;
|
||||||
|
|
||||||
|
// After writing a response, we switch back to request mode to process a
|
||||||
|
// next request
|
||||||
|
if (conn->wbuf_sent == conn->wbuf_size) {
|
||||||
|
conn->state = conn->close_after_write ? event_loop_conn_state_end
|
||||||
|
: event_loop_conn_state_req;
|
||||||
|
/* c->wbuf_sent = 0; */
|
||||||
|
/* c->wbuf_size = 0; */
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it's not EGAIN, there was an error writing so we simply end the request
|
|
||||||
if (res < 0) {
|
|
||||||
conn->state = event_loop_conn_state_end;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
conn->wbuf_sent += (size_t)res;
|
|
||||||
|
|
||||||
// After writing a response, we switch back to request mode to process a next
|
|
||||||
// request
|
|
||||||
if (conn->wbuf_sent == conn->wbuf_size) {
|
|
||||||
conn->state = conn->close_after_write ? event_loop_conn_state_end
|
|
||||||
: event_loop_conn_state_req;
|
|
||||||
/* c->wbuf_sent = 0; */
|
|
||||||
/* c->wbuf_size = 0; */
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// still got some data in wbuf, could try to write again
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool try_one_request(event_loop_conn *conn) {
|
bool event_loop_handle_request(event_loop_conn *conn) {
|
||||||
// We definitely can't do anything with zero bytes.
|
// Prevents the request handler function from looping indefinitely without
|
||||||
|
// ever consuming new data
|
||||||
if (conn->rbuf_size == 0) {
|
if (conn->rbuf_size == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -117,76 +116,68 @@ bool try_one_request(event_loop_conn *conn) {
|
||||||
*
|
*
|
||||||
* Returns whether the function should be retried immediately or not.
|
* Returns whether the function should be retried immediately or not.
|
||||||
*/
|
*/
|
||||||
bool event_loop_conn_io_req(event_loop_conn *conn) {
|
void event_loop_conn_io_req(event_loop_conn *conn) {
|
||||||
ssize_t res;
|
while (1) {
|
||||||
size_t cap = EVENT_LOOP_BUFFER_SIZE - conn->rbuf_size;
|
ssize_t res;
|
||||||
|
size_t cap = EVENT_LOOP_BUFFER_SIZE - conn->rbuf_size;
|
||||||
|
|
||||||
// Try to read at most cap bytes from the file descriptor
|
// Try to read at most cap bytes from the file descriptor
|
||||||
do {
|
do {
|
||||||
res = read(conn->fd, &conn->rbuf[conn->rbuf_size], cap);
|
res = read(conn->fd, &conn->rbuf[conn->rbuf_size], cap);
|
||||||
} while (res < 0 && errno == EINTR);
|
} while (res < 0 && errno == EINTR);
|
||||||
|
|
||||||
// EGAIN means we try again later
|
// EGAIN means we try again later
|
||||||
if (res < 0 && errno == EAGAIN) {
|
if (res < 0 && errno == EAGAIN) {
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Any other negative error message means the read errored out
|
// Any other negative error message means the read errored out
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
conn->state = event_loop_conn_state_end;
|
conn->state = event_loop_conn_state_end;
|
||||||
|
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output of 0 and no error means we've reached the end of the input. We run
|
// Output of 0 and no error means we've reached the end of the input. We run
|
||||||
// try_one_request one more time and close the connection if this doesn't
|
// try_one_request one more time and close the connection if this doesn't
|
||||||
// change the result.
|
// change the result.
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
conn->state = event_loop_conn_state_end;
|
conn->state = event_loop_conn_state_end;
|
||||||
|
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We switch to processing mode if we've reached the end of the data stream,
|
// We switch to processing mode if we've reached the end of the data stream,
|
||||||
// or if the read buffer is filled
|
// or if the read buffer is filled
|
||||||
/* if (res == 0 || c->rbuf_size == MAX_MSG_SIZE) { */
|
/* if (res == 0 || c->rbuf_size == MAX_MSG_SIZE) { */
|
||||||
/* c->state = STATE_PROCESS; */
|
/* c->state = STATE_PROCESS; */
|
||||||
/* return false; */
|
/* return false; */
|
||||||
/* } */
|
/* } */
|
||||||
|
|
||||||
conn->rbuf_size += (size_t)res;
|
conn->rbuf_size += (size_t)res;
|
||||||
|
|
||||||
/* assert(conn->rbuf_size <= sizeof(conn->rbuf)); */
|
/* assert(conn->rbuf_size <= sizeof(conn->rbuf)); */
|
||||||
|
|
||||||
// Try to process requests one by one.
|
// Try to process requests one by one.
|
||||||
// Try to process requests one by one.
|
// Try to process requests one by one.
|
||||||
// Why is there a loop? Please read the explanation of "pipelining".
|
// Why is there a loop? Please read the explanation of "pipelining".
|
||||||
while (try_one_request(conn)) {
|
while (event_loop_handle_request(conn)) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// We can keep reading as long as we're in request mode
|
// We can keep reading as long as we're in request mode
|
||||||
return conn->state == event_loop_conn_state_req;
|
if (conn->state != event_loop_conn_state_req) {
|
||||||
/* while (try_one_request(conn)) {} */
|
return;
|
||||||
/* return (conn->state == STATE_REQ); */
|
};
|
||||||
}
|
|
||||||
|
|
||||||
void conn_state_res(event_loop_conn *conn) {
|
|
||||||
while (event_loop_conn_io_res(conn)) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void conn_state_req(event_loop_conn *conn) {
|
|
||||||
while (event_loop_conn_io_req(conn)) {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void event_loop_conn_io(event_loop_conn *conn) {
|
void event_loop_conn_io(event_loop_conn *conn) {
|
||||||
switch (conn->state) {
|
switch (conn->state) {
|
||||||
case event_loop_conn_state_req:
|
case event_loop_conn_state_req:
|
||||||
conn_state_req(conn);
|
event_loop_conn_io_req(conn);
|
||||||
break;
|
break;
|
||||||
case event_loop_conn_state_res:
|
case event_loop_conn_state_res:
|
||||||
conn_state_res(conn);
|
event_loop_conn_io_res(conn);
|
||||||
break;
|
break;
|
||||||
case event_loop_conn_state_end:
|
case event_loop_conn_state_end:
|
||||||
printf("we shouldn't be here\n");
|
printf("we shouldn't be here\n");
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
const char http_404[] = "HTTP/1.1 404 Not Found\n"
|
||||||
|
"Connection: close\n"
|
||||||
|
"Content-Length: 0\n\n";
|
||||||
|
const size_t http_404_len = sizeof(http_404) - 1;
|
||||||
|
|
||||||
|
const char http_500[] = "HTTP/1.1 500 Internal Server Error\n"
|
||||||
|
"Connection: close\n"
|
||||||
|
"Content-Length: 0\n\n";
|
||||||
|
const size_t http_500_len = sizeof(http_500) - 1;
|
|
@ -53,4 +53,9 @@ int event_loop_accept(event_loop *loop, int fd);
|
||||||
|
|
||||||
void event_loop_conn_io(event_loop_conn *conn);
|
void event_loop_conn_io(event_loop_conn *conn);
|
||||||
|
|
||||||
|
extern const char http_404[];
|
||||||
|
extern const size_t http_404_len;
|
||||||
|
extern const char http_500[];
|
||||||
|
extern const size_t http_500_len;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue