ref: 51489f979a4b1a0df534f9b8d461314c8ad86483
parent: ee71fd2728c3201348fdc0ffbd8720d3597f2ac5
author: B. Wilson <x@wilsonb.com>
date: Thu Jun 19 10:45:49 EDT 2025
Allow async io
--- a/ridefs.c
+++ b/ridefs.c
@@ -12,14 +12,15 @@
struct Client {
Ref;
+ QLock;
char *addr;
ulong umask;
/* internal use */
+ int ridone; /* ride initialized */
Req *req; /* i/o req */
int pid; /* pid */
- int oio; /* io opened */
char *r; /* response buffer */
int rn; /* length */
int roff; /* offset */
@@ -465,7 +466,7 @@
static void
fsopen(Req *r){
- int e, pid;
+ int pid;
char *err;
Rfid *f;
Client *c;
@@ -472,6 +473,7 @@
f = r->fid->aux;
c = clientref(f->client);
+ err = nil;
switch(f->kind){
case Qclone:
if((f->client = mkclient()) == -1){
@@ -487,21 +489,25 @@
respond(r, nil);
break;
case Qio:
- if(e = c->oio)
- respond(r, "client in use");
- else if(e = (nil == c->addr))
+ if(nil == c->addr){
respond(r, "no server set");
- if(e)
return;
+ }
switch(pid = rfork(RFPROC|RFNOWAIT|RFMEM)){
case 0:
+ qlock(c);
+ if(c->ridone)
+ goto end;
+
err = rideinit(f->client);
- if(err == nil)
- c->oio = 1;
- respond(r, err);
c->pid = 0;
c->req = nil;
+ c->ridone = 1;
+
+ end:
+ respond(r, err);
+ qunlock(c);
exits(nil);
case -1:
respond(r, "failed to init ride");
@@ -537,8 +543,9 @@
case Qio:
switch(pid = rfork(RFPROC|RFNOWAIT|RFMEM)){
case 0:
- off = r->ifcall.offset - c->roff;
+ qlock(c);
+ off = r->ifcall.offset - c->roff;
if(c->rn < 0){
c->rn = readmsg(c->fd, c->r, bufsz);
c->roff = r->ifcall.offset;
@@ -558,6 +565,8 @@
respond(r, err);
c->pid = 0;
c->req = nil;
+
+ qunlock(c);
exits(nil);
case -1:
err = "failed to fork read";
@@ -602,11 +611,14 @@
case Qio:
switch(pid = rfork(RFPROC|RFNOWAIT|RFMEM)){
case 0:
+ qlock(c);
r->ofcall.count = writemsg(c->fd, d, n);
respond(r, nil);
c->pid = 0;
c->req = nil;
+
+ qunlock(c);
exits(nil);
case -1:
err = "failed to fork write";
@@ -638,6 +650,7 @@
respond(c->req, "interrupted");
c->pid = 0;
c->req = nil;
+ qunlock(c);
}
respond(r, nil);
--- a/test
+++ b/test
@@ -50,6 +50,7 @@
ls -d $n >[2]/dev/null &&
fail 'Did not clean up closed client'
+
<clone {
cd `{read}
@@ -71,4 +72,21 @@
fail 'Did not receive response'
}
cd ..
+}
+
+<clone {
+ cd `{read}
+ echo 'connect 192.168.11.17' >ctl
+
+ <>io >[1=0] {
+ msg='["Execute",{"text":"⍳5\n","trace":0}]'
+ echo -n $msg || fail 'Could not send message'
+ } & spid=$apid
+
+ <>io >[1=0] {
+ cat >/dev/null || fail 'Could not receive message'
+ } & rpid=$apid
+
+ wait $spid || fail $status
+ wait $rpid || fail $status
}
--
⑨