9front - general discussion about 9front
 help / color / mirror / Atom feed
From: james palmer <james@biobuf.link>
To: 9front@9front.org
Subject: [9front] [PATCH] acme: limit reads of the event file to one read.
Date: Fri, 11 Jun 2021 21:00:24 +0100	[thread overview]
Message-ID: <AD2DBCBD646D70FB0853D9EE79CD08A1@biobuf.link> (raw)

this patch limits acme to one message per read of the event file.
this makes writing clients easier because events can be read into a
sufficiently large buffer and parsed instead of read one byte at a time.

git/import-able patch follows.

- james

 From 189797ed9098d5f6cc06cda299f1941dc07dee08
From: james palmer <foura@biobuf.link>
Date: Fri, 11 Jun 2021 19:41:38 +0000
Subject: [PATCH] acme: limit reads of the events file to one event for easier parsing.

---
diff 3ec67240f59d1e68b8d7fcb30fa17fe87f317bff 189797ed9098d5f6cc06cda299f1941dc07dee08
--- a/sys/src/cmd/acme/dat.h	Mon Jun  7 10:13:51 2021
+++ b/sys/src/cmd/acme/dat.h	Fri Jun 11 20:41:38 2021
@@ -44,6 +44,7 @@
 typedef	struct	Fid Fid;
 typedef	struct	File File;
 typedef	struct	Elog Elog;
+typedef struct	Event Event;
 typedef	struct	Mntdir Mntdir;
 typedef	struct	Range Range;
 typedef	struct	Rangeset Rangeset;
@@ -256,8 +257,8 @@
 	int		rdselfd;
 	Column	*col;
 	Xfid		*eventx;
-	char		*events;
-	int		nevents;
+	Event	*evhead;
+	Event	*evtail;
 	int		owner;
 	int		maxlines;
 	Dirlist	**dlp;
@@ -278,6 +279,14 @@
 	int		tagexpand;
 	int		taglines;
 	Rectangle	tagtop;
+	int deleted;
+};
+
+struct Event {
+	char *buf;
+	int sz;
+	int offset;
+	Event *next;
 };
 
 void	wininit(Window*, Window*, Rectangle);
--- a/sys/src/cmd/acme/wind.c	Mon Jun  7 10:13:51 2021
+++ b/sys/src/cmd/acme/wind.c	Fri Jun 11 20:41:38 2021
@@ -22,6 +22,9 @@
 	Rune *rp;
 	int nc, i;
 
+	w->deleted = 0;
+	w->evhead = nil;
+	w->evtail = nil;
 	w->tag.w = w;
 	w->taglines = 1;
 	w->tagexpand = TRUE;
@@ -311,6 +314,7 @@
 winclose(Window *w)
 {
 	int i;
+	Event *cur, *next;
 
 	if(decref(w) == 0){
 		xfidlog(w, "del");
@@ -322,7 +326,15 @@
 		for(i=0; i<w->nincl; i++)
 			free(w->incl[i]);
 		free(w->incl);
-		free(w->events);
+		
+		cur = w->evhead;
+		while(cur) {
+			next = cur->next;
+			free(cur);
+			free(cur->buf);
+			cur = next;
+		}
+		
 		free(w);
 	}
 }
@@ -331,12 +343,21 @@
 windelete(Window *w)
 {
 	Xfid *x;
+	Event *cur, *next;
 
 	x = w->eventx;
 	if(x){
-		w->nevents = 0;
-		free(w->events);
-		w->events = nil;
+		cur = w->evhead;
+		while(cur) {
+			next = cur->next;
+			free(cur->buf);
+			free(cur);
+			cur = next;
+		}
+		
+		w->deleted = 1;
+		w->evhead = nil;
+		w->evtail = nil;
 		w->eventx = nil;
 		sendp(x->c, nil);	/* wake him up */
 	}
@@ -669,26 +690,42 @@
 void
 winevent(Window *w, char *fmt, ...)
 {
-	int n;
-	char *b;
 	Xfid *x;
+	char *buf;
 	va_list arg;
+	Event *ev;
 
 	if(w->nopen[QWevent] == 0)
 		return;
 	if(w->owner == 0)
-		error("no window owner");
+		error("no window owner");	
+		
+	ev = emalloc(sizeof(Event));
+	ev->next = nil;
+
 	va_start(arg, fmt);
-	b = vsmprint(fmt, arg);
+	buf = vsmprint(fmt, arg);
 	va_end(arg);
-	if(b == nil)
+	
+	if(buf == nil)
 		error("vsmprint failed");
-	n = strlen(b);
-	w->events = erealloc(w->events, w->nevents+1+n);
-	w->events[w->nevents++] = w->owner;
-	memmove(w->events+w->nevents, b, n);
-	free(b);
-	w->nevents += n;
+		
+	ev->buf = smprint("%c%s", w->owner, buf);
+	if(!ev->buf)
+		error("smprint failed");
+	free(buf);
+	
+	ev->offset = 0;
+	ev->sz = strlen(ev->buf);
+	
+	if(w->evhead) {
+		w->evtail->next = ev;
+		w->evtail = ev;
+	} else {
+		w->evhead = ev;
+		w->evtail = ev;
+	}
+	
 	x = w->eventx;
 	if(x){
 		w->eventx = nil;
--- a/sys/src/cmd/acme/xfid.c	Mon Jun  7 10:13:51 2021
+++ b/sys/src/cmd/acme/xfid.c	Fri Jun 11 20:41:38 2021
@@ -991,34 +991,45 @@
 xfideventread(Xfid *x, Window *w)
 {
 	Fcall fc;
-	char *b;
-	int i, n;
+	Event *ev;
+	int bufsz;
+	char *buf;
 
-	i = 0;
 	x->flushed = FALSE;
-	while(w->nevents == 0){
-		if(i){
-			if(!x->flushed)
-				respond(x, &fc, "window shut down");
+	while(!w->evhead){
+		if(w->deleted) {
+			respond(x, &fc, "window shut down");
 			return;
 		}
+		
 		w->eventx = x;
 		winunlock(w);
 		recvp(x->c);
 		winlock(w, 'F');
-		i++;
 	}
-
-	n = w->nevents;
-	if(n > x->count)
-		n = x->count;
-	fc.count = n;
-	fc.data = w->events;
+	
+	ev = w->evhead;
+	bufsz = ev->sz - ev->offset < x->count
+		? ev->sz - ev->offset : x->count;
+	buf = emalloc(bufsz);
+	
+	memcpy(buf, ev->buf+ev->offset, bufsz);
+	ev->offset += bufsz;
+	
+	if(ev->offset == bufsz) {
+		w->evhead = ev->next;
+		free(ev->buf);
+		free(ev);
+		
+		if(!w->evhead)
+			w->evtail = nil;
+	}
+		
+	
+	fc.count = bufsz;
+	fc.data = buf;
 	respond(x, &fc, nil);
-	b = w->events;
-	w->events = estrdup(w->events+n);
-	free(b);
-	w->nevents -= n;
+	free(buf);
 }
 
 void


             reply	other threads:[~2021-06-12  2:58 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-11 20:00 james palmer [this message]
2021-06-12 11:43 ` james palmer
2021-06-12 14:22   ` james palmer
2021-06-12 14:10 ` ori

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=AD2DBCBD646D70FB0853D9EE79CD08A1@biobuf.link \
    --to=james@biobuf.link \
    --cc=9front@9front.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.
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 NNTP newsgroup(s).