mwrap (Perl version) user+dev discussion/patches/pulls/bugs/help
 help / color / mirror / code / Atom feed
From: Eric Wong <e@80x24.org>
To: mwrap-perl@80x24.org
Subject: [PATCH 3/3] httpd: do not waste TSD space
Date: Wed, 21 Dec 2022 11:34:05 +0000	[thread overview]
Message-ID: <20221221113405.2129-4-e@80x24.org> (raw)
In-Reply-To: <20221221113405.2129-1-e@80x24.org>

mwrap-httpd is inherently single-threaded, and the TSD pointer
needs to be alotted to every thread.  So tie the request pointer
to the daemon itself instead of per-thread space.

If this were a dedicated multi-threaded httpd, I would be using
TSD for this.  But this is only a single-threaded embedded httpd
with many threads doing completely unrelated things.
---
 httpd.h | 46 +++++++++++++++++++++++++---------------------
 1 file changed, 25 insertions(+), 21 deletions(-)

diff --git a/httpd.h b/httpd.h
index 128836c..e528d2b 100644
--- a/httpd.h
+++ b/httpd.h
@@ -94,6 +94,7 @@ struct mw_h1d { /* the daemon + listener, a singleton */
 	/* use open_memstream + fwrite to implement a growing pollfd array */
 	struct mw_fbuf pb; /* pollfd vector */
 	pthread_t tid;
+	struct mw_h1req *shared_h1r; /* shared by all fast clients */
 	size_t pid_len;
 	char pid_str[10];
 };
@@ -104,7 +105,6 @@ union mw_sockaddr { /* cast-avoiding convenience :> */
 };
 
 static struct mw_h1d g_h1d = { .lfd = -1 };
-static MWRAP_TSD struct mw_h1req *tsd_h1r;
 
 /* sortable snapshot version of struct src_loc */
 struct h1_src_loc {
@@ -787,12 +787,22 @@ static enum mw_qev h1_dispatch(struct mw_h1 *h1, struct mw_h1req *h1r)
 	return h1_404(h1);
 }
 
+static void
+prep_trickle(struct mw_h1 *h1, struct mw_h1req *h1r, struct mw_h1d *h1d)
+{
+	if (h1->h1r) return; /* already trickling */
+	h1->h1r = h1r;
+	mwrap_assert(h1d->shared_h1r == h1r);
+	h1d->shared_h1r = NULL;
+}
+
 /*
  * nothing in the PSGI app actually reads input, but clients tend
  * to send something in the body of POST requests anyways, so we
  * just drain it
  */
-static enum mw_qev h1_drain_input(struct mw_h1 *h1, struct mw_h1req *h1r)
+static enum mw_qev h1_drain_input(struct mw_h1 *h1, struct mw_h1req *h1r,
+	struct mw_h1d *h1d)
 {
 	if (h1r) { /* initial */
 		ssize_t overread = h1r->rbuf_len - h1r->pret;
@@ -822,11 +832,7 @@ static enum mw_qev h1_drain_input(struct mw_h1 *h1, struct mw_h1req *h1r)
 		} else {
 			switch (errno) {
 			case EAGAIN:
-				if (!h1->h1r) {
-					h1->h1r = h1r;
-					mwrap_assert(tsd_h1r == h1r);
-					tsd_h1r = NULL;
-				}
+				prep_trickle(h1, h1r, h1d);
 				return MW_QEV_RD;
 			case ECONNRESET: /* common */
 			case ENOTCONN:
@@ -860,7 +866,8 @@ static void ctl_set(struct mw_h1 *h1, long n)
 	}
 }
 
-static enum mw_qev h1_parse_harder(struct mw_h1 *h1, struct mw_h1req *h1r)
+static enum mw_qev h1_parse_harder(struct mw_h1 *h1, struct mw_h1req *h1r,
+	struct mw_h1d *h1d)
 {
 	enum { HDR_IGN, HDR_XENC, HDR_CLEN } cur = HDR_IGN;
 	char *end;
@@ -940,10 +947,10 @@ static enum mw_qev h1_parse_harder(struct mw_h1 *h1, struct mw_h1req *h1r)
 		h1r->qlen = h1r->path + h1r->path_len - h1r->qstr;
 		h1r->path_len -= (h1r->qlen + 1);
 	}
-	return h1_drain_input(h1, h1r);
+	return h1_drain_input(h1, h1r, h1d);
 }
 
-static enum mw_qev h1_event_step(struct mw_h1 *h1)
+static enum mw_qev h1_event_step(struct mw_h1 *h1, struct mw_h1d *h1d)
 {
 	struct mw_h1req *h1r;
 
@@ -956,14 +963,14 @@ static enum mw_qev h1_event_step(struct mw_h1 *h1)
 		return h1_send_flush(h1);
 
 	if (h1->has_input)
-		return h1_drain_input(h1, NULL);
+		return h1_drain_input(h1, NULL, h1d);
 	/*
-	 * The majority of requests can be served using TSD rbuf,
+	 * The majority of requests can be served using per-daemon rbuf,
 	 * no need for per-client allocations unless a client trickles
 	 */
-	h1r = h1->h1r ? h1->h1r : tsd_h1r;
+	h1r = h1->h1r ? h1->h1r : h1d->shared_h1r;
 	if (!h1r) {
-		h1r = tsd_h1r = malloc(sizeof(*h1r));
+		h1r = h1d->shared_h1r = malloc(sizeof(*h1r));
 		if (!h1r) {
 			fprintf(stderr, "h1r malloc: %m\n");
 			return h1_close(h1);
@@ -982,7 +989,7 @@ static enum mw_qev h1_event_step(struct mw_h1 *h1)
 						&h1r->minor_ver, h1r->hdr,
 						&h1r->nr_hdr, h1->prev_len);
 			if (h1r->pret > 0)
-				return h1_parse_harder(h1, h1r);
+				return h1_parse_harder(h1, h1r, h1d);
 			if (h1r->pret == -1)
 				return h1_400(h1); /* parser error */
 
@@ -1001,11 +1008,8 @@ static enum mw_qev h1_event_step(struct mw_h1 *h1)
 		} else { /* r < 0 */
 			switch (errno) {
 			case EAGAIN: /* likely, detach to per-client buffer */
-				if (h1->prev_len && !h1->h1r) {
-					h1->h1r = h1r;
-					mwrap_assert(tsd_h1r == h1r);
-					tsd_h1r = NULL;
-				}
+				if (h1->prev_len)
+					prep_trickle(h1, h1r, h1d);
 				return MW_QEV_RD;
 			case ECONNRESET: /* common */
 			case ENOTCONN:
@@ -1258,7 +1262,7 @@ static void *h1d_run(void *x) /* pthread_create cb */
 					h1d_event_step(h1d);
 				} else {
 					h1 = h1_lookup(h1d, pfd[i].fd);
-					ev = h1_event_step(h1);
+					ev = h1_event_step(h1, h1d);
 					if (ev == MW_QEV_IGNORE)
 						continue;
 					h1->events = ev;

      parent reply	other threads:[~2022-12-21 11:34 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-21 11:34 [PATCH 0/3] httpd: debloating and refining Eric Wong
2022-12-21 11:34 ` [PATCH 1/3] httpd: drop connection if 404 on POST bodies Eric Wong
2022-12-21 11:34 ` [PATCH 2/3] httpd: drop persistent connection support Eric Wong
2022-12-21 11:34 ` Eric Wong [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221221113405.2129-4-e@80x24.org \
    --to=e@80x24.org \
    --cc=mwrap-perl@80x24.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mwrap-perl.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).