ceptr
 All Data Structures Files Functions Variables Typedefs Macros Modules Pages
receptor.c
Go to the documentation of this file.
1 
11 #include "receptor.h"
12 #include "stream.h"
13 #include "semtrex.h"
14 #include "process.h"
15 #include "accumulator.h"
16 #include "debug.h"
17 #include "mtree.h"
18 #include "protocol.h"
19 #include <stdarg.h>
20 #include <time.h>
21 #include <unistd.h>
22 
23 Xaddr G_null_xaddr = {0,0};
24 /***************** create and destroy receptors */
25 
26 /* set up the c structures for a receptor from a semantic tree */
27 Receptor * __r_init(T *t,SemTable *sem) {
28  Receptor *r = malloc(sizeof(Receptor));
29  r->root = t;
30  r->parent = *(int *)_t_surface(_t_child(t,ReceptorInstanceParentContextIdx));
31  r->context = *(int *)_t_surface(_t_child(t,ReceptorInstanceContextNumIdx));
32  r->addr.addr = r->context; //@fixme!! for now these are the same, but this needs to get fixed
33  r->sem = sem;
34  r->instances = NULL;
35  r->q = _p_newq(r);
36  r->state = Alive; //@todo, check if this is true on unserialize
37 
38  T *state = _t_child(t,ReceptorInstanceStateIdx);
39  r->flux = _t_child(state,ReceptorFluxIdx);
40  r->pending_signals = _t_child(state,ReceptorPendingSignalsIdx);
41  r->pending_responses = _t_child(state,ReceptorPendingResponsesIdx);
42  r->conversations = _t_child(state,ReceptorConversationsIdx);
43  r->edge = NULL;
44  return r;
45 }
46 
47 T *__r_add_aspect(T *flux,Aspect aspect) {
48  T *a = _t_newr(flux,aspect);
49  _t_newr(a,EXPECTATIONS);
50  _t_newr(a,SIGNALS);
51  return a;
52 }
53 
54 T *_r_make_state() {
55  T *t = _t_new_root(RECEPTOR_STATE);
56  T *f = _t_newr(t,FLUX);
57  __r_add_aspect(f,DEFAULT_ASPECT);
58  _t_newr(t,PENDING_SIGNALS);
59  _t_newr(t,PENDING_RESPONSES);
60  _t_newr(t,CONVERSATIONS);
61  _t_newi(t,RECEPTOR_ELAPSED_TIME,0);
62  return t;
63 }
64 
65 //helper to make empty definitions tree
66 T *__r_make_definitions() {
67  T *defs = _t_new_root(DEFINITIONS);
68  _t_newr(defs,STRUCTURES);
69  _t_newr(defs,SYMBOLS);
70  _t_newr(defs,PROCESSES);
71  _t_newr(defs,RECEPTORS);
72  _t_newr(defs,PROTOCOLS);
73  _t_newr(defs,SCAPES);
74  return defs;
75 }
76 
89  T *t = _t_new_root(RECEPTOR_INSTANCE);
90  _t_news(t,INSTANCE_OF,r);
91  if (semeq(r,SYS_RECEPTOR)) {
92  _t_newi(t,CONTEXT_NUM,0);
93  _t_newi(t,PARENT_CONTEXT_NUM,-1);
94  }
95  else {
96  _t_newi(t,CONTEXT_NUM,_d_get_receptor_context(sem,r));
97  _t_newi(t,PARENT_CONTEXT_NUM,r.context);
98  }
99  T *state = _r_make_state();
100  _t_add(t,state);
101  return __r_init(t,sem);
102 }
103 
115  T *defs = _t_clone(_t_child(p,3));
116  // T *aspects = _t_clone(_t_child(p,4)); @todo this should be inside the defs allready
117  raise_error("fix receptor address");
118  Receptor *r = _r_new(sem,s);
119 
120  //@todo fix this because it relies on SemanticTypes value matching the index order in the definitions.
121  // DO_KIDS(defs,__r_set_labels(r,_t_child(defs,i),i));
122 
123  return r;
124 }
125 
126 T *__r_build_default_until() {
127  T *until = _t_new_root(END_CONDITIONS);
128  _t_newr(until,UNLIMITED);
129  return until;
130 }
131 
132 // helper to build and expectation tree
133 T *__r_build_expectation(Symbol carrier,T *pattern,T *action,T *with,T *until,T *using,T *cid) {
134  T *e = _t_newr(0,EXPECTATION);
135  _t_news(e,CARRIER,carrier);
136  _t_add(e,pattern);
137  _t_add(e,action);
138  if (!with) with = _t_new_root(PARAMS);
139  _t_add(e,with);
140  if (!until) {
141  until = __r_build_default_until();
142  }
143  _t_add(e,until);
144  if (using)
145  _t_add(e,using);
146  if (cid) {
147  _t_add(e,cid);
148  }
149  return e;
150 }
151 
164 void _r_add_expectation(Receptor *r,Aspect aspect,Symbol carrier,T *pattern,T *action,T *with,T *until,T *using,T *cid) {
165  T *e = __r_build_expectation(carrier,pattern,action,with,until,using,cid);
166  __r_add_expectation(r,aspect,e);
167 }
168 
169 void __r_add_expectation(Receptor *r,Aspect aspect,T *e) {
170  T *a = __r_get_expectations(r,aspect);
171  _t_add(a,e);
172 }
173 
174 void _r_remove_expectation(Receptor *r,T *expectation) {
175  T *a = _t_parent(expectation);
176  _t_detach_by_ptr(a,expectation);
177  _t_free(expectation);
178  // @todo, if there are any processes blocked on this expectation they
179  // should actually get cleaned up somehow. This would mean searching
180  // through for them, or something...
181 }
182 
186 void _r_free(Receptor *r) {
187  _t_free(r->root);
188  _a_free_instances(&r->instances);
189  if (r->q) _p_freeq(r->q);
190 
191  // special cases for cleaning up edge receptor resources that
192  // don't get cleaned up the usual way, i.e. socket listener streams
193  if (r->edge) {
194  T *t;
195  while(t = _t_detach_by_idx(r->edge,1)) {
196  if (semeq(_t_symbol(t),EDGE_LISTENER)) {
199  }
200  _t_free(t);
201  }
202  _t_free(r->edge);
203  }
204  free(r);
205 }
206 
207 /***************** receptor symbols, structures and processes */
208 
219  Symbol sym = _d_define_symbol(r->sem,s,label,r->context);
220  return sym;
221 }
222 
236 Structure _r_define_structure(Receptor *r,char *label,int num_params,...) {
237  va_list params;
238  va_start(params,num_params);
239  T *def = _d_make_vstruc_def(r->sem,label,num_params,params);
240  va_end(params);
241  Structure s = _d_define_structure(r->sem,label,def,r->context);
242  return s;
243 }
244 
258 Structure __r_define_structure(Receptor *r,char *label,T *structure_def) {
259  Structure s = _d_define_structure(r->sem,label,structure_def,r->context);
260  return s;
261 }
262 
275 Process _r_define_process(Receptor *r,T *code,char *name,char *intention,T *signature,T *link) {
276  Process p = _d_define_process(r->sem,code,name,intention,signature,link,r->context);
277  return p;
278 }
279 
280 Protocol _r_define_protocol(Receptor *r,T *protocol_def) {
281  Protocol p = _d_define_protocol(r->sem,protocol_def,r->context);
282  return p;
283 }
284 
289  SemanticID sid;
290  if (!__sem_get_by_label(r->sem,label,&sid,r->context))
291  raise_error("label not found %s",label);
292  return sid;
293 }
294 
300  return _sem_get_symbol_structure(r->sem,s);
301 }
302 
307 size_t __r_get_structure_size(Receptor *r,Structure s,void *surface) {
308  return _d_get_structure_size(r->sem,s,surface);
309 }
314 size_t __r_get_symbol_size(Receptor *r,Symbol s,void *surface) {
315  return _d_get_symbol_size(r->sem,s,surface);
316 }
317 
326  return _d_build_def_semtrex(r->sem,s,0);
327 }
328 
344  T *stx = _r_build_def_semtrex(r,s);
345  int result = _t_match(stx,t);
346  _t_free(stx);
347  return result;
348 }
349 
350 /***************** receptor instances and xaddrs */
351 
366  return _a_new_instance(&r->instances,t);
367 }
368 
380  return _a_get_instance(&r->instances,x);
381 }
382 
395  return _a_set_instance(&r->instances,x,t);
396 }
397 
408  _a_delete_instance(&r->instances,x);
409 }
410 
414 TreeHash _r_hash(Receptor *r,Xaddr t) {
415  return _t_hash(r->sem,_r_get_instance(r,t));
416 }
417 
418 /****************** receptor serialization */
419 
432 void _r_serialize(Receptor *r,void **surfaceP,size_t *lengthP) {
433  /* size_t buf_size = 10000; */
434  /* *surfaceP = malloc(buf_size); */
435  /* *lengthP = __t_serialize(&r->defs,r->root,surfaceP,sizeof(size_t),buf_size,0); */
436  /* *(size_t *)(*surfaceP) = *lengthP; */
437 
438  H h = _m_new_from_t(r->root);
439  S *s = _m_serialize(h.m);
440 
441  S *is = __a_serialize_instances(&r->instances);
442  s = (S *)realloc(s,s->total_size+is->total_size);
443  memcpy(((void *)s)+s->total_size,is,is->total_size);
444 
445  *lengthP = s->total_size+is->total_size;
446  *surfaceP = (void *)s;
447  free(is);
448  _m_free(h);
449 }
450 
459 Receptor * _r_unserialize(SemTable *sem,void *surface) {
460 
461  S *s = (S *)surface;
462  H h = _m_unserialize(s);
463 
464  T *t = _t_new_from_m(h);
465  _m_free(h);
466 
467  Receptor *r = __r_init(t,sem);
468 
469  /* size_t length = *(size_t *)surface; */
470  /* Receptor *r = _r_new(*(Symbol *)(surface+sizeof(size_t))); */
471  /* surface += sizeof(size_t); */
472  /* T *t = _t_unserialize(&r->defs,&surface,&length,0); */
473  /* _t_free(r->root); */
474  /* r->root = t; */
475  // T *defs = _t_child(t,1);
476  // DO_KIDS(defs,__r_set_labels(r,_t_child(defs,i),i));
477 
478  // move to the instances
479  s = (S *) (surface + s->total_size);
480  __a_unserialize_instances(sem,&r->instances,(S *)s);
481  return r;
482 }
483 
484 /****************** receptor signaling */
485 
486 // build a receptor address. This is scaffolding for later receptor
487 // addressing that will include both ceptrnet addresses and receptor paths
488 // as a possible options for addressing the receptor.
489 T *___r_make_addr(T *parent,Symbol type,ReceptorAddress addr,bool is_run_node) {
490  T *a = __t_newr(parent,type,is_run_node);
491  __t_newi(a,RECEPTOR_ADDR,addr.addr,is_run_node);
492  return a;
493 }
494 
495 ReceptorAddress __r_get_addr(T *addr) {
496  // for now they are all instance nums so we can just get the surface
497  // of the first child.
498  T *t = _t_child(addr,1);
499  return *(ReceptorAddress *)_t_surface(t);
500 }
501 
515 T* __r_make_signal(ReceptorAddress from,ReceptorAddress to,Aspect aspect,Symbol carrier,T *signal_contents,UUIDt *in_response_to,T* until,T *cid) {
516  T *s = _t_new_root(SIGNAL);
517  T *e = _t_newr(s,ENVELOPE);
518  T *m = _t_newr(s,MESSAGE);
519  T *h = _t_newr(m,HEAD);
520  // @todo convert to paths at some point?
521  __r_make_addr(h,FROM_ADDRESS,from);
522  __r_make_addr(h,TO_ADDRESS,to);
523  _t_news(h,ASPECT_IDENT,aspect);
524  _t_news(h,CARRIER,carrier);
525  UUIDt t = __uuid_gen();
526  _t_new(e,SIGNAL_UUID,&t,sizeof(UUIDt));
527  T *b = _t_newt(m,BODY,signal_contents);
528 
529  if (in_response_to && until) raise_error("attempt to make signal with both response_uuid and until");
530  if (in_response_to)
531  _t_new(h,IN_RESPONSE_TO_UUID,in_response_to,sizeof(UUIDt));
532  else if (until)
533  _t_add(h,until);
534  if (cid) {
535  _t_add(h,_t_clone(cid));
536  }
537  return s;
538 }
539 
540 // low level send, must be called with pending_signals resource locked!!
541 T* __r_send(Receptor *r,T *signal) {
542  _t_add(r->pending_signals,signal);
543 
544  //@todo for now we return the UUID of the signal as the result. Perhaps later we return an error condition if delivery to address is known to be impossible, or something like that.
545  T *envelope = _t_child(signal,SignalEnvelopeIdx);
546  return _t_rclone(_t_child(envelope,EnvelopeSignalUUIDIdx));
547 }
548 
556 T* _r_send(Receptor *r,T *signal) {
557  debug(D_SIGNALS,"sending %s\n",_t2s(r->sem,signal));
558  //@todo lock resources
559  T *result =__r_send(r,signal);
560  //@todo unlock resources
561  return result;
562 }
563 
575 T* _r_request(Receptor *r,T *signal,Symbol response_carrier,T *code_point,int process_id,T *cid) {
576 
577  //@todo lock resources
578  T *result = __r_send(r,signal); // result is signal UUID
579  T *pr = _t_newr(r->pending_responses,PENDING_RESPONSE);
580  _t_add(pr,_t_clone(result));
581  _t_news(pr,CARRIER,response_carrier);
582  _t_add(pr,__p_build_wakeup_info(code_point,process_id));
583  int p[] = {SignalMessageIdx,MessageHeadIdx,HeadOptionalsIdx,TREE_PATH_TERMINATOR};
584  T *ec = _t_get(signal,p);
585  if (!ec || !semeq(_t_symbol(ec),END_CONDITIONS)) raise_error("request missing END_CONDITIONS");
586  _t_add(pr,_t_clone(ec));
587  if (cid) _t_add(pr,_t_clone(cid));
588 
589  debug(D_SIGNALS,"sending request and adding pending response: %s\n",_td(r,pr));
590  //@todo unlock resources
591 
592  return result;
593 }
594 
595 // check if the end condition has been met
596 // @todo find the correct home for this function
597 void evaluateEndCondition(T *ec,bool *cleanup,bool *allow) {
598  *cleanup = false;
599  *allow = false;
600  int k = _t_children(ec);
601  while (k) {
602  T *c = _t_child(ec,k);
603  Symbol sym = _t_symbol(c);
604  if (semeq(sym,COUNT)) {
605  //@todo mutex!!
606  int *cP = (int *)_t_surface(c);
607  if (*cP <= 1) *cleanup = true;
608  if (*cP >= 1) *allow = true;
609  (*cP)--;
610  debug(D_SIGNALS,"decreasing count to: %d\n",*cP);
611  break; // this is final, even if there's a timeout
612  }
613  else if (semeq(sym,TIMEOUT_AT)) {
614  T *td = _t_child(c,1);
615  T *nw = _t_child(c,2);
616  int year = *(int *)_t_surface(_t_child(td,1))-1900;
617  int mon = *(int *)_t_surface(_t_child(td,2))-1;
618  int mday = *(int *)_t_surface(_t_child(td,3));
619  int hour = *(int *)_t_surface(_t_child(nw,1));
620  int min = *(int *)_t_surface(_t_child(nw,2));
621  int sec = *(int *)_t_surface(_t_child(nw,3));
622 
623  //debug(D_SIGNALS,"T: y:%d,m:%d,d:%d,h:%d,m:%d,s:%d\n")
624  time_t now_t;
625  time(&now_t);
626  struct tm now;
627  gmtime_r(&now_t, &now);
628  if ((year > now.tm_year) ||
629  (mon > now.tm_mon) ||
630  (mday > now.tm_mday) ||
631  (hour > now.tm_hour) ||
632  (min > now.tm_min) ||
633  (sec > now.tm_sec)) {
634  *allow = true;
635  }
636 
637  *cleanup = !*allow;
638  }
639  else if (semeq(sym,UNLIMITED)) {
640  *allow = true;
641  }
642  else {
643  raise_error("unknown end condition %s",t2s(c));
644  }
645 
646  k--;
647  }
648  debug(D_SIGNALS,"after end condition %s cleanup=%s allow=%s\n",t2s(ec),*cleanup?"true":"false",*allow?"true":"false");
649 }
650 
656 void __r_test_expectation(Receptor *r,T *expectation,T *signal) {
657  Q *q = r->q;
658  int p[] = {SignalMessageIdx,MessageBodyIdx,TREE_PATH_TERMINATOR};
659  T *body = _t_get(signal,p);
660  T *signal_contents = (T *)_t_surface(body);
661 
662  //test carriers first because they must match
663  T *e_carrier = _t_child(expectation,ExpectationCarrierIdx);
664  T *head =_t_getv(signal,SignalMessageIdx,MessageHeadIdx,TREE_PATH_TERMINATOR);
665  T *s_carrier = _t_child(head,HeadCarrierIdx);
666 
667  debug(D_SIGNALS,"checking signal carrier %s\n",_td(q->r,s_carrier));
668  debug(D_SIGNALS,"against expectation carrier %s\n",_td(q->r,e_carrier));
669 
670  Symbol esym = *(Symbol *)_t_surface(e_carrier);
671  if (!semeq(esym,*(Symbol *)_t_surface(s_carrier)) && !semeq(esym,NULL_SYMBOL)) return;
672 
673  T *s_cid = __t_find(head,CONVERSATION_IDENT,HeadOptionalsIdx);
674  T *e_cid = __t_find(expectation,CONVERSATION_IDENT,ExpectationOptionalsIdx);
675  debug(D_SIGNALS,"checking signal conversation %s\n",_td(q->r,s_cid));
676  debug(D_SIGNALS,"against expectation conversation %s\n",_td(q->r,e_cid));
677 
678  // if expectation is keyed to a conversation and the signal isn't the instant no match
679  if (e_cid && !s_cid) return;
680  // if both signal and expectation are keyed to a conversation test the ids for equality
681  if (s_cid && e_cid) {
682  if (!__cid_equal(r->sem,s_cid,e_cid)) return;
683  }
684 
685  T *pattern,*m;
686  pattern = _t_child(expectation,ExpectationPatternIdx);
687  // if we get a match, create a run tree from the action, using the match and signal as the parameters
688  T *stx = _t_news(0,SEMTREX_GROUP,NULL_SYMBOL);
689  _t_add(stx,_t_clone(_t_child(pattern,1)));
690  debug(D_SIGNALS,"matching %s\n",_td(q->r,signal_contents));
691  debug(D_SIGNALS,"against %s\n",_td(q->r,stx));
692 
693  bool matched;
694  matched = _t_matchr(stx,signal_contents,&m);
695  bool allow;
696  bool cleanup;
697  evaluateEndCondition(_t_child(expectation,ExpectationEndCondsIdx),&cleanup,&allow);
698 
699  if (allow && matched) {
700  debug(D_SIGNALS,"got a match on %s\n",_td(q->r,stx));
701 
702  T *rt=0;
703  T *action = _t_child(expectation,ExpectationActionIdx);
704  if (!action) {
705  raise_error("null action in expectation!");
706  }
707 
708  if (semeq(_t_symbol(action),WAKEUP_REFERENCE)) {
709  /* // for now we add the params to the contexts run tree */
710  /* /// @todo later this should be integrated into some kind of scoping handling */
711  T *params = _t_rclone(_t_child(expectation,ExpectationParamsIdx));
712  _p_fill_from_match(r->sem,params,m,signal_contents);
713  _p_wakeup(q,action,params,noReductionErr);
714  cleanup = true; //always cleanup after a wakeup because the context is gone.
715  }
716  else {
717  Process p = *(Process*) _t_surface(action);
718 
719  // _p_make_run_tree assumes rT nodes
720  T *params = _t_rclone(_t_child(expectation,ExpectationParamsIdx));
721  _p_fill_from_match(r->sem,params,m,signal_contents);
722  T *sm = __t_find(expectation,SEMANTIC_MAP,ExpectationOptionalsIdx);
723  if (sm) sm = _t_clone(sm);
724  debug(D_SIGNALS,"creating a run tree for action %s with params %s\n",_sem_get_name(r->sem,p),_t2s(r->sem,params));
725  //@todo check the signature?
726  rt = _p_make_run_tree(r->sem,p,params,sm);
727  _t_free(params);
728  _t_add(signal,rt);
729  __p_addrt2q(q,rt,sm);
730  }
731  _t_free(m);
732  }
733  if (cleanup) {
734  debug(D_SIGNALS,"cleaning up %s\n",_td(q->r,expectation));
735  _r_remove_expectation(q->r,expectation);
736  }
737 
738  _t_free(stx);
739 }
740 
741 // what kind of sanatizing do we do of the actual response signal?
742 T* __r_sanatize_response(Receptor *r,T* response) {
743  return _t_rclone(response);
744 }
745 
746 int __r_deliver_response(Receptor *r,T *response_to,T *signal) {
747  T *head = _t_getv(signal,SignalMessageIdx,MessageHeadIdx,TREE_PATH_TERMINATOR);
748  // responses don't trigger expectation matching, instead they
749  // go through the pending_responses list to see where the signal goes
750  UUIDt *u = (UUIDt*)_t_surface(response_to);
751  debug(D_SIGNALS,"Delivering response: %s\n",_td(r,signal));
752  Symbol signal_carrier = *(Symbol *)_t_surface(_t_child(head,HeadCarrierIdx));
753 
754  T *body = _t_getv(signal,SignalMessageIdx,MessageBodyIdx,TREE_PATH_TERMINATOR);
755  T *response = (T *)_t_surface(body);
756  T *l;
757  DO_KIDS(r->pending_responses,
758  l = _t_child(r->pending_responses,i);
759  if (__uuid_equal(u,(UUIDt *)_t_surface(_t_child(l,PendingResponseUUIDIdx)))) {
760 
761  // get the end conditions so we can see if we should actually respond
762  T *ec = _t_child(l,PendingResponseEndCondsIdx);
763  bool allow;
764  bool cleanup;
765  evaluateEndCondition(ec,&cleanup,&allow);
766 
767  if (allow) {
768  Symbol carrier = *(Symbol *)_t_surface(_t_child(l,PendingResponseCarrierIdx));
769  T *wakeup = _t_child(l,PendingResponseWakeupIdx);
770  // now set up the signal so when it's freed below, the body doesn't get freed too
771  signal->context.flags &= ~TFLAG_SURFACE_IS_TREE;
772  if (!semeq(carrier,signal_carrier)) {
773  debug(D_SIGNALS,"response failed carrier check, expecting %s, but got %s!\n",_r_get_symbol_name(r,carrier),_r_get_symbol_name(r,signal_carrier));
774  //@todo what kind of logging of these kinds of events?
775  break;
776  }
777 
778  response = __r_sanatize_response(r,response);
779  // if the response isn't safe just break
780  if (!response) {
781  //@todo figure out if this means we should throw away the pending response too
782  break;
783  }
784  _p_wakeup(r->q,wakeup,response,noReductionErr);
785  }
786 
787  if (cleanup) {
788  debug(D_SIGNALS,"removing pending response: %s\n",_td(r,l));
789  _t_detach_by_idx(r->pending_responses,i);
790  //i--;
791  _t_free(l);
792  }
793  break;
794  }
795  );
796  _t_free(signal);
797  return noDeliveryErr;
798 }
799 
800 
801 bool __cid_equal(SemTable *sem,T *cid1,T*cid2) {
802  UUIDt *u1 = __cid_getUUID(cid1);
803  UUIDt *u2 = __cid_getUUID(cid2);
804  return __uuid_equal(u1,u2);
805  // return _t_hash(sem,cid1) == _t_hash(sem,cid2);
806 }
807 
808 T *__cid_new(T *parent,UUIDt *c,T *topic) {
809  T *cid = _t_newr(parent,CONVERSATION_IDENT);
810  _t_new(cid,CONVERSATION_UUID,c,sizeof(UUIDt));
811  return cid;
812 }
813 
814 UUIDt *__cid_getUUID(T *cid) {
815  return (UUIDt *)_t_surface(_t_child(cid,ConversationIdentUUIDIdx));
816 }
817 
818 // registers a new conversation at the receptor level. Note that this routine
819 // expects that the until param (if provided) can be added to the conversation tree,
820 // i.e. it must not be part of some other tree.
821 T * _r_add_conversation(Receptor *r,UUIDt *parent_u,UUIDt *u,T *until,T *wakeup) {
822  T *c = _t_new_root(CONVERSATION);
823  T *cu = __cid_new(c,u,0);
824 
825  _t_add(c, until ? until : __r_build_default_until());
826  _t_newr(c,CONVERSATIONS); // add the root for any sub-conversations
827  if (wakeup) _t_add(c,wakeup);
828 
829  //@todo NOT THREAD SAFE, add locking
830  T *p;
831  if (parent_u) {
832  p = _r_find_conversation(r,parent_u);
833  p = _t_child(p,ConversationConversationsIdx);
834  if (!p) raise_error("parent conversation not found!");
835  }
836  else p = r->conversations;
837  _t_add(p,c);
838  //@todo UNLOCK
839  return c;
840 }
841 
842 // finds a conversation searching recursively through sub-conversations
843 T *__r_find_conversation(T *conversations, UUIDt *uuid) {
844  T *c,*ci;
845  bool found = false;
846 
847  // @todo lock?
848  DO_KIDS(conversations,
849  c = _t_child(conversations,i);
850  UUIDt *u = __cid_getUUID(_t_child(c,ConversationIdentIdx));
851  if (__uuid_equal(uuid,u)) {
852  found = true;
853  break;
854  }
855  T *sub_conversations = _t_child(c,ConversationConversationsIdx);
856  if (_t_children(sub_conversations)) {
857  c = __r_find_conversation(sub_conversations,uuid);
858  if (c) {found = true;break;}
859  }
860  );
861  // @todo unlock
862  return found?c:NULL;
863 }
864 
865 T *_r_find_conversation(Receptor *r, UUIDt *uuid) {
866  // @todo reimplement with semtrex?
867  return __r_find_conversation(r->conversations, uuid);
868 }
869 
870 
871 typedef void (*doConversationFn)(T *,void *);
872 void __r_walk_conversation(T *conversation, doConversationFn fn,void *param) {
873  (*fn)(_t_child(conversation,ConversationIdentIdx),param);
874 
875  T *conversations = _t_child(conversation,ConversationConversationsIdx);
876  if (_t_children(conversations)) {
877  T *c;
878  DO_KIDS(conversations,
879  c = _t_child(conversations,i);
880  __r_walk_conversation(c,param,fn);
881  );
882  }
883 }
884 
885 void _cleaner(T *cid,void *p) {
886  Receptor *r = (Receptor *)p;
887  UUIDt *u = __cid_getUUID(cid);
888  T *e,*ex;
889  int i,j;
890  // remove any pending listeners that were established in the covnersation
891  // @todo implement saving expectations in conversations into a hash
892  // so we don't have to do this ugly n^2 search...
893  for(j=1;j<=_t_children(r->flux);j++) {
894  ex = _t_child(_t_child(r->flux,j),aspectExpectationsIdx);
895  for(i=1;i<=_t_children(ex);i++) {
896  e = _t_child(ex,i);
897  T *cid = __t_find(e,CONVERSATION_IDENT,ExpectationOptionalsIdx);
898  if (cid && __uuid_equal(u,__cid_getUUID(cid))) {
899  _t_detach_by_ptr(ex,e);
900  _t_free(e);
901  i--;
902  }
903  }
904  }
905  // remove any pending response handlers from requests
906  for(i=1;i<=_t_children(r->pending_responses);i++) {
907  e = _t_child(r->pending_responses,i);
908  T *cid = _t_child(e,PendingResponseConversationIdentIdx);
909  if (cid && __uuid_equal(u,__cid_getUUID(cid))) {
910  _t_detach_by_ptr(r->pending_responses,e);
911  _t_free(e);
912  i--;
913  }
914  }
915 }
916 
917 // cleans up any pending requests, listens and the conversation record
918 // returns the wakeup reference
919 T * __r_cleanup_conversation(Receptor *r, UUIDt *cuuid) {
920  // @todo lock conversations?
921  T *c = _r_find_conversation(r,cuuid);
922  if (!c) {
923  raise_error("can't find conversation");
924  }
925  T *w = _t_detach_by_idx(c,ConversationWakeupIdx);
926 
927  __r_walk_conversation(c,_cleaner,r);
928 
930  _t_free(c);
931  // @todo unlock conversations?
932  return w;
933 }
934 
954 Error _r_deliver(Receptor *r, T *signal) {
955 
956  T *head = _t_getv(signal,SignalMessageIdx,MessageHeadIdx,TREE_PATH_TERMINATOR);
957 
958  T *conversation = NULL;
959  T *end_conditions = NULL;
960  T *response_to = NULL;
961 
962  // check the optional HEAD items to see if this is more than a plain signal
963  int optionals = HeadOptionalsIdx;
964  T *extra;
965  while(extra =_t_child(head,optionals++)) {
966  Symbol sym = _t_symbol(extra);
967  if (semeq(CONVERSATION_IDENT,sym))
968  conversation = extra;
969  else if (semeq(IN_RESPONSE_TO_UUID,sym))
970  response_to = extra;
971  else if (semeq(END_CONDITIONS,sym))
972  end_conditions = extra;
973  }
974 
975  // if there is a conversation, check to see if we've got a scope open for it
976  if (conversation) {
977  UUIDt *cuuid = __cid_getUUID(conversation);
978  T *c = _r_find_conversation(r,cuuid);
979  if (!c) {
980  c = _r_add_conversation(r,0,cuuid,end_conditions,NULL);
981  }
982  }
983 
984  // if there is an IN_RESPONSE_TO_UUID then we know it's a response
985  if (response_to) {
986  return __r_deliver_response(r,response_to,signal);
987  }
988  else {
989 
990  // if there are END_CONDITIONS we know this is a request
991  if (end_conditions) {
992  // determine if we will honor the request conditions?
993  // perhaps that all happens at the protocol level
994  // @todo anything specific we need to store here??
995  }
996 
997  Aspect aspect = *(Aspect *)_t_surface(_t_child(head,HeadAspectIdx));
998 
999  T *as = __r_get_signals(r,aspect);
1000 
1001  debug(D_SIGNALS,"Delivering: %s\n",_td(r,signal));
1002  _t_add(as,signal);
1003  // walk through all the expectations on the aspect and see if any expectations match this incoming signal
1004  T *es = __r_get_expectations(r,aspect);
1005  debug(D_SIGNALS,"Testing %d expectations\n",es ? _t_children(es) : 0);
1006  T *l;
1007  DO_KIDS(es,
1008  l = _t_child(es,i);
1009  __r_test_expectation(r,l,signal);
1010  );
1011  }
1012  return noDeliveryErr;
1013 }
1014 
1015 /****************** internal utilities */
1016 
1017 T *__r_get_aspect(Receptor *r,Aspect aspect) {
1018  int i;
1019  T *a;
1020  DO_KIDS(r->flux,
1021  a = _t_child(r->flux,i);
1022  if (semeq(aspect,_t_symbol(a)))
1023  return a;
1024  );
1025  a = __r_add_aspect(r->flux,aspect);
1026  return a;
1027 }
1028 T *__r_get_expectations(Receptor *r,Aspect aspect) {
1029  return _t_child(__r_get_aspect(r,aspect),aspectExpectationsIdx);
1030 }
1031 T *__r_get_signals(Receptor *r,Aspect aspect) {
1032  return _t_child(__r_get_aspect(r,aspect),aspectSignalsIdx);
1033 }
1034 
1035 
1039 Receptor * __r_get_receptor(T *installed_receptor) {
1040  if (! is_receptor(_t_symbol(installed_receptor)))
1041  raise_error("expecting SEM_TYPE_RECEPTOR!");
1042  return (Receptor *)_t_surface(installed_receptor);
1043 }
1044 
1045 /***************** Tree debugging utilities */
1046 
1047 char *_r_get_symbol_name(Receptor *r,Symbol s) {
1048  return _sem_get_name(r->sem,s);
1049 }
1050 
1051 char *_r_get_structure_name(Receptor *r,Structure s) {
1052  return _sem_get_name(r->sem,s);
1053 }
1054 
1055 char *_r_get_process_name(Receptor *r,Process p) {
1056  return _sem_get_name(r->sem,p);
1057 }
1058 
1059 char __t_dump_buf[10000];
1060 
1061 char *_td(Receptor *r,T *t) {
1062  __td(r,t,__t_dump_buf);
1063 }
1064 
1065 char *__td(Receptor *r,T *t,char *buf) {
1066  if (!t) sprintf(buf,"<null-tree>");
1067  else
1068  __t_dump(r->sem,t,0,buf);
1069  return buf;
1070 }
1071 
1072 /***************** Built-in core and edge receptors */
1073 // functions for stream edge receptors
1074 
1075 Receptor *_r_makeStreamEdgeReceptor(SemTable *sem) {
1076  Receptor *r = _r_new(sem,STREAM_EDGE);
1077  return r;
1078 }
1079 
1080 void __r_listenerCallback(Stream *st,void *arg) {
1081  Receptor *r = (Receptor *)arg;
1082 
1083  T *code = _t_rclone(_t_child(r->edge,2));
1084  T *params = _t_clone(_t_child(r->edge,3));
1085  _t_new_cptr(params,EDGE_STREAM,st);
1086  T *err_handler = _t_child(r->edge,4);
1087 
1088  T *run_tree = _t_new_root(RUN_TREE);
1089  _t_add(run_tree,code);
1090  _t_add(run_tree,params);
1091  if (err_handler) {
1092  _t_add(run_tree,_t_rclone(err_handler));
1093  }
1094 
1095  _p_addrt2q(r->q,run_tree);
1096 
1097 }
1098 
1099 SocketListener *_r_addListener(Receptor *r,int port,T *code,T*params,T *err_handler,char *delim) {
1100  T *e = _t_new_root(PARAMS);
1101 
1102  SocketListener *l = _st_new_socket_listener(port,__r_listenerCallback,r,delim);
1103  _t_new_cptr(e,EDGE_LISTENER,l);
1104  _t_add(e,code);
1105  if (!params) params = _t_newr(e,PARAMS);
1106  else _t_add(e,params);
1107  if (err_handler) _t_add(e,err_handler);
1108 
1109  if (r->edge) raise_error("edge in use!!");
1110  r->edge = e;
1111  return l;
1112 }
1113 
1114 void _r_addReader(Receptor *r,Stream *st,ReceptorAddress to,Aspect aspect,Symbol carrier,Symbol result_symbol,bool conversation) {
1115 
1116  // code is something like:
1117  // (do (not stream eof) (send to (read_stream stream line)))
1118 
1119  T *p,*code = NULL;
1120  if (conversation) {
1121  code = _t_new_root(CONVERSE);
1122  p = _t_newr(code,SCOPE);
1123  p = _t_newr(p,ITERATE);
1124  }
1125  else {
1126  code = p = _t_new_root(ITERATE);
1127  }
1128 
1129  T *params = _t_newr(p,PARAMS);
1130  T *eof = _t_newr(p,STREAM_ALIVE);
1131 
1132  _t_new_cptr(eof,EDGE_STREAM,st);
1133  // _t_newi(p,TEST_INT_SYMBOL,2); // two repetitions
1134  T *say = _t_newr(p,SAY);
1135 
1136  __r_make_addr(say,TO_ADDRESS,to);
1137  _t_news(say,ASPECT_IDENT,aspect);
1138  _t_news(say,CARRIER,carrier);
1139 
1140  T *s = _t_new(say,STREAM_READ,0,0);
1141  _t_new_cptr(s,EDGE_STREAM,st);
1142  _t_new(s,RESULT_SYMBOL,&result_symbol,sizeof(Symbol));
1143 
1144  T *run_tree = __p_build_run_tree(code,0);
1145  _t_free(code);
1146  _p_addrt2q(r->q,run_tree);
1147 }
1148 
1149 void _r_addWriter(Receptor *r,Stream *st,Aspect aspect) {
1150 
1151  T *expect = _t_new_root(PATTERN);
1152 
1153  char *stx = "/<LINE:LINE>";
1154 
1155  // @fixme for some reason parseSemtrex doesn't clean up after itself
1156  // valgrind reveals that some of the state in the FSA that match the
1157  // semtrex are left un freed. So I'm doing this one manually below.
1158  /* T *t = parseSemtrex(&r->defs,stx); */
1159  /* _t_add(expect,t); */
1160 
1161  // T *t =_t_news(expect,SEMTREX_GROUP,NULL_SYMBOL);
1162  T *t =_t_newr(expect,SEMTREX_SYMBOL_ANY);
1163  // _t_news(x,SEMTREX_SYMBOL,LINE);
1164 
1165  /* char buf[1000]; */
1166  /* _dump_semtrex(r->sem,t,buf); */
1167  /* puts(buf); */
1168 
1169  T* params = _t_new_root(PARAMS);
1170  _t_new_cptr(params,EDGE_STREAM,st);
1171  T* s = _t_newr(params,SLOT);
1172  _t_news(s,USAGE,NULL_SYMBOL);
1173 
1174  Symbol echo2stream;
1175  _sem_get_by_label(G_sem,"echo2stream",&echo2stream);
1176 
1177  T *act = _t_newp(0,ACTION,echo2stream);
1178 
1179  _r_add_expectation(r,aspect,NULL_SYMBOL,expect,act,params,0,NULL,NULL);
1180 
1181 }
1182 
1183 void _r_defineClockReceptor(SemTable *sem) {
1184  Context clk_ctx = _d_get_receptor_context(sem,CLOCK_RECEPTOR);
1185  T *resp = _t_new_root(RESPOND);
1186  int p[] = {SignalMessageIdx,MessageHeadIdx,HeadCarrierIdx,TREE_PATH_TERMINATOR};
1187  _t_new(resp,SIGNAL_REF,p,sizeof(int)*4);
1188 
1189  Xaddr x = {TICK,1};
1190  T *g = _t_newr(resp,GET);
1191  _t_new(g,WHICH_XADDR,&x,sizeof(Xaddr));
1192  T *signature = __p_make_signature("result",SIGNATURE_SYMBOL,NULL_SYMBOL,NULL);
1193  Process proc = _d_define_process(sem,resp,"respond with current time","long desc...",signature,NULL,clk_ctx);
1194  T *act = _t_newp(0,ACTION,proc);
1195  T *pattern = _t_new_root(PATTERN);
1196  T *s = _sl(pattern,CLOCK_TELL_TIME);
1197 
1198  T *req_act = _t_newp(0,ACTION,time_request);
1199 
1200  T *def = _o_make_protocol_def(sem,clk_ctx,"time",
1201  ROLE,TIME_TELLER,
1202  ROLE,TIME_HEARER,
1203  GOAL,RESPONSE_HANDLER,
1204  INTERACTION,tell_time,
1205  INITIATE,TIME_HEARER,TIME_TELLER,req_act,
1206  EXPECT,TIME_TELLER,TIME_HEARER,pattern,act,NULL_SYMBOL,
1207  NULL_SYMBOL
1208  );
1209  Protocol tt = _d_define_protocol(sem,def,clk_ctx);
1210 
1211 }
1212 
1213 Receptor *_r_makeClockReceptor(SemTable *sem) {
1214  Receptor *r = _r_new(sem,CLOCK_RECEPTOR);
1215 
1216  // add the expectation in explicitly because we haven't yet defined the clock protocol
1217  T *expect = _t_new_root(PATTERN);
1218  T *s = _sl(expect,CLOCK_TELL_TIME);
1219 
1220  T *tick = __r_make_tick(); // initial tick, will get updated by clock thread.
1221  Xaddr x = _r_new_instance(r,tick);
1222 
1223  Protocol time;
1224  __sem_get_by_label(sem,"time",&time,r->context);
1225  _o_express_role(r,time,TIME_TELLER,DEFAULT_ASPECT,NULL);
1226 
1227 
1228  /* Process proc;
1229  __sem_get_by_label(sem,"respond with current time",&proc,r->context); */
1230 
1231  /* T *act = _t_newp(0,ACTION,proc); */
1232  /* T *params = _t_new_root(PARAMS); */
1233  /* _r_add_expectation(r,DEFAULT_ASPECT,CLOCK_TELL_TIME,expect,act,params,0,NULL,NULL); */
1234 
1235  return r;
1236 }
1237 
1250 void *___clock_thread(void *arg){
1251  Receptor *r = (Receptor*)arg;
1252  debug(D_CLOCK,"clock started\n");
1253  int err =0;
1254  ReceptorAddress self = __r_get_self_address(r);
1255  while (r->state == Alive) {
1256  T *tick =__r_make_tick();
1257  debug(D_CLOCK,"%s\n",_td(r,tick));
1258  Xaddr x = {TICK,1};
1259  _r_set_instance(r,x,tick);
1260  // T *signal = __r_make_signal(self,self,DEFAULT_ASPECT,TICK,tick,0,0,0);
1261  // _r_deliver(r,signal);
1262  sleep(1);
1264  // with nano-sleep so that we get every second?
1265  }
1266  debug(D_CLOCK,"clock stopped\n");
1267  pthread_exit(&err); //@todo determine if we should use pthread_exit or just return 0
1268  return 0;
1269 }
1270 
1271 T * __r_make_timestamp(Symbol s,int delta) {
1272  struct tm t;
1273  time_t clock;
1274  time(&clock);
1275  clock += delta;
1276  gmtime_r(&clock, &t);
1277  T *tick = _t_new_root(s);
1278  T *today = _t_newr(tick,TODAY);
1279  T *now = _t_newr(tick,NOW);
1280  _t_newi(today,YEAR,t.tm_year+1900);
1281  _t_newi(today,MONTH,t.tm_mon+1);
1282  _t_newi(today,DAY,t.tm_mday);
1283  _t_newi(now,HOUR,t.tm_hour);
1284  _t_newi(now,MINUTE,t.tm_min);
1285  _t_newi(now,SECOND,t.tm_sec);
1286  return tick;
1287 }
1288 
1289 void __r_kill(Receptor *r) {
1290  r->state = Dead;
1291  /* pthread_mutex_lock(&shutdownMutex); */
1292  /* G_shutdown = val; */
1293  /* pthread_mutex_unlock(&shutdownMutex); */
1294 }
1295 
1296 ReceptorAddress __r_get_self_address(Receptor *r) {
1297  return r->addr;
1298 }
1299 
1300 void __r_dump_instances(Receptor *r) {
1301  printf("\nINSTANCES:%s\n",_t2s(r->sem,r->instances));
1302 }
T * _t_new_root(Symbol symbol)
Definition: tree.c:160
Receptor * r
back-pointer to receptor in which this Q is running (for defs and more)
Definition: ceptr_types.h:207
T * edge
data store for edge receptors
Definition: ceptr_types.h:252
char * _sem_get_name(SemTable *sem, SemanticID s)
Definition: semtable.c:85
Definition: ceptr_types.h:114
void _st_close_listener(SocketListener *l)
Definition: stream.c:444
int state
state information about the receptor that the vmhost manages
Definition: ceptr_types.h:251
Structure __r_get_symbol_structure(Receptor *r, Symbol s)
find a symbol's structure
Definition: receptor.c:299
void _r_serialize(Receptor *r, void **surfaceP, size_t *lengthP)
Definition: receptor.c:432
Process _d_define_process(SemTable *sem, T *code, char *name, char *intention, T *signature, T *link, Context c)
Definition: def.c:336
Definition: stream.h:30
H _m_unserialize(S *s)
Definition: mtree.c:743
Definition: ceptr_types.h:206
T * __t_newi(T *parent, Symbol symbol, int surface, bool is_run_node)
Definition: tree.c:97
T * _t_get(T *t, int *p)
Definition: tree.c:1441
Context parent
the context this receptor's definition lives in
Definition: ceptr_types.h:239
T * _t_detach_by_idx(T *t, int i)
Definition: tree.c:278
void _p_freeq(Q *q)
Definition: process.c:2055
void __r_test_expectation(Receptor *r, T *expectation, T *signal)
Definition: receptor.c:656
S * _m_serialize(M *m)
Definition: mtree.c:645
Semantic tree regular expression header file.
void _p_wakeup(Q *q, T *wakeup, T *with, Error err)
Definition: process.c:1458
TreeHash _t_hash(SemTable *sem, T *t)
Definition: tree.c:1614
T * __p_build_wakeup_info(T *code_point, int process_id)
Definition: process.c:1931
Definition: ceptr_types.h:68
T * _t_clone(T *t)
Definition: tree.c:589
void _r_free(Receptor *r)
Definition: receptor.c:186
T * __t_newr(T *parent, Symbol symbol, bool is_run_node)
Definition: tree.c:171
Symbol _t_symbol(T *t)
Definition: tree.c:1228
T * _t_child(T *t, int i)
Definition: tree.c:1251
Receptor * __r_get_receptor(T *installed_receptor)
Definition: receptor.c:1039
protocol helpers header file
T * _t_newp(T *parent, Symbol symbol, Process surface)
Definition: tree.c:251
TreeHash _r_hash(Receptor *r, Xaddr t)
Definition: receptor.c:414
Receptor * _r_new_receptor_from_package(SemTable *sem, Symbol s, T *p, T *bindings)
Creates a new receptor from a receptor package.
Definition: receptor.c:114
streams abstraction header file
T * _d_build_def_semtrex(SemTable *sem, Symbol s, T *parent)
Definition: def.c:433
Context context
the context this receptor's definition creates
Definition: ceptr_types.h:240
Structure _d_define_structure(SemTable *sem, char *label, T *structure_def, Context c)
Definition: def.c:104
ReceptorAddress addr
the address by which to get messages to this receptor instance
Definition: ceptr_types.h:241
Instances instances
the instances store
Definition: ceptr_types.h:249
receptor implementation header file
Structure _r_define_structure(Receptor *r, char *label, int num_params,...)
Definition: receptor.c:236
void _r_add_expectation(Receptor *r, Aspect aspect, Symbol carrier, T *pattern, T *action, T *with, T *until, T *using, T *cid)
Adds an expectation to a receptor's aspect.
Definition: receptor.c:164
size_t _d_get_symbol_size(SemTable *sem, Symbol s, void *surface)
Definition: def.c:178
Q * q
process queue
Definition: ceptr_types.h:250
int _t_match(T *semtrex, T *t)
Definition: semtrex.c:809
void * _t_surface(T *t)
Definition: tree.c:1215
Structure __r_define_structure(Receptor *r, char *label, T *structure_def)
Definition: receptor.c:258
T * flux
pointer for quick access to the flux
Definition: ceptr_types.h:243
size_t __r_get_structure_size(Receptor *r, Structure s, void *surface)
Definition: receptor.c:307
Receptor * _r_new(SemTable *sem, SemanticID r)
Creates a new receptor.
Definition: receptor.c:88
size_t _d_get_structure_size(SemTable *sem, Structure s, void *surface)
Definition: def.c:218
Receptor * _r_unserialize(SemTable *sem, void *surface)
Definition: receptor.c:459
T * _t_newt(T *parent, Symbol symbol, T *surface)
Definition: tree.c:133
T * _r_send(Receptor *r, T *signal)
Definition: receptor.c:556
Symbol _r_get_sem_by_label(Receptor *r, char *label)
Definition: receptor.c:288
SState * state(StateType type, int *statesP, int level)
Definition: semtrex.c:103
T * _t_parent(T *t)
Definition: tree.c:1262
processing header files
Symbol _d_define_symbol(SemTable *sem, Structure s, char *label, Context c)
Definition: def.c:83
T * _t_new_from_m(H h)
Definition: mtree.c:250
int _t_matchr(T *semtrex, T *t, T **rP)
Definition: semtrex.c:798
Qe * __p_addrt2q(Q *q, T *run_tree, T *sem_map)
Definition: process.c:2068
T * __r_make_signal(ReceptorAddress from, ReceptorAddress to, Aspect aspect, Symbol carrier, T *signal_contents, UUIDt *in_response_to, T *until, T *cid)
Definition: receptor.c:515
T * _r_build_def_semtrex(Receptor *r, Symbol s)
Definition: receptor.c:325
T * __t_find(T *t, SemanticID sym, int start_child)
Definition: tree.c:1328
void _p_fill_from_match(SemTable *sem, T *t, T *match_results, T *match_tree)
Definition: process.c:76
T * root
RECEPTOR_INSTANCE semantic tree.
Definition: ceptr_types.h:238
SemTable * sem
pointer back to the genotype table for this receptor's vmhost instance
Definition: ceptr_types.h:242
H _m_new_from_t(T *t)
Definition: mtree.c:206
size_t __r_get_symbol_size(Receptor *r, Symbol s, void *surface)
Definition: receptor.c:314
void _o_express_role(Receptor *r, Protocol protocol, Symbol role, Aspect aspect, T *bindings)
Definition: protocol.c:409
T * _r_get_instance(Receptor *r, Xaddr x)
Definition: receptor.c:379
Q * _p_newq(Receptor *r)
Definition: process.c:2015
Definition: ceptr_types.h:83
void * ___clock_thread(void *arg)
Definition: receptor.c:1250
#define _sl(t, s)
macro to add a single symbol literal to semtrex tree
Definition: semtrex.h:122
semantic tree matrix header file ``
Protocol _d_define_protocol(SemTable *sem, T *def, Context c)
Definition: def.c:357
void _t_add(T *t, T *c)
Definition: tree.c:261
Symbol _r_define_symbol(Receptor *r, Structure s, char *label)
Definition: receptor.c:218
Error _r_deliver(Receptor *r, T *signal)
Definition: receptor.c:954
int _t_children(T *t)
Definition: tree.c:1205
header file for the accumulator
T * _r_set_instance(Receptor *r, Xaddr x, T *t)
Definition: receptor.c:394
T * _o_make_protocol_def(SemTable *sem, Context c, char *label,...)
Definition: protocol.c:37
Process _r_define_process(Receptor *r, T *code, char *name, char *intention, T *signature, T *link)
Definition: receptor.c:275
void _t_detach_by_ptr(T *t, T *c)
Definition: tree.c:291
void _t_free(T *t)
Definition: tree.c:526
T * _r_delete_instance(Receptor *r, Xaddr x)
Definition: receptor.c:407
T * _r_request(Receptor *r, T *signal, Symbol response_carrier, T *code_point, int process_id, T *cid)
Definition: receptor.c:575
T * _t_getv(T *t,...)
Definition: tree.c:1470
T * _p_make_run_tree(SemTable *sem, Process p, T *params, T *sem_map)
Definition: process.c:1974
T * _t_new_cptr(T *parent, Symbol symbol, void *s)
Definition: tree.c:239
int _r_def_match(Receptor *r, Symbol s, T *t)
Definition: receptor.c:343
Xaddr _r_new_instance(Receptor *r, T *t)
Definition: receptor.c:365
SocketListener * _st_new_socket_listener(int port, lisenterConnectionCallbackFn fn, void *callback_arg, char *delim)
Definition: stream.c:372