ref: 081ed9fecdb571030ee202e8014e8de58acca206
parent: 90a6fc91052ebe27f3e1fa0d96d0876c00b48ff3
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Sep 17 14:03:49 EDT 2023
mq: fix some bugs and crashes
--- a/mq.c
+++ b/mq.c
@@ -11,8 +11,14 @@
enum {
Qroot,
+ Maxqid,
};
+enum {
+ Cclose,
+ Ctrunc,
+};
+
struct Aux {
Mq *q;
int id;
@@ -35,8 +41,9 @@
};
struct Mq {
+ Ref;
Qid qid;
- int count;
+ int moribund;
usize logsz;
Msg *loghd;
Msg *logtl;
@@ -55,12 +62,16 @@
Mq **queues;
int nqueues;
vlong maxlog = -1;
-vlong queueid = Qroot + 1;
+vlong queueid = Maxqid;
char Ebaduse[] = "invalid use of fd";
char Einuse[] = "fid in use";
char Eexist[] = "file already exists";
-char Enoexist[] = "file does not exists";
+char Enoexist[] = "file does not exist";
+char Eintr[] = "interrupted";
+char Enotdir[] = "not a directory";
+char Ebadcmd[] = "unknown command";
+char Enomem[] = "out of memory";
void *
emalloc(ulong n)
@@ -96,21 +107,7 @@
return s;
}
-Msg*
-msgref(Msg *m)
-{
- incref(m);
- return m;
-}
-
void
-msgunref(Msg *m)
-{
- if(decref(m) == 0)
- free(m);
-}
-
-void
trimlog(Mq *q)
{
Msg *m;
@@ -121,7 +118,8 @@
m = q->loghd;
q->loghd = m->next;
q->logsz -= m->count;
- msgunref(m);
+ if(decref(m) == 0)
+ free(m);
}
if(q->loghd == nil)
q->logtl = nil;
@@ -151,7 +149,7 @@
rd->hd = q->loghd;
rd->tl = q->logtl;
for(m = q->loghd; m != nil; m = m->next)
- msgref(m);
+ incref(m);
return rd->id;
}
@@ -214,12 +212,12 @@
if(strcmp(name, "..") == 0){
*qid = f->qid;
return nil;
+ }else if((q = lookup(name)) != nil){
+ f->qid = q->qid;
+ *qid = f->qid;
+ return nil;
}
- if((q = lookup(name)) == nil)
- return Enoexist;
- f->qid = q->qid;
- *qid = f->qid;
- return nil;
+ return Enoexist;
default:
if(strcmp(name, "..") == 0){
f->qid = (Qid){Qroot, 0, QTDIR};
@@ -226,7 +224,7 @@
*qid = f->qid;
return nil;
}
- return "not a dir";
+ return Enotdir;
}
}
@@ -267,8 +265,24 @@
void
mqremove(Req *r)
{
- USED(r);
- abort();
+ vlong path;
+ int i, o;
+
+ path = r->fid->qid.path;
+ if(path == Qroot){
+ respond(r, Ebaduse);
+ return;
+ }
+ o = 0;
+ for(i = 0; i < nqueues; i++){
+ if(queues[i]->qid.path == path){
+ queues[i]->moribund = 1;
+ continue;
+ }
+ queues[o++] = queues[i];
+ }
+ nqueues--;
+ respond(r, nil);
}
void
@@ -311,13 +325,14 @@
if(q->rd[i].tl != nil)
q->rd[i].tl->next = m;
q->rd[i].tl = m;
- msgref(m);
+ incref(m);
}
if(q->loghd == nil)
q->loghd = m;
if(q->logtl != nil)
q->logtl->next = m;
- q->logtl = msgref(m);
+ incref(m);
+ q->logtl = m;
q->logsz += m->count;
q->logtl = m;
@@ -369,7 +384,8 @@
rd->hd = m->next;
if(rd->hd == nil)
rd->tl = nil;
- msgunref(m);
+ if(decref(m) == 0)
+ free(m);
}
}
@@ -419,7 +435,8 @@
p = r->fid->qid.path;
a = emalloc(sizeof(Aux));
if(p != Qroot){
- a->q = queues[p-1];
+ incref(queues[p-Maxqid]);
+ a->q = queues[p-Maxqid];
if(m == OREAD || m == ORDWR || m == OMASK)
a->id = subscribe(a->q);
r->fid->aux = a;
@@ -497,4 +514,5 @@
}ARGEND;
postmountsrv(&mq, srvname, mntpt, MCREATE|MREPL);
+ exits(nil);
}