/** * @brief Creates a new virtual machine host * * allocates all the memory needed in the heap * * @returns pointer to a newly allocated VMHost * <b>Examples (from test suite):</b> * @snippet spec/vmhost_spec.h testVMHostCreate */ VMHost * _v_new() { SemTable *sem = _sem_new(); base_contexts(sem); base_defs(sem); Receptor *r = _r_new(sem,SYS_RECEPTOR); VMHost *v = __v_init(r,sem); r = _r_new(sem,COMPOSITORY); _v_new_receptor(v,v->r,COMPOSITORY,r); r = _r_new(sem,DEV_COMPOSITORY); _v_new_receptor(v,v->r,DEV_COMPOSITORY,r); r = _r_new(sem,TEST_RECEPTOR); _v_new_receptor(v,v->r,TEST_RECEPTOR,r); _r_defineClockReceptor(sem); return v; }
/** * install a receptor into vmhost, creating a symbol for it * * @param[in] v VMHost in which to install the receptor * @param[in] package xaddr of package to install * @param[in] bindings completed manifest which specifies how the receptor will be installed * @param[in] label label to be used for the semantic name for this receptor * @returns Xaddr of the instance * * <b>Examples (from test suite):</b> * @snippet spec/vmhost_spec.h testVMHostInstallReceptor */ Xaddr _v_install_r(VMHost *v,Xaddr package,T *bindings,char *label) { raise_error("not implemented"); T *p;// = _r_get_instance(v->c,package); T *id = _t_child(p,2); TreeHash h = _t_hash(v->r->sem,id); // make sure we aren't re-installing an already installed receptor Xaddr x = _s_get(v->installed_receptors,h); if (!(is_null_xaddr(x))) return G_null_xaddr; _s_add(v->installed_receptors,h,package); // confirm that the bindings match the manifest /// @todo expand the manifest to allow optional binding, etc, using semtrex to do the matching instead of assuming positional matching if (bindings) { T *m = _t_child(p,1); int c = _t_children(m); if (c%2) {raise_error("manifest must have even number of children!");} int i; for(i=1;i<=c;i++) { T *mp = _t_child(m,i); T *s = _t_child(mp,2); T *bp = _t_child(bindings,i); if (!bp) { raise_error("missing binding for %s",(char *)_t_surface(_t_child(mp,1))); } T *vb = _t_child(bp,2); Symbol spec = *(Symbol *)_t_surface(s); if (semeq(_t_symbol(vb),spec)) { T *symbols = _t_child(p,3); raise_error("bindings symbol %s doesn't match spec %s",_sem_get_name(v->r->sem,_t_symbol(vb)),_sem_get_name(v->r->sem,spec)); } } } Symbol s = _r_define_symbol(v->r,RECEPTOR,label); raise_error("fix semtable"); Receptor *r = _r_new_receptor_from_package(NULL,s,p,bindings); return _v_new_receptor(v,v->r,s,r); }
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); }
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; }
/** * 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); }