summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2007-03-22 19:37:49 +0000
committerCharles.Forsyth <devnull@localhost>2007-03-22 19:37:49 +0000
commitfa7a3b619d233eb020ef07941dd3c9697474baaf (patch)
treea7c06768ef9fdac7edde3b185dce8f8f68e741a1
parent3f4f3401476e5bf8131b6a0f51f7f0e88e758d60 (diff)
20070322-1937 registry updates
-rw-r--r--appl/cmd/ndb/registry.b97
-rw-r--r--dis/ndb/registry.disbin8483 -> 9244 bytes
-rw-r--r--man/4/registry9
3 files changed, 95 insertions, 11 deletions
diff --git a/appl/cmd/ndb/registry.b b/appl/cmd/ndb/registry.b
index f720781f..7c6b8a88 100644
--- a/appl/cmd/ndb/registry.b
+++ b/appl/cmd/ndb/registry.b
@@ -82,8 +82,20 @@ Filter: adt {
remove: fn(f: self ref Filter);
};
-filters: list of ref Filter;
+Event: adt {
+ id: int; # fid reading from Qevents
+ vers: int; # last change seen
+ m: ref Tmsg.Read; # outstanding read request
+
+ new: fn(id: int): ref Event;
+ find: fn(id: int): ref Event;
+ remove: fn(e: self ref Event);
+ queue: fn(e: self ref Event, m: ref Tmsg.Read): string;
+ post: fn(vers: int);
+};
+filters: list of ref Filter;
+events: list of ref Event;
services := array[9] of ref Service;
nservices := 0;
@@ -105,11 +117,11 @@ init(nil: ref Draw->Context, args: list of string)
if(daytime == nil)
loaderr(Daytime->PATH);
styx = load Styx Styx->PATH;
- if (styx == nil)
+ if(styx == nil)
loaderr(Styx->PATH);
styx->init();
styxservers = load Styxservers Styxservers->PATH;
- if (styxservers == nil)
+ if(styxservers == nil)
loaderr(Styxservers->PATH);
styxservers->init(styx);
@@ -170,7 +182,7 @@ Serve:
error(sys->sprint("fatal read error: %s\n", m.error));
break Serve;
Open =>
- (fid, mode, d, e) := srv.canopen(m);
+ (fid, nil, nil, e) := srv.canopen(m);
if((err = e) != nil)
break;
if(fid.qtype & Sys->QTDIR)
@@ -219,6 +231,9 @@ open(m: ref Tmsg.Open, fid: ref Fid)
svc := Service.new(fid.uname);
svc.fid = fid.fid;
fid.open(m.mode, (big ((svc.id << Shift)|Qsvc), 0, Sys->QTFILE));
+ Qevent =>
+ Event.new(fid.fid);
+ fid.open(m.mode, (fid.path, 0, Sys->QTFILE));
* =>
fid.open(m.mode, (fid.path, 0, fid.qtype));
}
@@ -246,7 +261,16 @@ read(m: ref Tmsg.Read, fid: ref Fid): string
}
srv.reply(styxservers->readbytes(m, fid.data));
Qevent =>
- return "not implemented yet";
+ e := Event.find(fid.fid);
+ if(e.vers == rootvers)
+ return e.queue(m);
+ else{
+ s := sys->sprint("%8.8d\n", rootvers);
+ e.vers = rootvers;
+ m.offset = big 0;
+ srv.reply(styxservers->readstr(m, s));
+ return nil;
+ }
* =>
return Egreg;
}
@@ -267,7 +291,7 @@ write(m: ref Tmsg.Write, fid: ref Fid): string
return "bad syntax";
# first write names the service (possibly with attributes)
if(svc.name == nil){
- if((e := svcnameok(hd toks)) != nil)
+ if(svcnameok(hd toks) != nil)
return "bad service name";
svc.name = hd toks;
toks = tl toks;
@@ -278,6 +302,7 @@ write(m: ref Tmsg.Write, fid: ref Fid): string
svc.vers++;
for(; toks != nil; toks = tl tl toks)
svc.set(hd toks, hd tl toks);
+ Event.post(++rootvers);
Qfind =>
s := string m.data;
toks := str->unquoted(s);
@@ -310,10 +335,13 @@ clunk(fid: ref Fid)
case path & Mask {
Qsvc =>
svc := Service.find(path >> Shift);
- if(svc != nil && svc.fid == fid.fid && int svc.get("persist") == 0)
+ if(svc != nil && svc.fid == fid.fid && int svc.get("persist") == 0){
svc.remove();
+ Event.post(rootvers);
+ }
Qevent =>
- ; # remove queued events?
+ if((e := Event.find(fid.fid)) != nil)
+ e.remove();
Qfind =>
if((f := Filter.find(fid.fid)) != nil)
f.remove();
@@ -327,6 +355,7 @@ remove(fid: ref Fid): string
svc := Service.find(path >> Shift);
if(fid.uname == svc.owner){
svc.remove();
+ Event.post(rootvers);
return nil;
}
}
@@ -425,12 +454,12 @@ navigator(navops: chan of ref Navop)
d: array of int;
case path & Mask {
Qroot =>
- Nstatic: con 3;
+ Nstatic: con 4;
d = array[Nstatic + nservices] of int;
d[0] = Qnew;
d[1] = Qindex;
d[2] = Qfind;
-# d[3] = Qevent;
+ d[3] = Qevent;
for(i := 0; i < nservices; i++)
if(services[i].name != nil)
d[i + Nstatic] = (services[i].id<<Shift) | Qsvc;
@@ -439,7 +468,7 @@ navigator(navops: chan of ref Navop)
n.reply <-= (nil, Enotdir);
break;
}
- for (i := n.offset; i < len d; i++)
+ for(i := n.offset; i < len d; i++)
n.reply <-= dirgen(d[i]);
n.reply <-= (nil, nil);
}
@@ -621,6 +650,52 @@ Filter.match(f: self ref Filter, attrs: list of (string, string)): int
return i == len f.attrs;
}
+Event.new(id: int): ref Event
+{
+ e := ref Event(id, rootvers, nil);
+ events = e::events;
+ return e;
+}
+
+Event.find(id: int): ref Event
+{
+ for(l := events; l != nil; l = tl l)
+ if((hd l).id == id)
+ return hd l;
+ return nil;
+}
+
+Event.remove(e: self ref Event)
+{
+ rl: list of ref Event;
+ for(l := events; l != nil; l = tl l)
+ if((hd l).id != e.id)
+ rl = hd l :: rl;
+ events = rl;
+}
+
+Event.queue(e: self ref Event, m: ref Tmsg.Read): string
+{
+ if(e.m != nil)
+ return "concurrent read for event fid";
+ m.offset = big 0;
+ e.m = m;
+ return nil;
+}
+
+Event.post(vers: int)
+{
+ s := sys->sprint("%8.8d\n", vers);
+ for(l := events; l != nil; l = tl l){
+ e := hd l;
+ if(e.vers < vers && e.m != nil){
+ srv.reply(styxservers->readstr(e.m, s));
+ e.vers = vers;
+ e.m = nil;
+ }
+ }
+}
+
dbload(db: ref Db)
{
ptr: ref Attrdb->Dbptr;
diff --git a/dis/ndb/registry.dis b/dis/ndb/registry.dis
index f96234aa..dcf0fafa 100644
--- a/dis/ndb/registry.dis
+++ b/dis/ndb/registry.dis
Binary files differ
diff --git a/man/4/registry b/man/4/registry
index c952d3d6..a8b852d9 100644
--- a/man/4/registry
+++ b/man/4/registry
@@ -116,6 +116,15 @@ so that several processes can set different filters simultaneously.
(Note that after the write, the file offset must be set to zero using
.IR sys-seek (2)
before reading.)
+.TP
+.B event
+A read-only text file that can be used to detect when changes are made to the registry.
+Reading from it blocks until a change is made. At that point, the read completes and returns a
+string with a newline terminated decimal version number representing
+the number of changes made to the registry, which matches
+.B Qid.vers
+for the registry directory.
+Multiple changes are coalesced into one report.
.PP
A service file created by
.B new