shithub: svcfs

Download patch

ref: 7f4c8f0736d52d4bff3fb0aefda9cf58bc39b5e6
parent: b512993b0e23a11ec1de50ebc0b7fee19cf994a9
author: Michael Misch <michaelmisch1985@gmail.com>
date: Thu Aug 1 01:33:42 EDT 2024

Updates found during integration

--- a/TODO
+++ b/TODO
@@ -15,4 +15,4 @@
 
 ## Notifications:
 
-- Create and update them, integrate with tabs
+- Create and update, clear when read
--- a/alt.h
+++ b/alt.h
@@ -3,7 +3,7 @@
 
 struct Buffer
 {
-	QLock;
+	QLock       l;
 	char	*name;
 	char	title[1024];
 	char	status[1024];
--- a/buffer.c
+++ b/buffer.c
@@ -18,6 +18,7 @@
 bufferDrop(Buffer *base, char *name)
 {
 	Buffer *mp, *bp;
+	qlock(&base->l);
 	for(bp = base; bp->next; bp = bp->next){
 		mp = bp->next;
 		if(strcmp(bp->next->name, name) == 0){
@@ -29,7 +30,7 @@
 				bufferFree(mp);
 		}
 	}
-				
+	qunlock(&base->l);			
 	return nil;
 }
 
@@ -39,19 +40,22 @@
 	Buffer *b, *ep;
 	char p[1024];
 
+	qlock(&base->l);
 	for(ep = base; ep->next; ep = ep->next){
-		if(ep && strcmp(ep->name, name) == 0)
+		if(ep && strcmp(ep->name, name) == 0){
+			qunlock(&base->l);
 			return "buffer exists";
+		}
 		if(ep->next == nil)
 			break;
 	}
 	
-	b = emalloc(sizeof(*b));
+	b = mallocz(sizeof(*b), 1);
 	b->name = estrdup(name);
 	b->notify = nil;
 	b->unread = 0;
 	b->tag = -1;
-	b->rz.l = b;
+	b->rz.l = &b->l;
 	memset(b->title, 0, sizeof(b->title));
 	memset(b->status, 0, sizeof(b->status));
 	memset(b->aside, 0, sizeof(b->aside));
@@ -62,7 +66,7 @@
 		b->fd = create(p, OWRITE, 0644);
 	seek(b->fd, 0, 2);
 	ep->next = b;
-
+	qunlock(&base->l);
 	return nil;
 }
 
@@ -70,9 +74,13 @@
 bufferSearch(Buffer *base, char *name)
 {
 	Buffer *sp;
+	qlock(&base->l);
 	for(sp = base; sp; sp = sp->next)
-		if(strcmp(sp->name, name) == 0)
+		if(strcmp(sp->name, name) == 0){
+			qunlock(&base->l);
 			return sp;
+		}
+	qunlock(&base->l);
 	return nil;
 }
 
@@ -80,9 +88,13 @@
 bufferSearchTag(Buffer *base, ulong tag)
 {
 	Buffer *sp;
+	qlock(&base->l);
 	for(sp = base; sp; sp = sp->next)
-		if(sp->tag == tag)
+		if(sp->tag == tag){
+			qunlock(&base->l);
 			return sp;
+		}
+	qunlock(&base->l);
 	return nil;
 }
 
@@ -91,7 +103,7 @@
 {
 	Buffer *b;
 
-	b = emalloc(sizeof(*b));
+	b = mallocz(sizeof(*b), 1);
 	b->name = nil;
 	memset(b->title, 0, sizeof(b->title));
 	memset(b->status, 0, sizeof(b->status));
@@ -101,7 +113,7 @@
 	b->unread = 0;
 	b->notify = nil;
 	b->next = nil;
-	b->rz.l = b;
+	b->rz.l = &b->l;
 
 	return b;
 }
--- a/client.c
+++ b/client.c
@@ -53,7 +53,7 @@
 
 static Client client[256];
 static Buffer *root;
-int flushtag;
+static int flushtag;
 static int nclient;
 static int time0;
 static Srv *fs;
@@ -128,7 +128,7 @@
 {
 	Clfid *f;
 
-	f = emalloc(sizeof(*f));
+	f = mallocz(sizeof(*f), 1);
 	f->cl = newclient(r->ifcall.aname);
 	f->level = Qcroot;
 	clmkqid(&r->fid->qid, f->level, nil);
@@ -182,7 +182,7 @@
 	o = oldfid->aux;
 	if(o == nil)
 		return "bad fid";
-	f = emalloc(sizeof(*f));
+	f = mallocz(sizeof(*f), 1);
 	memmove(f, o, sizeof(*f));
 	if(f->cl)
 		incref(f->cl);
@@ -230,9 +230,8 @@
 			respond(r, nil);
 			return;
 		}
-		b = f->cl->current;
 		srvrelease(fs);
-		qlock(b);
+		b = f->cl->current;
 Again:
 		// Check if we have a tag here, abort early if so.
 		if(b->tag != flushtag){	
@@ -242,13 +241,14 @@
 				r->ofcall.count = n;
 				memmove(r->ofcall.data, buf, n);
 			} else {
+				qlock(&b->l);
 				b->unread = 0;
 				rsleep(&b->rz);
+				qunlock(&b->l);
 				goto Again;
 			}
 		} else
 			flushtag = -1;
-		qunlock(b);
 		memset(buf, 0, sizeof(buf));
 		srvacquire(fs);
 		respond(r, nil);
@@ -255,8 +255,11 @@
 		return;
 	case Qtitle:
 		if(f->cl->current && f->cl->current->title){
+			b = f->cl->current;
 			memset(buf, 0, sizeof(buf));
-			snprint(buf, sizeof(buf), "%s", f->cl->current->title);
+			qlock(&b->l);
+			snprint(buf, sizeof(buf), "%s", b->title);
+			qunlock(&b->l);
 String:
 			readstr(r, buf);
 			respond(r, nil);
@@ -265,35 +268,43 @@
 		break;
 	case Qstatus:
 		if(f->cl->current && f->cl->current->status){
+			b = f->cl->current;
 			memset(buf, 0, sizeof(buf));
-			snprint(buf, sizeof(buf), "%s", f->cl->current->status);
+			qlock(&b->l);
+			snprint(buf, sizeof(buf), "%s",b->status);
+			qunlock(&b->l);
 			goto String;
 		}
 		break;
 	case Qaside:
 		if(f->cl->current && f->cl->current->aside){
+			b = f->cl->current;
 			memset(buf, 0, sizeof(buf));
-			snprint(buf, sizeof(buf), "%s", f->cl->current->aside);
+			qlock(&b->l);
+			snprint(buf, sizeof(buf), "%s", b->aside);
+			qunlock(&b->l);
 			goto String;
 		}
 		break;
 	case Qnotify:
 		if(f->cl->current && f->cl->current->notify){
+			b = f->cl->current;
 			memset(buf, 0, sizeof(buf));
-			for(np = f->cl->current->notify; np; np = np->next)
-				n = snprint(buf + n, sizeof(buf), "%!\n", np);
+			qlock(&b->l);
+			for(np = b->notify; np; np = np->next)
+				n = snprint(buf + n, sizeof(buf), "!%s\n", np->data);
+			qunlock(&b->l);
 			goto String;
 		}
 		break;
 	case Qtabs:
-		if(f->cl->current){
-			memset(buf, 0, sizeof(buf));
-			for(b = root->next; b; b = b->next){
-				n = snprint(buf + n, sizeof(buf), "%t\n", b);
-			}
-			goto String;
+		qlock(&root->l);
+		memset(buf, 0, sizeof(buf));
+		for(b = root->next; b; b = b->next){
+			n += snprint(buf + n, sizeof(buf) - n, "%t\n", b);
 		}
-		break;
+		qunlock(&root->l);
+		goto String;
 	}
 	if(!f->cl->current)
 		respond(r, "no buffer selected");
@@ -304,6 +315,7 @@
 void
 clwrite(Req *r)
 {
+	Buffer *b;
 	Clfid *f;
 	char *s, *t, path[1024];
 	int n;
@@ -319,10 +331,15 @@
 		if(strcmp(t, "buffer") == 0){
 			if(f->cl->fd)
 				close(f->cl->fd);
-			f->cl->current = bufferSearch(root, s);
-			if(!f->cl->current)
-				respond(r, "No buffer for selected");
-			f->cl->current->tag = r->tag;
+			b = bufferSearch(root, s);
+			if(!b){
+				respond(r, "No buffers available");
+				return;
+			}
+			qlock(&b->l);
+			f->cl->current = b;
+			b->tag = r->tag;
+			qunlock(&b->l);
 			memset(path, sizeof(path), 0);
 			snprint(path, sizeof(path), "%s/%s/%s", logdir, root->name, s);
 			f->cl->fd = open(path, OREAD);
@@ -341,7 +358,9 @@
 			respond(r, nil);
 		} else {
 			snprint(path, sizeof(path), "%s %s", t, s);
+			srvrelease(fs);
 			send(root->cmds, path);
+			srvacquire(fs);
 			respond(r, nil);
 		}
 		return;
@@ -366,9 +385,9 @@
 	Buffer *b;
 	flushtag = r->tag;
 	if(b = bufferSearchTag(root, flushtag)){
-		qlock(b);
+		qlock(&b->l);
 		rwakeup(&b->rz);
-		qunlock(b);
+		qunlock(&b->l);
 	}
 	respond(r, nil);
 }
@@ -379,6 +398,7 @@
 	Clfid *f;
 
 	if(f = fid->aux){
+		// TODO: Uncomment once we use this in aux/listen
 		//fid->aux = nil;
 		//if(f->cl)
 		//	freeclient(f->cl);
@@ -400,6 +420,5 @@
 void
 clend(Srv*)
 {
-	postnote(PNGROUP, getpid(), "shutdown");
 	exits(nil);
 }
--- a/fs.c
+++ b/fs.c
@@ -77,5 +77,5 @@
 
 	create(logdir, OREAD, DMDIR | 0755);
 	threadpostmountsrv(&svcfs, nil, mtpt, MCREATE);
-	exits(nil); 
+	exits(nil);
 }
--- a/service.c
+++ b/service.c
@@ -58,6 +58,7 @@
 	int	childpid;
 };
 
+static Srv *fs;
 Service service[64];
 int nservice;
 
@@ -75,8 +76,8 @@
 	if(i == nservice)
 		nservice++;
 	svc = &service[i];
-
 	svc->ref++;
+
 	// NOTE: If you're sending more commands than this before they are processed, up this number
 	// But also it might be time to question your design, because commands really should not be taking long
 	svc->cmds = chancreate(1024, 16);
@@ -155,7 +156,7 @@
 		respond(r, "invalid attach specifier");
 		return;
 	}
-	f = emalloc(sizeof(*f));
+	f = mallocz(sizeof(*f), 1);
 	f->level = Qsroot;
 	svcmkqid(&r->fid->qid, f->level, wfaux(f));
 	r->ofcall.qid = r->fid->qid;
@@ -224,7 +225,7 @@
 	o = oldfid->aux;
 	if(o == nil)
 		return "bad fid";
-	f = emalloc(sizeof(*f));
+	f = mallocz(sizeof(*f), 1);
 	memmove(f, o, sizeof(*f));
 	if(f->svc)
 		incref(f->svc);
@@ -299,11 +300,20 @@
 		memset(buf, 0, sizeof(buf));
 		// NOTE: This stays here so we always get a good ID back on the client from the initial read
 		if(!f->svc->isInitialized) {
+			while(nbrecv(f->svc->cmds, nil) == 1)
+				;
 			snprint(buf, sizeof(buf), "%d\n", SERVICEID(f->svc));
 			readstr(r, buf);
-		} else
+			respond(r, nil);
+		} else {
+			srvrelease(fs);
 			recv(f->svc->cmds, buf);
-		respond(r, nil);
+			if(strcmp(buf, "flush") == 0)
+				readstr(r, buf);
+			respond(r, nil);
+			srvacquire(fs);
+		}
+
 		return;
 
 	}
@@ -322,7 +332,7 @@
 	targ = strtok(nil, "\n");
 	if(strcmp(cmd, "feed")==0) {
 		if(b = bufferSearch(svc->base, targ)) {
-			qlock(b);
+			qlock(&b->l);
 			d = dirfstat(b->fd);
 			data[strlen(data)] = '\n';
 			pwrite(b->fd, data, strlen(data), d->length);
@@ -329,7 +339,7 @@
 			free(d);
 			if(rwakeupall(&b->rz) == 0)
 				b->unread++;
-			qunlock(b);
+			qunlock(&b->l);
 			return nil;
 		}
 		return "buffer not found";
@@ -364,6 +374,8 @@
 		return bufferPush(svc->base, targ);
 	else if(strcmp(cmd, "close")==0)
 		return bufferDrop(svc->base, targ);
+	else if(strcmp(cmd, "error")==0)
+		return targ;
 	else 
 		return "command not supported";
 }
@@ -380,7 +392,7 @@
 
 	if(f->level == Qctl){
 		n = r->ofcall.count = r->ifcall.count;
-		s = emalloc(n+1);
+		s = mallocz(n+1, 1);
 		memmove(s, r->ifcall.data, n);
 		while(n > 0 && strchr("\r\n", s[n-1]))
 			n--;
@@ -417,6 +429,14 @@
 void
 svcflush(Req *r)
 {
+	Buffer *b;
+	int i;
+	for(i = 0; i < nservice; i++)
+		if(service[i].ref > 0)
+			if((b = bufferSearchTag(service[i].base, r->tag))){
+				send(service[i].cmds, "flush");
+				break;
+			}
 	respond(r, nil);
 }
 
@@ -437,8 +457,9 @@
 }
 
 void
-svcstart(Srv*)
+svcstart(Srv* s)
 {
+	fs = s;
 	if(mtpt != nil)
 		unmount(nil, mtpt);
 }
@@ -446,6 +467,15 @@
 void
 svcend(Srv*)
 {
+	int i;
+
+	if(mtpt != nil)
+		unmount(nil, mtpt);
+	for(i = 0; i < nservice; i++)
+		if(service[i].ref){
+			print("Killing %d\n", service[i].childpid);
+			postnote(PNGROUP, service[i].childpid, "shutdown");
+		}
 	postnote(PNGROUP, getpid(), "shutdown");
 	threadexitsall(nil);
 }
--