ref: 05d9123a707dec0eaa0ab079b94e69cdb750c6db
dir: /appl/alphabet/grid/remote.b/
implement Remote, Gridmodule;
include "sys.m";
sys: Sys;
include "draw.m";
include "sh.m";
include "alphabet/reports.m";
reports: Reports;
report, quit, Report: import reports;
include "alphabet/endpoints.m";
endpoints: Endpoints;
Endpoint: import endpoints;
include "alphabet/grid.m";
grid: Grid;
Value: import grid;
Remote: module {};
types(): string
{
return "ef-as";
}
init()
{
sys = load Sys Sys->PATH;
reports = checkload(load Reports Reports->PATH, Reports->PATH);
endpoints = checkload(load Endpoints Endpoints->PATH, Endpoints->PATH);
endpoints->init();
grid = checkload(load Grid Grid->PATH, Grid->PATH);
grid->init();
}
run(nil: chan of string, r: ref Reports->Report,
opts: list of (int, list of ref Grid->Value), args: list of ref Grid->Value): ref Grid->Value
{
addr := "local";
if(opts != nil)
addr = (hd (hd opts).t1).s().i;
f := (hd args).f().i;
spawn remoteproc(ec := chan of Endpoint, f, addr, r.start("remote"));
return ref Value.Ve(ec);
}
Noendpoint: con Endpoint(nil, nil, nil);
remoteproc(ec: chan of Endpoint, f: chan of ref Sys->FD, addr: string, errorc: chan of string)
{
(fd1, ep) := endpoints->create(addr);
if(fd1 == nil){
report(errorc, "error: remote: cannot create endpoint at "+addr+": "+ep.about);
ec <-= Noendpoint;
<-f;
f <-= nil;
quit(errorc);
}
fd0 := <-f;
if(fd0 != nil)
ep.about = sys->sprint("local(%#q)", sys->fd2path(fd0));
else
ep.about = "local(pipe)";
ec <-= ep;
f <-= fd1;
quit(errorc);
}
# sys->pipe(p := array[2] of ref Sys->FD);
# f <-= p[1];
# p[1] = nil;
# buf := array[Sys->ATOMICIO] of byte;
# while((n := sys->read(p[0], buf, len buf)) > 0){
# if(sys->write(fd, buf, n) == -1){
# report(errorc, sys->sprint("write error: %r"));
# break;
# }
# }exception{
# "write on closed pipe" =>
# report(errorc, "got write on closed pipe");
# }
# sys->write(fd, array[0] of byte, 0);
# quit(errorc);
#}
checkload[T](m: T, path: string): T
{
if(m != nil)
return m;
raise sys->sprint("fail:cannot load %s: %r", path);
}