98 lines
2.3 KiB
C
98 lines
2.3 KiB
C
#ifndef LANDER_EVENT_LOOP
|
|
#define LANDER_EVENT_LOOP
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
|
|
// Size of the read and write buffers for each connection, in bytes
|
|
#define EVENT_LOOP_BUFFER_SIZE 1024
|
|
|
|
/**
|
|
* State of a connection
|
|
*/
|
|
typedef enum {
|
|
event_loop_conn_state_req = 0,
|
|
event_loop_conn_state_res = 1,
|
|
event_loop_conn_state_end = 2,
|
|
} event_loop_conn_state;
|
|
|
|
/**
|
|
* Represents an active connection managed by the event loop
|
|
*/
|
|
typedef struct event_loop_conn {
|
|
int fd;
|
|
event_loop_conn_state state;
|
|
// Read buffer
|
|
size_t rbuf_size;
|
|
size_t rbuf_read;
|
|
uint8_t rbuf[EVENT_LOOP_BUFFER_SIZE];
|
|
// Write buffer
|
|
size_t wbuf_size;
|
|
size_t wbuf_sent;
|
|
uint8_t wbuf[EVENT_LOOP_BUFFER_SIZE];
|
|
|
|
// If true, the server will close the connection after the final write buffer
|
|
// has been written
|
|
bool close_after_write;
|
|
// Context for a request
|
|
void *ctx;
|
|
} event_loop_conn;
|
|
|
|
/*
|
|
* Main struct object representing the event loop
|
|
*/
|
|
typedef struct event_loop {
|
|
event_loop_conn **connections;
|
|
size_t connection_count;
|
|
// Global context passed to every connection
|
|
void *gctx;
|
|
// Function to initialize a context for a connection
|
|
void *(*ctx_init)(void *gctx);
|
|
// Function to free a context for a connection
|
|
void (*ctx_free)(void *ctx);
|
|
// Function that processes incoming data
|
|
bool (*handle_data)(event_loop_conn *conn);
|
|
// Function that writes outgoing data
|
|
void (*write_data)(event_loop_conn *conn);
|
|
} event_loop;
|
|
|
|
/*
|
|
* Initialize a new connection struct
|
|
*/
|
|
event_loop_conn *event_loop_conn_init(event_loop *el);
|
|
|
|
/*
|
|
* Free a connection struct
|
|
*/
|
|
void event_loop_conn_free(event_loop *el, event_loop_conn *conn);
|
|
|
|
/*
|
|
* Handle I/O for a connection, be it reading input or writing output.
|
|
*/
|
|
void event_loop_conn_io(event_loop *el, event_loop_conn *conn);
|
|
|
|
/*
|
|
* Initialize a new event loop struct
|
|
*/
|
|
event_loop *event_loop_init();
|
|
|
|
/*
|
|
* Place a new connection into the event loop's internal array.
|
|
*
|
|
* Returns -1 if the internal realloc failed
|
|
*/
|
|
int event_loop_put(event_loop *el, event_loop_conn *conn);
|
|
|
|
/**
|
|
* Accept a new connection for the given file descriptor.
|
|
*/
|
|
int event_loop_accept(event_loop *el, int fd);
|
|
|
|
/*
|
|
* Run the event loop. This function never returns.
|
|
*/
|
|
void event_loop_run(event_loop *el, int port);
|
|
|
|
#endif
|