aboutsummaryrefslogtreecommitdiff
path: root/server_file.c
diff options
context:
space:
mode:
Diffstat (limited to 'server_file.c')
-rw-r--r--server_file.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/server_file.c b/server_file.c
index e8db8a7..74a7106 100644
--- a/server_file.c
+++ b/server_file.c
@@ -84,7 +84,29 @@ server_file(struct httpd *env, struct client *clt)
return (-1);
}
- if ((fd = open(path, O_RDONLY)) == -1 || fstat(fd, &st) == -1)
+ if ((fd = open(path, O_RDONLY)) == -1) {
+ /*
+ * Pause accept if we are out of file descriptors, or
+ * libevent will haunt us here too.
+ */
+ if (errno == ENFILE || errno == EMFILE) {
+ struct timeval evtpause = { 1, 0 };
+
+ event_del(&srv->srv_ev);
+ evtimer_add(&srv->srv_evt, &evtpause);
+ log_debug("%s: deferring connections", __func__);
+ return (0);
+ }
+ }
+
+ if (clt->clt_persist <= 1) {
+ server_inflight--;
+ DPRINTF("%s: inflight decremented, now %d",
+ __func__, server_inflight);
+ event_add(&srv->srv_ev, NULL);
+ }
+
+ if (fstat(fd, &st) == -1)
goto fail;
media = media_find(env->sc_mediatypes, path);
@@ -112,7 +134,7 @@ server_file(struct httpd *env, struct client *clt)
bufferevent_settimeout(clt->clt_file,
srv->srv_conf.timeout.tv_sec, srv->srv_conf.timeout.tv_sec);
- bufferevent_enable(clt->clt_file, EV_READ);
+ bufferevent_enable(clt->clt_file, EV_READ|EV_WRITE);
return (0);
fail: