void makeShell(VMHost *v,FILE *input, FILE *output,Receptor **irp,Receptor **orp,Stream **isp,Stream **osp) { // define and then create the shell receptor Symbol shell = _d_define_receptor(v->r->sem,"shell",__r_make_definitions(),DEV_COMPOSITORY_CONTEXT); Receptor *r = _r_new(v->sem,shell); Xaddr shellx = _v_new_receptor(v,v->r,shell,r); _v_activate(v,shellx); // create stdin/out receptors Stream *output_stream = *osp = _st_new_unix_stream(output,0); Stream *input_stream = *isp = _st_new_unix_stream(input,1); Receptor *i_r = *irp = _r_makeStreamEdgeReceptor(v->sem); _r_addReader(i_r,input_stream,r->addr,DEFAULT_ASPECT,parse_line,LINE,false); Xaddr ix = _v_new_receptor(v,v->r,STREAM_EDGE,i_r); _v_activate(v,ix); Receptor *o_r = *orp = _r_makeStreamEdgeReceptor(v->sem); _r_addWriter(o_r,output_stream,DEFAULT_ASPECT); Xaddr ox = _v_new_receptor(v,v->r,STREAM_EDGE,o_r); _v_activate(v,ox); // set up shell to express the line parsing protocol when it receives LINES from the stream reader Protocol clp; __sem_get_by_label(v->sem,"PARSE_COMMAND_FROM_LINE",&clp,DEV_COMPOSITORY_CONTEXT); T *bindings = _t_new_root(PROTOCOL_BINDINGS); T *res = _t_newr(bindings,RESOLUTION); T *w = _t_newr(res,WHICH_RECEPTOR); _t_news(w,ROLE,LINE_SENDER); __r_make_addr(w,ACTUAL_RECEPTOR,i_r->addr); res = _t_newr(bindings,RESOLUTION); w = _t_newr(res,WHICH_RECEPTOR); _t_news(w,ROLE,COMMAND_RECEIVER); __r_make_addr(w,ACTUAL_RECEPTOR,r->addr); res = _t_newr(bindings,RESOLUTION); w = _t_newr(res,WHICH_SYMBOL); _t_news(w,USAGE,COMMAND_TYPE); _t_news(w,ACTUAL_SYMBOL,SHELL_COMMAND); _o_express_role(r,clp,COMMAND_RECEIVER,DEFAULT_ASPECT,bindings); _t_free(bindings); // set up shell to use the CLOCK TELL_TIME protocol for the time command Protocol time; __sem_get_by_label(v->sem,"time",&time,CLOCK_CONTEXT); T *code = _t_new_root(INITIATE_PROTOCOL); _t_news(code,PNAME,time); _t_news(code,WHICH_INTERACTION,tell_time); bindings = _t_newr(code,PROTOCOL_BINDINGS); res = _t_newr(bindings,RESOLUTION); w = _t_newr(res,WHICH_RECEPTOR); _t_news(w,ROLE,TIME_HEARER); __r_make_addr(w,ACTUAL_RECEPTOR,r->addr); res = _t_newr(bindings,RESOLUTION); w = _t_newr(res,WHICH_RECEPTOR); _t_news(w,ROLE,TIME_TELLER); ReceptorAddress clock_addr = {3}; // @todo bogus!!! fix getting clock address somehow __r_make_addr(w,ACTUAL_RECEPTOR,clock_addr); res = _t_newr(bindings,RESOLUTION); w = _t_newr(res,WHICH_PROCESS); _t_news(w,GOAL,RESPONSE_HANDLER); addCommand(r,o_r->addr,"time","get time",code,w); // (expect (on flux SHELL_COMMAND:receptor) action (send std_out (convert_to_lines (send vmhost receptor-list)))) code = _t_newi(0,MAGIC,MagicReceptors); addCommand(r,o_r->addr,"receptors","get receptor list",code,NULL); // (expect (on flux SHELL_COMMAND:receptor) action (send std_out (convert_to_lines (send vmhost shutdown))) code = _t_newi(0,MAGIC,MagicQuit); addCommand(r,o_r->addr,"quit","shut down the vmhost",code,NULL); // (expect (on flux SHELL_COMMAND:debug) action (send std_out (convert_to_lines (magic toggle debug))) code = _t_newi(0,MAGIC,MagicDebug); addCommand(r,o_r->addr,"debug","toggle debug mode",code,NULL); }
/** * create all the built in receptors that exist in all VMhosts */ void _v_instantiate_builtins(VMHost *v) { Receptor *r = _r_makeClockReceptor(v->sem); Xaddr clock = _v_new_receptor(v,v->r,CLOCK_RECEPTOR,r); _v_activate(v,clock); }
Receptor *makeGroup(VMHost *v,char *label) { SemTable *sem = v->r->sem; Symbol group = _d_define_receptor(sem,label,__r_make_definitions(),DEV_COMPOSITORY_CONTEXT); Receptor *r = _r_new(sem,group); Xaddr groupx = _v_new_receptor(v,v->r,group,r); _v_activate(v,groupx); //debug_enable(D_PROTOCOL); _o_express_role(r,group1,GROUP,DEFAULT_ASPECT,NULL); debug_disable(D_PROTOCOL); /* Symbol channel_addr = _r_define_symbol(r,RECEPTOR_ADDRESS,"channel"); */ /* Symbol member = _r_define_symbol(r,RECEPTOR_ADDRESS,"member"); */ /* Symbol group_addr = _r_define_symbol(r,RECEPTOR_ADDRESS,"group"); */ /* Symbol proxy_addr = _r_define_symbol(r,RECEPTOR_ADDRESS,"proxy"); */ /* // Symbol create = _r_define_symbol(r,NULL_STRUCTURE,"create"); */ /* Symbol join = _r_define_symbol(r,NULL_STRUCTURE,"talking join"); */ /* Symbol read = _r_define_symbol(r,NULL_STRUCTURE,"talking read"); */ /* Symbol post_id = _r_define_symbol(r,INTEGER,"post_id"); */ /* T *e_join,*e_sub,*e_crud,*e_act; */ /* T *g_d = _o_make_protocol_def(sem,"talking", */ /* ROLE,channel_addr, */ /* ROLE,group_addr, */ /* ROLE,proxy_addr, */ /* ROLE,member, */ /* CONVERSATION,"membership", */ /* group_addr,member,e_join, */ /* CONVERSATION,"subscribe", */ /* channel_addr,proxy_addr,e_sub, */ /* CONVERSATION,"crud", */ /* proxy_addr,member,e_crud, */ /* CONVERSATION,"act", */ /* member,proxy_addr,e_act, */ /* NULL_SYMBOL); */ /* _r_define_protocol(r,) */ /* T *proc = _t_new_root(IF); */ /* T *t = _t_newr(proc,SAY); */ /* __r_make_addr(t,TO_ADDRESS,C_authChanId); // @todo find the right address value to use by convention for the auth channel */ /* _t_news(t,ASPECT_IDENT,DEFAULT_ASPECT); // @todo, generalize to allow groups on different aspects */ /* _t_news(t,CARRIER,talking); */ /* T *w = _t_newr(t,read); */ /* int pt[] = {SignalEnvelopeIdx,EnvelopeFromIdx,TREE_PATH_TERMINATOR}; // the senders address */ /* _t_new(w,SIGNAL_REF,pt,sizeof(int)*4); */ /* t = _t_newr(proc,RESPOND); */ /* _t_news(t,RESPONSE_CARRIER,talking); */ // T *e = __r_build_expectation(join,join_stx,join_process,0,0,NULL,NULL); /* group { */ /* role { */ /* channel; */ /* proxy; */ /* group; */ /* } */ /* conversations { */ /* membership { */ /* group expects join from ! { */ /* if (read auth_channel for !) { */ /* create token; */ /* send to proxy for ! token; */ /* respond with token; */ /* } */ /* else { */ /* respond with err; */ /* } */ /* } */ /* } */ /* subscribe { */ /* channel expects sub from proxy { */ /* }*/ /* } */ /* crud post from proxy to channel (some channels have side-effects); */ /* act from ! to proxy; */ /* } */ /* } */ return r; }
/** * bootstrap the ceptr system * * starts up the vmhost and wakes up receptors that should be running in it. * * @TODO check the compository to verify our version of the vmhost * */ void _a_boot(char *dir_path) { // check if the storage directory exists struct stat st = {0}; if (stat(dir_path, &st) == -1) { // if no directory we are firing up an initial instance, so // create directory mkdir(dir_path,0700); // instantiate a VMHost object G_vm = _v_new(); // create the basic receptors that all VMHosts have _v_instantiate_builtins(G_vm); } else { char fn[1000]; void *buffer; // unserialize the semtable base tree SemTable *sem = _sem_new(); T *t = __a_unserializet(dir_path,SEM_FN); sem->stores[0].definitions = t; // restore definitions to the correct store slots T *paths = __a_unserializet(dir_path,PATHS_FN); int i = 0; int c = _t_children(paths); for(i=1;i<=c;i++) { T *p = _t_child(paths,i); if (semeq(RECEPTOR_PATH,_t_symbol(p))) { T *x = _t_get(t,(int *)_t_surface(p)); sem->stores[i-1].definitions = x; } } _t_free(paths); sem->contexts = c+1; // unserialize all of the vmhost's instantiated receptors and other instances __a_vmfn(fn,dir_path); buffer = readFile(fn,0); Receptor *r = _r_unserialize(sem,buffer); G_vm = __v_init(r,sem); free(buffer); // unserialize other vmhost state data S *s; __a_vm_state_fn(fn,dir_path); s = readFile(fn,0); H h = _m_unserialize(s); free(s); H hars; hars.m=h.m; hars.a = _m_child(h,1); // first child is ACTIVE_RECEPTORS H har; har.m=h.m; int j = _m_children(hars); for (i=1;i<=j;i++) { har.a = _m_child(hars,i); if(!semeq(_m_symbol(har),RECEPTOR_XADDR)) raise_error("expecting RECEPTOR_XADDR!"); _v_activate(G_vm,*(Xaddr *)_m_surface(har)); } _m_free(h); } G_vm->dir = dir_path; // _a_check_vm_host_version_on_the_compository(); _v_start_vmhost(G_vm); }