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
next 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).