@@ 14,33 14,32 @@ enum {
typedef struct {
int state;
usize length;
- Fid* members[];
+ Fid *members[];
} Queue;
// typeof(fid->aux)
typedef struct {
usize length;
- Req* members[];
+ Req *members[];
} Inflight;
typedef struct {
- char* name;
- File* file;
+ char *name;
+ File *file;
} QueueDesc;
Srv s;
int stdio;
-char* service;
+char *service;
-// FIXME: dynamically allocate queues
int maxname;
-int maxqueues;
-QueueDesc* queues;
-char* ctlbuf;
+int queueslen;
+QueueDesc *queues;
+char *ctlbuf;
void
usage(void)
{
- fprint(2,"usage: queuefs [ -Ds ] [ -n maxname ] [ -q maxqueues ] [ service ]\n");
+ fprint(2,"usage: queuefs [ -Ds ] [ -n maxname ] [ service ]\n");
exits("usage");
}
@@ 52,7 51,7 @@ setuptree(void)
}
void
-main(int argc, char* argv[])
+main(int argc, char *argv[])
{
ARGBEGIN{
case 's':
@@ 64,12 63,9 @@ main(int argc, char* argv[])
case 'n':
maxname = atoi(EARGF(usage()));
break;
- case 'q':
- maxqueues = atoi(EARGF(usage()));
- break;
default:
usage();
- } ARGEND
+ }ARGEND
switch(argc){
case 0:
@@ 84,15 80,13 @@ main(int argc, char* argv[])
if(maxname <= 0)
maxname = 64;
- if(maxqueues <= 0)
- maxqueues = 256;
fmtinstall('D', dirfmt);
fmtinstall('M', dirmodefmt);
- #pragma varargck type "F" Fcall*
+ #pragma varargck type "F" Fcall *
fmtinstall('F', fcallfmt);
- queues = calloc(maxqueues, sizeof(QueueDesc));
+ queueslen = 0;
setuptree();
@@ 100,43 94,49 @@ main(int argc, char* argv[])
s.infd = 0;
s.outfd = 1;
srv(&s);
- }
- else{
+ }else{
print("posting service %s\n", service);
if(postsrv(&s, service) < 0)
sysfatal("couldn't postsrv: %r");
}
}
-char*
-newqueue(char* name)
+void
+ctlclear(void)
+{
+ if(ctlbuf != nil){
+ free(ctlbuf);
+ ctlbuf = nil;
+ }
+}
+char *
+newqueue(char *name)
{
int i;
- Queue* queue;
+ Queue *queue;
- for(i = 0; i < maxqueues && queues[i].file != nil; i++);
- if(i == maxqueues)
- return "new: too many queues";
+ for(i = 0; i < queueslen && queues[i].file != nil; i++);
+ print("pre-realloc %d\n", queueslen);
+ if(i == queueslen)
+ queues = realloc(queues, (++queueslen) * sizeof(QueueDesc));
+ print("post-realloc %d\n", queueslen);
- queue = calloc(1, sizeof(Queue) + sizeof(Fid*));
+ queue = calloc(1, sizeof(Queue) + sizeof(Fid *));
queue->length = 1;
queues[i].file = createfile(s.tree->root, name, "none", 0444, queue);
queues[i].name = name;
- if(ctlbuf != nil){
- free(ctlbuf);
- ctlbuf = nil;
- }
+ ctlclear();
return nil;
}
uint
-newmember(Fid* fid)
+newmember(Fid *fid)
{
- File* file;
- Queue* queue;
- Inflight* inflight;
+ File *file;
+ Queue *queue;
+ Inflight *inflight;
uint i;
file = fid->file;
@@ 147,29 147,52 @@ newmember(Fid* fid)
// reallocate queue if necessary
if(i == queue->length){
queue->length *= 2;
- queue = realloc(queue, sizeof(Queue) + sizeof(Fid*) * queue->length);
+ queue = realloc(queue, sizeof(Queue) + sizeof(Fid *) * queue->length);
file->aux = queue;
}
queue->members[i] = fid;
// setup read queue
- inflight = calloc(1, sizeof(Inflight) + sizeof(Req*));
+ inflight = calloc(1, sizeof(Inflight) + sizeof(Req *));
inflight->length = 1;
fid->aux = inflight;
- // invalidate ctlbuf
- if(ctlbuf != nil)
- free(ctlbuf);
- ctlbuf = nil;
+ ctlclear();
// return spot in queue
return i;
}
+char *
+delqueue(QueueDesc* qd)
+{
+ uint i;
+ File *file;
+ Queue *queue;
+
+ file = qd->file;
+ queue = file->aux;
+
+ for(i = 0; i < queue->length && queue->members[i] == nil; i++);
+ if(i == queue->length){
+ removefile(file);
+ free(queue);
+ }else
+ queue->state = QDeleted;
+
+ free(qd->name);
+ qd->file = nil;
+ qd->name = nil;
+
+ ctlclear();
+
+ return nil;
+}
+
void
-registerreq(Req* r)
+registerreq(Req *r)
{
- Inflight* inflight;
+ Inflight *inflight;
uint i;
inflight = r->fid->aux;
@@ 177,7 200,7 @@ registerreq(Req* r)
for(i = 0; i < inflight->length && inflight->members[i] != nil; i++);
if(i == inflight->length){
inflight->length *= 2;
- inflight = realloc(inflight, sizeof(Inflight) + sizeof(Req*) * inflight->length);
+ inflight = realloc(inflight, sizeof(Inflight) + sizeof(Req *) * inflight->length);
r->fid->aux = inflight;
}
@@ 188,16 211,23 @@ registerreq(Req* r)
void
ctlregen(void)
{
- char* p;
+ char *p;
usize blen;
uint nmems, i;
- QueueDesc* qd;
- Queue* queue;
+ QueueDesc *qd;
+ Queue *queue;
- blen = (maxname + 20) * maxqueues + 10;
- p = ctlbuf = calloc(blen, 1);
+ blen = 10;
+ for(i = 0; i < queueslen; i++){
+ qd = queues + i;
+ if(qd->file != nil && qd->name != nil)
+ blen += strlen(qd->name) + 20;
+ }
+
+ p = ctlbuf = malloc(blen);
+ p[0] = 0;
- for(i = 0; i < maxqueues; i++){
+ for(i = 0; i < queueslen; i++){
qd = queues + i;
if(qd->file == nil)
continue;
@@ 207,11 237,11 @@ ctlregen(void)
nmems < queue->length && queue->members[nmems] != nil;
nmems++);
- p += sprint(p, "%s %d\n", qd->name, nmems);
+ p += sprint(p, "%s\t%d\n", qd->name, nmems);
}
}
void
-ctlread(Req* r)
+ctlread(Req *r)
{
if(ctlbuf == nil)
ctlregen();
@@ 221,11 251,12 @@ ctlread(Req* r)
}
// FIXME: errors if command split between multiple writes
void
-ctlwrite(Req* r)
+ctlwrite(Req *r)
{
- char *s, *p;
+ char *s, *p, *resp;
int i;
+ //FIXME: break parsing logic out into a function
if(r->ifcall.count > 5 && strncmp(r->ifcall.data, "new ", 4) == 0){
p = s = malloc(r->ifcall.count - 3);
strncpy(s, r->ifcall.data + 4, r->ifcall.count - 4);
@@ 240,25 271,54 @@ ctlwrite(Req* r)
return;
}
- for(i = 0; i < maxqueues; i++){
+ for(i = 0; i < queueslen; i++){
if(queues[i].file == nil)
continue;
if(strcmp(s, queues[i].name) == 0)
break;
}
- // FIXME: might leak s here
- if(i == maxqueues)
- respond(r, newqueue(s));
- else
+ if(i == queueslen){
+ resp = newqueue(s);
+ respond(r, resp);
+ if(resp != nil)
+ free(s);
+ }else
respond(r, nil);
- }
- else
+ }else if(r->ifcall.count > 8 && strncmp(r->ifcall.data, "delete ", 7) == 0){
+ p = s = malloc(r->ifcall.count - 6);
+ strncpy(s, r->ifcall.data + 7, r->ifcall.count - 7);
+ do{
+ if(isspace(*p))
+ *p = '\0';
+ }
+ while(*p++ != '\0');
+
+ if(strlen(s) == 0){
+ respond(r, "delete: missing argument");
+ return;
+ }
+
+ print("trying to delete %s\n", s);
+
+ for(i = 0; i < queueslen; i++){
+ if(queues[i].file == nil)
+ continue;
+ if(strcmp(s, queues[i].name) == 0)
+ break;
+ }
+
+ if(i != queueslen){
+ respond(r, delqueue(&(queues[i])));
+ free(s);
+ }else
+ respond(r, "queue does not exist");
+ }else
respond(r, "bad command");
}
void
-queueread(Req* r)
+queueread(Req *r)
{
uint spot;
char buf[32];
@@ 273,13 333,13 @@ queueread(Req* r)
registerreq(r);
}
void
-queuewrite(Req* r)
+queuewrite(Req *r)
{
respond(r, "queues are not writable");
}
void
-srvread(Req* r)
+srvread(Req *r)
{
if(r->fid->file->aux == nil)
ctlread(r);
@@ 288,7 348,7 @@ srvread(Req* r)
}
void
-srvwrite(Req* r)
+srvwrite(Req *r)
{
if(r->fid->file->aux == nil)
ctlwrite(r);
@@ 297,13 357,11 @@ srvwrite(Req* r)
}
void
-srvdestroyfid(Fid* fid)
+srvdestroyfid(Fid *fid)
{
- print("dfid %p\n", fid);
-
- Queue* queue;
- Inflight* inflight;
- Req* r;
+ Queue *queue;
+ Inflight *inflight;
+ Req *r;
uint i, j;
char buf[32];
@@ 311,9 369,10 @@ srvdestroyfid(Fid* fid)
return;
queue = fid->file->aux;
- for(i = 0; i < queue->length && queue->members[i] != fid && queue->members[i] != nil; i++);
+ for(i = 0; i < queue->length && queue->members[i] != fid && queue->members[i] != nil; i++);
if(i == queue->length || queue->members[i] == nil)
sysfatal("bugcheck: fid->aux != nil but fid not in queue->members");
+ free(fid->aux);
for(; (i + 1) < queue->length && queue->members[i + 1] != nil; i++){
queue->members[i] = queue->members[i + 1];
@@ 328,14 387,23 @@ srvdestroyfid(Fid* fid)
r->ifcall.offset = 0;
readstr(r, buf);
respond(r, nil);
+
+ inflight->members[j] = nil;
}
}
queue->members[i] = nil;
+
+ if(i == 0 && queue->state == QDeleted){
+ removefile(fid->file);
+ free(queue);
+ }
+
+ ctlclear();
}
void
-srvflush(Req* r)
+srvflush(Req *r)
{
if(r->fid != nil)
srvdestroyfid(r->fid);