~aleteoryx/9c

00a73e9c88d163cca06c9744092a4892cb66e2eb — glenda a month ago e7cc02f
deletions, bugfixes
2 files changed, 143 insertions(+), 74 deletions(-)

M mkfile
M queuesrv.c
M mkfile => mkfile +1 -0
@@ 24,6 24,7 @@ clean:V:
qclean:V:
	rm -f /srv/queue
	unmount /n || echo -n
	slay queuesrv | rc
qdev:V:
	mk queuesrv
	queuesrv -D || echo -n

M queuesrv.c => queuesrv.c +142 -74
@@ 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);