c_iter v_serviceTakeNewGroups( v_service service) { c_iter result; v_group group; c_set newGroups; assert(service != NULL); assert(C_TYPECHECK(service, v_service)); result = c_iterNew(NULL); v_observerLock(v_observer(service)); newGroups = (c_set)v_observer(service)->eventData; if (newGroups != NULL) { group = v_group(c_take(newGroups)); while (group != NULL) { c_iterInsert(result, group); group = v_group(c_take(newGroups)); } } v_observerUnlock(v_observer(service)); return result; }
c_iter v_serviceTakeNewGroups( v_service service) { c_iter result; v_group group; c_set newGroups; assert(service != NULL); assert(C_TYPECHECK(service, v_service)); result = c_iterNew(NULL); OSPL_BLOCK_EVENTS(service); newGroups = service->newGroups; if (newGroups != NULL) { group = v_group(c_take(newGroups)); while (group != NULL) { c_iterInsert(result, group); group = v_group(c_take(newGroups)); } } OSPL_UNBLOCK_EVENTS(service); return result; }
void v_participantDeleteHistoricalData( v_participant participant, const c_char* partitionExpr, const c_char* topicExpr) { c_iter matchingGroups; v_group group; c_time t; c_value params[2]; C_STRUCT(v_event) event; C_STRUCT(v_historyDeleteEventData) hde; assert(participant != NULL); assert(C_TYPECHECK(participant, v_participant)); assert(partitionExpr); assert(topicExpr); if(partitionExpr && topicExpr){ params[0] = c_stringValue((c_string)partitionExpr); params[1] = c_stringValue((c_string)topicExpr); c_lockRead(&participant->lock); t = v_timeGet(); matchingGroups = v_groupSetSelect( v_objectKernel(participant)->groupSet, "partition.name like %0 AND topic.name like %1", params); c_lockUnlock(&participant->lock); group = v_group(c_iterTakeFirst(matchingGroups)); while(group){ v_groupDeleteHistoricalData(group, t); c_free(group); group = v_group(c_iterTakeFirst(matchingGroups)); } c_iterFree(matchingGroups); hde.partitionExpression = (c_char *)partitionExpr; hde.topicExpression = (c_char *)topicExpr; hde.deleteTime = t; event.kind = V_EVENT_HISTORY_DELETE; event.source = v_publicHandle(v_public(participant)); event.userData = &hde; v_observableNotify(v_observable(v_objectKernel(participant)),&event); } return; }
static c_bool getHistoricalData( c_object o, c_voidp arg) { v_entry entry; c_iter proxies; v_proxy proxy; v_group group; assert(o != NULL); entry = v_entry(o); assert(entry != NULL); assert(C_TYPECHECK(entry,v_entry)); proxies = c_select(entry->groups, 0); proxy = c_iterTakeFirst(proxies); while (proxy != NULL) { group = v_group(v_proxyClaim(proxy)); if (group) { if(arg == NULL){ v_groupGetHistoricalData(group, entry); } else { v_groupGetHistoricalDataWithCondition(group, entry, (v_historicalDataRequest)arg); } v_proxyRelease(proxy); } c_free(proxy); proxy = c_iterTakeFirst(proxies); } c_iterFree(proxies); return TRUE; }
c_bool v_networkReaderWrite( v_networkReader reader, v_message message, v_networkReaderEntry entry, c_ulong sequenceNumber, v_gid sender, c_bool sendTo, /* for p2p writing */ v_gid receiver) { c_bool result; v_networkQueue bestQueue; assert(reader != NULL); assert(C_TYPECHECK(reader, v_networkReader)); assert(reader->remoteActivity == TRUE); /* First select the best queue */ if (message != NULL) { bestQueue = v_networkReaderSelectBestQueue( reader, message->qos, sendTo, v_partitionName(v_group(entry->group)->partition), v_topicName(v_groupTopic(entry->group))); } else { bestQueue = reader->defaultQueue; } result = v_networkQueueWrite(bestQueue, message, entry, sequenceNumber, sender, sendTo, receiver); return result; }
void v_entryFree( v_entry entry) { c_iter proxies; v_proxy proxy; v_group group; assert(C_TYPECHECK(entry,v_entry)); proxies = c_select(entry->groups, 0); proxy = c_iterTakeFirst(proxies); while (proxy != NULL) { group = v_group(v_proxyClaim(proxy)); if (group) { v_groupRemoveEntry(group, entry); v_proxyRelease(proxy); } c_free(proxy); proxy = c_iterTakeFirst(proxies); } c_iterFree(proxies); /* No parent to call Free on */ }
void v_publicDispose( v_public o) { assert(C_TYPECHECK(o,v_public)); if (o == NULL) { return; } switch(v_objectKind(o)) { case K_PARTICIPANT: v_participantDeinit(v_participant(o)); break; case K_PUBLISHER: v_publisherDeinit(v_publisher(o)); break; case K_SUBSCRIBER: v_subscriberDeinit(v_subscriber(o)); break; case K_WRITER: v_writerDeinit(v_writer(o)); break; case K_DATAREADER: v_dataReaderDeinit(v_dataReader(o)); break; case K_DELIVERYSERVICE:v_deliveryServiceDeinit(v_deliveryService(o)); break; case K_NETWORKREADER: v_networkReaderDeinit(v_networkReader(o)); break; case K_READER: v_readerDeinit(v_reader(o)); break; case K_GROUPQUEUE: v_groupQueueDeinit(v_groupQueue(o)); break; case K_TOPIC: v_topicDeinit(v_topic(o)); break; case K_ENTITY: break; case K_DOMAIN: v_partitionDeinit(v_partition(o)); break; case K_GROUP: v_groupDeinit(v_group(o)); break; case K_SERVICEMANAGER: /* Is never freed! */ break; case K_SPLICED: v_splicedDeinit(v_spliced(o)); break; case K_NETWORKING: case K_DURABILITY: case K_CMSOAP: case K_SERVICE: v_serviceDeinit(v_service(o)); break; case K_SERVICESTATE: /* Is never freed! */ break; case K_CONFIGURATION: break; case K_QUERY: OS_REPORT(OS_ERROR, "v_publicDispose failure", 0, "deinit of abstract class K_QUERY"); break; case K_DATAREADERQUERY: v_dataReaderQueryDeinit(v_dataReaderQuery(o)); break; case K_DATAVIEWQUERY: v_dataViewQueryDeinit(v_dataViewQuery(o)); break; case K_DATAVIEW: v_dataViewDeinit(v_dataView(o)); break; case K_WAITSET: v_waitsetDeinit(v_waitset(o)); break; case K_WRITERINSTANCE: v_writerInstanceDeinit(v_writerInstance(o)); break; case K_DATAREADERINSTANCE: v_dataReaderInstanceDeinit(v_dataReaderInstance(o)); break; case K_DATAVIEWINSTANCE: v_dataViewInstanceDeinit(v_dataViewInstance(o)); break; default: OS_REPORT_1(OS_ERROR,"v_publicDispose failed",0, "illegal entity kind (%d) specified",v_objectKind(o)); assert(FALSE); break; } c_free(o); }
void v_serviceFillNewGroups( v_service service) { c_set newGroups; C_STRUCT(v_event) ge; v_group g; v_kernel kernel; c_iter groups = NULL; assert(service != NULL); assert(C_TYPECHECK(service, v_service)); kernel = v_objectKernel(service); newGroups = (c_voidp)c_setNew(v_kernelType(kernel, K_GROUP)); if (newGroups != NULL) { groups = v_groupSetSelectAll(kernel->groupSet); /* Take the first group and at the end notify the service about this new group. * But before push all other groups to the servive newGroup set so that only one trigger * is required to notify all groups. * The first group is automatically added to the newGroup set by the notification. * TODO : get rid of this mechanism. */ ge.data = v_group(c_iterTakeFirst(groups)); if (ge.data) { ge.kind = V_EVENT_NEW_GROUP; ge.source = v_observable(kernel); ospl_c_insert(newGroups, ge.data); while ((g = v_group(c_iterTakeFirst(groups))) != NULL) { ospl_c_insert(newGroups, g); c_free(g); } OSPL_BLOCK_EVENTS(service); c_free(service->newGroups); service->newGroups = (c_voidp)newGroups; OSPL_UNBLOCK_EVENTS(service); OSPL_TRIGGER_EVENT((service), &ge, NULL); } c_iterFree(groups); } }
void v_serviceFillNewGroups( v_service service) { c_set newGroups; C_STRUCT(v_event) ge; v_group g, oldGroup; c_iter oldGroups; v_kernel kernel; assert(service != NULL); assert(C_TYPECHECK(service, v_service)); kernel = v_objectKernel(service); newGroups = (c_voidp)c_setNew(v_kernelType(kernel, K_GROUP)); if (newGroups != NULL) { addAllGroups(newGroups, kernel->groupSet); v_observerLock(v_observer(service)); g = v_group(c_read(newGroups)); /* need a group for the event */ if(v_observer(service)->eventData != NULL){ oldGroups = ospl_c_select((c_set)v_observer(service)->eventData, 0); oldGroup = v_group(c_iterTakeFirst(oldGroups)); while(oldGroup){ newGroups = c_setInsert(newGroups, oldGroup); c_free(oldGroup); oldGroup = v_group(c_iterTakeFirst(oldGroups)); } c_iterFree(oldGroups); } /* just for safety, when assertion are compiled out, free the prev set */ c_free((c_object)v_observer(service)->eventData); v_observer(service)->eventData = (c_voidp)newGroups; ge.kind = V_EVENT_NEW_GROUP; ge.source = v_publicHandle(v_public(kernel)); ge.userData = g; v_observerNotify(v_observer(service), &ge, NULL); v_observerUnlock(v_observer(service)); c_free(g); } }
static void setKernelGroup( v_entity entity, c_voidp args) { d_group group; group = d_group(args); d_groupSetKernelGroup(group,v_group(entity)); }
static void addAllGroups( c_set newGroups, v_groupSet groupSet) { c_iter groups = NULL; v_group g; assert(C_TYPECHECK(groupSet, v_groupSet)); groups = v_groupSetSelectAll(groupSet); g = v_group(c_iterTakeFirst(groups)); while (g != NULL) { c_insert(newGroups, g); c_free(g); g = v_group(c_iterTakeFirst(groups)); } c_iterFree(groups); }
static void cms_serviceActionGroups( v_entity e, c_voidp args) { v_service s; c_iter groups; v_group group; OS_UNUSED_ARG(args); s = v_service(e); groups = v_serviceTakeNewGroups(s); group = v_group(c_iterTakeFirst(groups)); while(group != NULL) { c_free(group); group = v_group(c_iterTakeFirst(groups)); } c_iterFree(groups); }
void v_networkReaderEntryNotifyConnected( v_networkReaderEntry entry, const c_char* serviceName) { c_bool allChannelsConnected = FALSE; c_mutexLock(&entry->channelCountdownMutex); assert (entry->channelCountdown > 0); entry->channelCountdown--; if (entry->channelCountdown == 0) { allChannelsConnected = TRUE; } c_mutexUnlock(&entry->channelCountdownMutex); if (allChannelsConnected) { v_groupAddEntry(v_group(entry->group), v_entry(entry)); v_groupNotifyAwareness(v_group(entry->group),serviceName,TRUE); v_groupGetHistoricalData(v_group(entry->group), v_entry(entry)); } }
void v_groupStreamDeinit( v_groupStream stream) { c_iter groups; v_group group; assert(C_TYPECHECK(stream, v_groupStream)); v_readerDeinit(v_reader(stream)); groups = ospl_c_select(stream->groups, 0); group = v_group(c_iterTakeFirst(groups)); while(group){ v_groupRemoveStream(group, stream); c_free(group); group = v_group(c_iterTakeFirst(groups)); } c_iterFree(groups); c_free(stream->groups); stream->groups = NULL; }
static c_bool v_networkReaderEntryUnSubscribeGroup( v_networkReaderEntry entry, v_group group) { assert(C_TYPECHECK(entry, v_networkReaderEntry)); assert(C_TYPECHECK(group, v_group)); if (v_group(entry->group) == group) { v_groupRemoveEntry(entry->group, v_entry(entry)); } return TRUE; }
static c_bool v_networkReaderEntryUnSubscribe( v_networkReaderEntry entry, v_partition partition) { assert(C_TYPECHECK(entry, v_networkReaderEntry)); assert(C_TYPECHECK(partition, v_partition)); if (v_group(entry->group)->partition == partition) { v_groupRemoveEntry(entry->group, v_entry(entry)); } return TRUE; }
void v_participantNotify( v_participant _this, v_event event, c_voidp userData) { /* This Notify method is part of the observer-observable pattern. * It is designed to be invoked when _this object as observer receives * an event from an observable object. * It must be possible to pass the event to the subclass of itself by * calling <subclass>Notify(_this, event, userData). * This implies that _this as observer cannot be locked within any * Notify method to avoid deadlocks. * For consistency _this must be locked by v_observerLock(_this) before * calling this method. */ assert(_this != NULL); assert(C_TYPECHECK(_this,v_participant)); if (event) { switch (event->kind) { case V_EVENT_NEW_GROUP: assert(event->userData); c_mutexLock(&_this->newGroupListMutex); c_listInsert(_this->newGroupList,v_group(event->userData)); c_mutexUnlock(&_this->newGroupListMutex); break; case V_EVENT_LIVELINESS_ASSERT: c_lockWrite(&_this->lock); c_walk(_this->entities, assertLivelinessPublisher, event); c_lockUnlock(&_this->lock); break; case V_EVENT_SERVICESTATE_CHANGED: case V_EVENT_DATA_AVAILABLE: case V_EVENT_HISTORY_DELETE: case V_EVENT_HISTORY_REQUEST: case V_EVENT_PERSISTENT_SNAPSHOT: /*Do nothing here.*/ break; default: OS_REPORT_1(OS_WARNING,"v_participantNotify",0, "Notify encountered unknown event kind (%d)", event->kind); break; } } }
/************************************************************** * Protected functions **************************************************************/ void v_serviceNotify( v_service service, v_event event, c_voidp userData) { v_group group; assert(service != NULL); assert(C_TYPECHECK(service, v_service)); if (event != NULL) { switch (event->kind) { case V_EVENT_SERVICESTATE_CHANGED: break; case V_EVENT_NEW_GROUP: group = v_group(event->userData); if ((group != NULL) && (v_observer(service)->eventData != NULL)) { /* Update new group admin */ c_insert((c_set)v_observer(service)->eventData, group); } /* This allows receiving the event by means of a waitset.*/ v_observableNotify(v_observable(service), event); break; case V_EVENT_HISTORY_DELETE: /* This allows receiving the event by means of a waitset.*/ v_observableNotify(v_observable(service), event); break; case V_EVENT_HISTORY_REQUEST: /* This allows receiving the event by means of a waitset.*/ v_observableNotify(v_observable(service), event); break; case V_EVENT_CONNECT_WRITER: case V_EVENT_PERSISTENT_SNAPSHOT: /* This allows receiving the event by means of a waitset.*/ v_observableNotify(v_observable(service), event); break; default: break; } } v_participantNotify(v_participant(service), event, userData); }
v_networkReaderEntry v_networkReaderLookupEntry( v_networkReader reader, v_group group) { struct v_findEntryArg findEntryArg; assert(v_networkReader(reader) == reader); assert(v_group(group) == group); findEntryArg.group = c_keep(group); findEntryArg.found = NULL; v_readerWalkEntries(v_reader(reader), (c_action)v_networkReaderFindEntry, &findEntryArg); c_free(group); /* Note that the keep has been done in the walk (if any entry was found) */ return findEntryArg.found; }
static c_bool waitForHistoricalData( c_object o, c_voidp arg) { v_entry entry; c_iter proxies; v_proxy proxy; v_group group; c_time waitTime; struct historicalWaitArg *parms = (struct historicalWaitArg *)arg; assert(o != NULL); assert(arg != NULL); entry = v_entry(o); assert(entry != NULL); assert(C_TYPECHECK(entry,v_entry)); proxies = c_select(entry->groups, 0); proxy = c_iterTakeFirst(proxies); while ((proxy != NULL) && (parms->_status == TRUE)) { group = v_group(v_proxyClaim(proxy)); if (group) { if (group->complete == FALSE) { waitTime = c_timeSub(parms->_expire_time, v_timeGet()); if (c_timeCompare(waitTime, C_TIME_ZERO) == C_GT) { parms->_status = v_groupWaitForComplete(group, waitTime); } else { parms->_status = FALSE; /* time out */ } } v_proxyRelease(proxy); } c_free(proxy); proxy = c_iterTakeFirst(proxies); } c_iterFree(proxies); return parms->_status; }
static c_type onTypeLookup( v_networkHashValue hashValue, const c_char *partitionName, const c_char *topicName, nw_typeLookupArg arg) { c_type result = NULL; nw_lookupArg lookupArg = (nw_lookupArg)arg; nw_receiveChannel receiveChannel = lookupArg->receiveChannel; v_networkReaderEntry entry; NW_CONFIDENCE(receiveChannel != NULL); #ifdef NW_LOOPBACK if (nw_configurationUseComplementPartitions()) { entry = nw_entryHashLookupByNamesOnly(receiveChannel->hash, partitionName, topicName); } else { entry = nw_entryHashLookup(receiveChannel->hash, hashValue, partitionName, topicName); } #else entry = nw_entryHashLookup(receiveChannel->hash, hashValue, partitionName, topicName); #endif if ((entry == NULL) && (lookupArg->entryLookupAction != NULL)) { entry = lookupArg->entryLookupAction(hashValue, partitionName, topicName, lookupArg->entryLookupArg); } lookupArg->entryFound = entry; if (entry != NULL) { result = v_topicMessageType(v_group(entry->group)->topic); } return result; }
void v_groupStreamNotify( v_groupStream stream, v_event e, c_voidp userData) { struct groupConnected data; c_iter partitions; c_bool interested; v_partition partition, found; OS_UNUSED_ARG(userData); assert(stream != NULL); assert(C_TYPECHECK(stream,v_groupStream)); if (e) { if (e->kind == V_EVENT_NEW_GROUP) { v_observerLock(v_observer(stream)); /* * Check if group fits interest. This extra steps are needed because * the groupActionStream does not create the groups that match the * subscriber qos partition expression on creation. It only needs to * connect to new groups once they are created. This is a different * approach then for a data reader. */ partition = v_group(e->userData)->partition; /* * Because already existing partitions are created and added to the * subscriber of the groupActionStream at creation time, these * partitions can be resolved from the subscriber. This is necessary to * determine whether the groupActionStream should connect to the new * group or if it is already connected. */ partitions = v_subscriberLookupPartitions(v_reader(stream)->subscriber, v_partitionName(partition)); interested = FALSE; found = v_partition(c_iterTakeFirst(partitions)); while(found){ if(interested == FALSE){ if(strcmp(v_partitionName(partition), v_partitionName(found)) == 0){ interested = TRUE; } } c_free(found); found = v_partition(c_iterTakeFirst(partitions)); } c_iterFree(partitions); if(interested == TRUE){ /* * This means the group is interesting for this * groupActionStream. Now I have to check if the stream is already * connected to this group, because we wouldn't want to connect * multiple times to one single group. */ data.connected = FALSE; data.group = v_group(e->userData); c_walk(stream->groups, (c_action)isGroupConnected, &data); if(data.connected == FALSE){ /* * The stream is not connected to the group yet, so connect now. */ v_groupStreamSubscribeGroup(stream, v_group(e->userData)); } } v_observerUnlock(v_observer(stream)); } } return; }