Bug #760 » bug760.patch
chunk.c 2007-05-24 18:13:08.000000000 -0600 | ||
---|---|---|
return len;
|
||
}
|
||
off_t chunkqueue_memory_used(chunkqueue *cq) {
|
||
off_t used = 0;
|
||
chunk *c;
|
||
|
||
for (c = cq->first; c; c = c->next) {
|
||
used += sizeof *c;
|
||
switch (c->type) {
|
||
case MEM_CHUNK:
|
||
used += c->mem->used;
|
||
break;
|
||
case FILE_CHUNK:
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
return used;
|
||
}
|
||
off_t chunkqueue_written(chunkqueue *cq) {
|
||
off_t len = 0;
|
||
chunk *c;
|
chunk.h 2007-05-24 18:13:08.000000000 -0600 | ||
---|---|---|
int chunkqueue_remove_finished_chunks(chunkqueue *cq);
|
||
off_t chunkqueue_length(chunkqueue *c);
|
||
off_t chunkqueue_memory_used(chunkqueue *c);
|
||
off_t chunkqueue_written(chunkqueue *c);
|
||
void chunkqueue_free(chunkqueue *c);
|
||
void chunkqueue_reset(chunkqueue *c);
|
mod_fastcgi.c 2007-05-24 18:19:13.000000000 -0600 | ||
---|---|---|
FCGI_STATE_CONNECT_DELAYED,
|
||
FCGI_STATE_PREPARE_WRITE,
|
||
FCGI_STATE_WRITE,
|
||
FCGI_STATE_WRITE_QUEUE_FULL,
|
||
FCGI_STATE_READ
|
||
} fcgi_connection_state_t;
|
||
/*
|
||
* Limit on how large any write queue is allowed to grow. If the
|
||
* queue becomes larger than this, lighttpd will temporarily remove
|
||
* the *input* side fd from the event handler until the queue length
|
||
* drops. Because of the hacky way in which this feature is
|
||
* implemented, the reduced queue length won't be noticed for up to
|
||
* one second. For that reason, the queue length should be large
|
||
* enough to sustain 2-3 seconds of output across the server's
|
||
* connection. On a 100 Mbps Ethernet, that works out to about 25 MB.
|
||
* Note that a machine that serves many connections might still run
|
||
* out of memory (for example, if MAX_WRITE_QUEUE_SIZE is 32 MB, 100
|
||
* connections will expect the server to allocate 3.2 GB, which most
|
||
* systems can't handle).
|
||
*
|
||
* The correct way to implement this feature is to have
|
||
* MAX_WRITE_QUEUE_SIZE fairly small, probably around 1 MB, but have
|
||
* the wakeup done by chunk.c when the chunk queue drains
|
||
* appropriately. That requires more extensive changes, and I'm
|
||
* trying to limit the amount of code I change, so I'll leave that
|
||
* improvement to someone more familiar with lighttpd. Geoff
|
||
* Kuenning, 5/24/2007.
|
||
*/
|
||
#define MAX_WRITE_QUEUE_SIZE (1 << 25) /* 32 MB */
|
||
typedef struct {
|
||
fcgi_proc *proc;
|
||
fcgi_extension_host *host;
|
||
... | ... | |
fcgi_extension_host *host= hctx->host;
|
||
fcgi_proc *proc = hctx->proc;
|
||
|
||
/*
|
||
* Before reading, find out if the write queue is overfull.
|
||
* If so, suspend reading. Geoff Kuenning, 5/24/2007.
|
||
*/
|
||
if (chunkqueue_memory_used(con->write_queue) >= MAX_WRITE_QUEUE_SIZE) {
|
||
fdevent_event_del(srv->ev, &(hctx->fde_ndx), fcgi_fd);
|
||
fcgi_set_state(srv, hctx, FCGI_STATE_WRITE_QUEUE_FULL);
|
||
return 0;
|
||
}
|
||
/*
|
||
* check how much we have to read
|
||
*/
|
||
... | ... | |
case FCGI_STATE_READ:
|
||
/* waiting for a response */
|
||
break;
|
||
case FCGI_STATE_WRITE_QUEUE_FULL:
|
||
/*
|
||
* We stopped reading because the write queue is full.
|
||
* See if we can read again. If so, put the fd back
|
||
* in the event list. Geoff Kuenning, 5/24/2007.
|
||
*/
|
||
if (chunkqueue_memory_used(con->write_queue) < MAX_WRITE_QUEUE_SIZE) {
|
||
fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
|
||
fcgi_set_state(srv, hctx, FCGI_STATE_READ);
|
||
|
||
}
|
||
break;
|
||
default:
|
||
log_error_write(srv, __FILE__, __LINE__, "s", "(debug) unknown state");
|
||
return HANDLER_ERROR;
|
||
... | ... | |
fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
|
||
|
||
break;
|
||
case FCGI_STATE_WRITE_QUEUE_FULL:
|
||
/*
|
||
* We stopped reading because the write queue
|
||
* is full. See if we can read again. If so,
|
||
* put the fd back in the event list. Geoff
|
||
* Kuenning, 5/24/2007.
|
||
*/
|
||
if (chunkqueue_memory_used(con->write_queue) < MAX_WRITE_QUEUE_SIZE) {
|
||
fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
|
||
fcgi_set_state(srv, hctx, FCGI_STATE_READ);
|
||
}
|
||
break;
|
||
case FCGI_STATE_INIT:
|
||
/* at reconnect */
|
||
break;
|
- « Previous
- 1
- 2
- 3
- 4
- Next »