};
/** Clients will be kicked if there are more than that many bytes pending. */
-#define MAX_BACKLOG 40000
+#define MAX_BACKLOG 400000
/** The list of connected clients. */
static struct list_head clients;
/** The whitelist/blacklist. */
static struct list_head access_perm_list;
+struct chunk_queue{
+ /** The list of pending chunks for this client. */
+ struct list_head q;
+ /** The number of pending bytes for this client. */
+ unsigned long num_pending;
+ unsigned long max_pending;
+};
+
/** Describes one client that connected the tcp port of the http sender. */
struct http_client {
/** The file descriptor of the client. */
/** The position of this client in the client list. */
struct list_head node;
/** The list of pending chunks for this client. */
- struct list_head chunk_queue;
- /** The number of pending bytes for this client. */
- unsigned long cq_bytes;
+ struct chunk_queue cq;
};
/**
numclients--;
close(hc->fd);
del_close_on_fork_list(hc->fd);
- list_for_each_entry_safe(qc, tmp, &hc->chunk_queue, node) {
+ list_for_each_entry_safe(qc, tmp, &hc->cq.q, node) {
list_del(&qc->node);
free(qc);
}
return http_send_msg(hc, HTTP_ERR_MSG);
}
-static int queue_chunk(struct http_client *hc, long unsigned chunk_num,
+static int enqueue_chunk(struct http_client *hc, long unsigned chunk_num,
size_t sent)
{
struct queued_chunk *qc;
return ret;
} else
buf = vss_get_header(&len);
- if (hc->cq_bytes + len > MAX_BACKLOG)
+ if (hc->cq.num_pending + len > MAX_BACKLOG)
return -E_QUEUE;
qc = para_malloc(sizeof(struct queued_chunk));
- hc->cq_bytes += len;
+ hc->cq.num_pending += len;
qc->chunk_num = chunk_num;
qc->sent = sent;
- list_add_tail(&qc->node, &hc->chunk_queue);
- PARA_INFO_LOG("%lu bytes queued for fd %d\n", hc->cq_bytes, hc->fd);
+ list_add_tail(&qc->node, &hc->cq.q);
+ PARA_INFO_LOG("%lu bytes queued for fd %d\n", hc->cq.num_pending, hc->fd);
return 1;
}
int ret;
struct queued_chunk *qc, *tmp;
- if (list_empty(&hc->chunk_queue))
+ if (list_empty(&hc->cq.q))
return 1;
- list_for_each_entry_safe(qc, tmp, &hc->chunk_queue, node) {
+ list_for_each_entry_safe(qc, tmp, &hc->cq.q, node) {
char *buf;
size_t len;
ret = write_ok(hc->fd);
ret = write(hc->fd, buf + qc->sent, len - qc->sent);
if (ret < 0)
return -1; /* FIXME */
- hc->cq_bytes -= ret;
+ hc->cq.num_pending -= ret;
if (ret != len - qc->sent) {
qc->sent += ret;
return 0;
static int queue_chunk_or_shutdown(struct http_client *hc, long unsigned chunk_num,
size_t sent)
{
- int ret = queue_chunk(hc, chunk_num, sent);
+ int ret = enqueue_chunk(hc, chunk_num, sent);
if (ret < 0)
http_shutdown_client(hc, "queue error");
return ret;
if (!ret || write_ok(hc->fd) <= 0) {
PARA_INFO_LOG("fd %d not ready (%lu bytes queued),"
" trying to queue chunk\n", hc->fd,
- hc->cq_bytes);
+ hc->cq.num_pending);
queue_chunk_or_shutdown(hc, current_chunk, 0);
continue;
}
goto err_out;
}
hc->status = HTTP_CONNECTED;
- INIT_LIST_HEAD(&hc->chunk_queue);
+ INIT_LIST_HEAD(&hc->cq.q);
PARA_INFO_LOG("accepted client #%d: %s (fd %d)\n", numclients,
CLIENT_ADDR(hc), hc->fd);
numclients++;