109 lines
2.1 KiB
C
109 lines
2.1 KiB
C
#include "pool.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
|
|
#define DEFAULT_READ_BUF 8192
|
|
#define DEFAULT_WRITE_BUF 8192
|
|
#define DEFAULT_ARENA 4096
|
|
|
|
// pool_new creates a new connection pool.
|
|
pool_t* pool_new(runtime_t *rt, int max_conns) {
|
|
pool_t *p = calloc(1, sizeof(pool_t));
|
|
if (!p) return NULL;
|
|
|
|
p->rt = rt;
|
|
p->max_conns = max_conns;
|
|
p->read_buf_size = DEFAULT_READ_BUF;
|
|
p->write_buf_size = DEFAULT_WRITE_BUF;
|
|
p->arena_size = DEFAULT_ARENA;
|
|
|
|
// Allocate connection array
|
|
p->conns = calloc(max_conns, sizeof(conn_t));
|
|
if (!p->conns) {
|
|
free(p);
|
|
return NULL;
|
|
}
|
|
|
|
// Initialize each connection
|
|
for (int i = 0; i < max_conns; i++) {
|
|
conn_t *c = &p->conns[i];
|
|
c->pool = p;
|
|
c->state = CONN_IDLE;
|
|
|
|
c->rbuf = malloc(p->read_buf_size);
|
|
c->rsize = p->read_buf_size;
|
|
|
|
c->wbuf = malloc(p->write_buf_size);
|
|
c->wsize = p->write_buf_size;
|
|
|
|
c->arena = arena_new(p->arena_size);
|
|
|
|
if (!c->rbuf || !c->wbuf || !c->arena) {
|
|
// Cleanup on failure
|
|
pool_free(p);
|
|
return NULL;
|
|
}
|
|
|
|
// Add to free list
|
|
c->next = p->free_list;
|
|
p->free_list = c;
|
|
}
|
|
|
|
return p;
|
|
}
|
|
|
|
// pool_free destroys the pool and all connections.
|
|
void pool_free(pool_t *p) {
|
|
if (!p) return;
|
|
|
|
for (int i = 0; i < p->max_conns; i++) {
|
|
conn_t *c = &p->conns[i];
|
|
if (c->fd > 0) close(c->fd);
|
|
free(c->rbuf);
|
|
free(c->wbuf);
|
|
arena_free(c->arena);
|
|
}
|
|
|
|
free(p->conns);
|
|
free(p);
|
|
}
|
|
|
|
// pool_get retrieves a connection from the free list.
|
|
conn_t* pool_get(pool_t *p) {
|
|
if (!p->free_list) return NULL;
|
|
|
|
conn_t *c = p->free_list;
|
|
p->free_list = c->next;
|
|
c->next = NULL;
|
|
c->state = CONN_READING;
|
|
return c;
|
|
}
|
|
|
|
// pool_put returns a connection to the free list.
|
|
void pool_put(pool_t *p, conn_t *c) {
|
|
conn_reset(c);
|
|
c->state = CONN_IDLE;
|
|
c->next = p->free_list;
|
|
p->free_list = c;
|
|
}
|
|
|
|
// pool_runtime returns the pool's runtime.
|
|
runtime_t* pool_runtime(pool_t *p) {
|
|
return p->rt;
|
|
}
|
|
|
|
// pool_handle_request calls the request handler if set.
|
|
void pool_handle_request(pool_t *p, conn_t *c) {
|
|
if (p->on_request) {
|
|
p->on_request(c);
|
|
}
|
|
}
|
|
|
|
// pool_handle_close calls the close handler if set.
|
|
void pool_handle_close(pool_t *p, conn_t *c) {
|
|
if (p->on_close) {
|
|
p->on_close(c);
|
|
}
|
|
}
|