ref: dba0c3fbd5463e44d57c5c75f6fa285b91770474
parent: 4401e746299f6c7c0665cefb557c455d4edb7d9f
author: B. Wilson <x@wilsonb.com>
date: Mon Jun 23 11:57:36 EDT 2025
Allow simultaneous reading and writing
--- a/ridefs.c
+++ b/ridefs.c
@@ -12,20 +12,19 @@
struct Client {
Ref;
- QLock;
char *addr;
- /* internal use */
- Req *req; /* i/o req */
- int pid; /* pid */
- char *r; /* response buffer */
- int rn; /* length */
- int roff; /* offset */
- char *qinfo;
- char *qctl;
- int fd; /* data */
- int cfd; /* ctl */
+ /* tcp i/o */
+ QLock rl, wl;
+ Req *rreq, *wreq;
+ int rpid, wpid;
+ int fd, cfd;
+
+ /* buffers */
+ char *qinfo, *qctl;
+ char *r; /* response */
+ int rn, roff;
};
enum {
@@ -457,25 +456,25 @@
return;
}
- qlock(c);
+ qlock(&c->wl);
incref(&r->ref);
- c->req = r;
- switch(c->pid = rfork(RFPROC|RFNOWAIT|RFMEM)){
+ c->wreq = r;
+ switch(c->wpid = rfork(RFPROC|RFNOWAIT|RFMEM)){
case 0:
if(!c->fd)
err = rideinit(c->addr, &c->fd, &c->cfd, &c->qinfo);
- c->pid = 0;
- c->req = nil;
+ c->wpid = 0;
+ c->wreq = nil;
decref(&r->ref);
respond(r, err);
- qunlock(c);
+ qunlock(&c->wl);
exits(nil);
case -1:
respond(r, "failed to init ride");
- c->pid = 0;
- c->req = nil;
+ c->wpid = 0;
+ c->wreq = nil;
decref(&r->ref);
- qunlock(c);
+ qunlock(&c->wl);
break;
default:
return;
@@ -504,14 +503,15 @@
case Qctl: buf = estrdup(c->qctl); break;
case Qinfo: buf = estrdup(c->qinfo); break;
case Qdata:
- qlock(c);
+ qlock(&c->rl);
incref(&r->ref);
- c->req = r;
- switch(c->pid = rfork(RFPROC|RFNOWAIT|RFMEM)){
+ c->rreq = r;
+ switch(c->rpid = rfork(RFPROC|RFNOWAIT|RFMEM)){
case 0:
off = r->ifcall.offset - c->roff;
if(c->rn < 0){
free(c->r);
+ c->r = nil;
c->rn = readmsg(c->fd, &c->r);
c->roff = r->ifcall.offset;
off = 0;
@@ -527,18 +527,18 @@
r->ofcall.count = n;
}
- c->pid = 0;
- c->req = nil;
+ c->rpid = 0;
+ c->rreq = nil;
decref(&r->ref);
respond(r, err);
- qunlock(c);
+ qunlock(&c->rl);
exits(nil);
case -1:
err = "failed to fork read";
- c->pid = 0;
- c->req = nil;
+ c->rpid = 0;
+ c->rreq = nil;
decref(&r->ref);
- qunlock(c);
+ qunlock(&c->rl);
break;
default:
return;
@@ -575,26 +575,25 @@
r->ofcall.count = writeqctl(d, n, f->client);
break;
case Qdata:
- qlock(c);
+ qlock(&c->wl);
incref(&r->ref);
- c->req = r;
- switch(c->pid = rfork(RFPROC|RFNOWAIT|RFMEM)){
+ c->wreq = r;
+ switch(c->wpid = rfork(RFPROC|RFNOWAIT|RFMEM)){
case 0:
r->ofcall.count = writemsg(c->fd, d, n);
- c->pid = 0;
- c->req = nil;
+ c->wpid = 0;
+ c->wreq = nil;
decref(&r->ref);
respond(r, nil);
-
- qunlock(c);
+ qunlock(&c->wl);
exits(nil);
case -1:
err = "failed to fork write";
- c->pid = 0;
- c->req = nil;
+ c->wpid = 0;
+ c->wreq = nil;
decref(&r->ref);
- qunlock(c);
+ qunlock(&c->wl);
break;
default:
return;
@@ -616,13 +615,19 @@
if(o = r->oldreq)
if(f = o->fid->aux)
if(c = clientref(f->client))
- if(c->req){
- postnote(PNPROC, c->pid, "interrupt");
- respond(c->req, "interrupted");
- c->pid = 0;
- c->req = nil;
- decref(&c->req->ref);
- qunlock(c);
+ if(o == c->rreq){
+ postnote(PNPROC, c->rpid, "interrupt");
+ respond(c->rreq, "interrupted");
+ c->rpid = 0;
+ decref(&c->rreq->ref);
+ qunlock(&c->rl);
+ } else if (o == c->wreq){
+ postnote(PNPROC, c->wpid, "interrupt");
+ respond(c->wreq, "interrupted");
+ c->wpid = 0;
+ c->wreq = nil;
+ decref(&c->wreq->ref);
+ qunlock(&c->wl);
}
respond(r, nil);
--
⑨