const ActorClass *getReceiverClass(int tokenSize, tokenFn *functions) { ensureInitialized(); //Detect need for serialization with if such function is provided int needSerialization = functions->serialize != NULL; /* * Linear search should be fine: this list is likely to be small, and * this is only done during network construction time, not at runtime. */ dllist_element_t *elem = dllist_first(&receiver_classes); while (elem) { struct extended_class *xclass = (struct extended_class *) elem; if(needSerialization) { //If we already have a class pointing to the same serialization function take it if (xclass->portDescription.functions->serialize == functions->serialize) { return &xclass->actorClass; } } else { if (xclass->portDescription.tokenSize == tokenSize) { return &xclass->actorClass; } } elem = dllist_next(&receiver_classes, elem); } /* no class found -- we need to create one */ struct extended_class *xclass = calloc(1, sizeof(struct extended_class)); /* make up a name */ if(needSerialization) snprintf(xclass->className, GENERATED_CLASS_NAME_MAX, "_receiver_%dB%8p", tokenSize, functions->serialize); else snprintf(xclass->className, GENERATED_CLASS_NAME_MAX, "_receiver_%dB", tokenSize); xclass->portDescription.name = "out"; xclass->portDescription.tokenSize = tokenSize; if(needSerialization) { xclass->portDescription.functions = calloc(1,sizeof(tokenFn)); memcpy(xclass->portDescription.functions, functions, sizeof(tokenFn)); } xclass->actorClass.majorVersion = ACTORS_RTS_MAJOR; xclass->actorClass.minorVersion = ACTORS_RTS_MINOR; xclass->actorClass.name = xclass->className; xclass->actorClass.sizeActorInstance = sizeof(ActorInstance_art_SocketReceiver); xclass->actorClass.numInputPorts = 0; xclass->actorClass.numOutputPorts = 1; xclass->actorClass.outputPortDescriptions = &xclass->portDescription; xclass->actorClass.action_scheduler = &receiver_action_scheduler; xclass->actorClass.constructor = &receiver_constructor; xclass->actorClass.destructor = &receiver_destructor; dllist_append(&receiver_classes, &xclass->elem); return &xclass->actorClass; }
/* Description: */ void dllist_foreach_elem(void **head, void *arg, void *(*func)(void **h, void *elem, void *arg)) { t_dllist *walker = *(t_dllist**)head; t_dllist *it = NULL; while (walker) { if (func) it = func(head, walker, arg); if (it == walker) walker = dllist_next(walker); else walker = it; } }
int getReceiverPort(AbstractActorInstance *pBase) { /* Ensure this is actually an instance of a known receiver class */ int correct_instance_type = 0; dllist_element_t *elem = dllist_first(&receiver_classes); while (elem) { struct extended_class *xclass = (struct extended_class *) elem; if (pBase->actorClass == &xclass->actorClass) { correct_instance_type = 1; } elem = dllist_next(&receiver_classes, elem); } assert(correct_instance_type); return ((ActorInstance_art_SocketReceiver *) pBase)->port; }
void setSenderRemoteAddress(AbstractActorInstance *pBase, const char *host, int port) { /* Ensure this is actually an instance of a known sender class */ int correct_instance_type = 0; dllist_element_t *elem = dllist_first(&sender_classes); while (elem) { struct extended_class *xclass = (struct extended_class *) elem; if (pBase->actorClass == &xclass->actorClass) { correct_instance_type = 1; } elem = dllist_next(&sender_classes, elem); } assert(correct_instance_type); ActorInstance_art_SocketSender * instance = (ActorInstance_art_SocketSender *) pBase; instance->remoteHost = strdup(host); instance->remotePort = port; }