c_bool v_groupStreamSubscribeGroup( v_groupStream stream, v_group group) { c_bool inserted; assert(C_TYPECHECK(stream, v_groupStream)); assert(C_TYPECHECK(group, v_group)); if (v_reader(stream)->qos->durability.kind == v_topicQosRef(group->topic)->durability.kind) { struct groupMatched data; /* * OSPL-1073: Check if the new group matches with the group-expression list. This * is a collection of partition.topic strings that allows users to connect to specific * topics rather than connecting to all topics within a partition. */ if(stream->expr) { data.matched = FALSE; data.group = group; c_walk(stream->expr, (c_action)isGroupMatched, &data); }else { data.matched = TRUE; } if(data.matched) { inserted = v_groupAddStream(group, stream); if(inserted == TRUE){ c_insert(stream->groups, group); } } } return TRUE; }
static c_bool d_storeMMFKernelWalkGroups( d_storeMMFKernel _this, d_nameSpace matchingNameSpace, c_action action, c_voidp actionArg) { groupWalkArg walkArg; c_bool result; if (matchingNameSpace == NULL){ result = c_walk(_this->groups, action, actionArg); } else { walkArg.matchingNameSpace = matchingNameSpace; walkArg.action = action; walkArg.actionArg = actionArg; result = c_walk(_this->groups, groupWalkMatchingAction, &walkArg); } return result; }
c_iter v_cfElementGetChildren( v_cfElement element) { c_iter i = NULL; assert(C_TYPECHECK(element, v_cfElement)); c_walk(element->children, childsToIterator, &i); return i; }
c_iter v_cfElementGetAttributes( v_cfElement element) { c_iter i = NULL; assert(C_TYPECHECK(element, v_cfElement)); c_walk(element->attributes, attributesToIterator, &i); return i; }
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; } } }
void v_participantAssertLiveliness( v_participant p) { C_STRUCT(v_event) event; assert(p != NULL); assert(C_TYPECHECK(p,v_participant)); event.kind = V_EVENT_LIVELINESS_ASSERT; event.source = v_publicHandle(v_public(p)); event.userData = NULL; /* Walk over all entities and assert liveliness on all writers */ c_lockWrite(&p->lock); c_walk(p->entities, assertLivelinessPublisher, &event); c_lockUnlock(&p->lock); }
v_cfAttribute v_cfElementAttribute( v_cfElement element, const c_char *attributeName) { struct getAttributeArg arg; assert(C_TYPECHECK(element, v_cfElement)); assert(attributeName != NULL); arg.name = attributeName; arg.attr = NULL; c_walk(element->attributes, getAttribute, &arg); assert(C_TYPECHECK(arg.attr, v_cfAttribute)); return arg.attr; }
void v_participantConnectNewGroup ( v_participant _this, v_event event) { v_group g; c_mutexLock(&_this->newGroupListMutex); g = c_take(_this->newGroupList); while (g) { c_mutexUnlock(&_this->newGroupListMutex); c_lockWrite(&_this->lock); c_walk(_this->entities, connectNewGroup, g); c_lockUnlock(&_this->lock); c_mutexLock(&_this->newGroupListMutex); g = c_take(_this->newGroupList); } c_mutexUnlock(&_this->newGroupListMutex); }
void v_leaseRenew( v_lease lease, v_duration leaseDuration) { c_iter observers = NULL; v_leaseManager observer; if (lease != NULL) { assert(C_TYPECHECK(lease, v_lease)); v_leaseLock(lease); lease->expiryTime = c_timeAdd(v_timeGet(), leaseDuration); lease->duration = leaseDuration; /* Collect all observers, so they can be notified of the lease change * Must do a seperate collect as the lease mutex is 'lower' then the * leaseManager mutex. So to prevent deadlock we can not directly notify * the lease manager as we walk the collection */ if(lease->observers) { c_walk(lease->observers, v_leaseCollectObservers, &observers); } v_leaseUnlock(lease); if(observers) { observer = v_leaseManager(c_iterTakeFirst(observers)); while (observer != NULL) { v_leaseManagerNotify( observer, lease, V_EVENT_LEASE_RENEWED); c_free(observer); observer = v_leaseManager(c_iterTakeFirst(observers)); } c_iterFree(observers); } } }
static c_array copyReaderGIDsFromPublications( v_deliveryGuard _this) { /* copy system Ids from _this->publications */ C_STRUCT(copySystemIdsArg) arg; c_long size; if (_this->publications) { size = c_count(_this->publications); } else { size = 0; } if (size > 0) { arg.readerGID = c_arrayNew(_this->gidType,size); arg.index = 0; c_walk(_this->publications, copySystemIds, &arg); } else { arg.readerGID = NULL; } return arg.readerGID; }
void v_groupStreamConnectNewGroups( v_groupStream stream, v_group group) { struct groupConnected data; assert(stream != NULL); assert(C_TYPECHECK(stream,v_groupStream)); v_observerLock(v_observer(stream)); /* * 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 = group; 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, group); } v_observerUnlock(v_observer(stream)); if(data.connected == FALSE){ v_groupStreamHistoricalData(group, stream); } return; }
v_rnrGroupStatistics v_rnrStorageStatisticsGroup( v_rnrStorageStatistics _this, v_service service, const c_char* name) { v_kernel kernel; struct checkGroupExistsHelper helper; assert(_this); assert(C_TYPECHECK(_this, v_rnrStorageStatistics)); assert(service && name); helper.name = name; helper.stats = NULL; if (c_walk(_this->topics, checkGroupExists, &helper)) { kernel = v_objectKernel(service); helper.stats = v_rnrGroupStatisticsNew(kernel, name); assert(helper.stats); c_tableInsert(_this->topics, helper.stats); } return helper.stats; }
c_iter v_cfElementXPath( v_cfElement element, const c_char *xpathExpr) { c_iter result; const c_char *posInExpr; const c_char *slash; char *attribEnd; c_ulong length; struct getChildrenArg arg; c_long nrToProcess; v_cfNode node; assert(C_TYPECHECK(element, v_cfElement)); assert(xpathExpr != NULL); result = c_iterNew(element); nrToProcess = 1; posInExpr = xpathExpr; slash = strchr(posInExpr, XPATH_SEPERATOR); while (nrToProcess > 0) { node = c_iterTakeFirst(result); nrToProcess--; if (node->kind == V_CFELEMENT) { /* do not process data elements */ if (slash) { length = C_ADDRESS(slash) - C_ADDRESS(posInExpr); } else { length = strlen(posInExpr); } arg.children = c_iterNew(NULL); arg.tagName = (c_char *)os_malloc(length + 1U); os_strncpy(arg.tagName, posInExpr, length); arg.tagName[length] = 0; /* Look for selection criteria based on attribute value * Example XPath expression: * /aaa/bbb[@name='value']/ccc or /aaa/bbb[@name!='value']/ccc */ arg.attribName = strchr(arg.tagName, '['); if (arg.attribName != NULL) { *arg.attribName = '\0'; arg.attribName = &(arg.attribName[1]); assert(*arg.attribName == '@'); arg.attribName = &(arg.attribName[1]); arg.attribValue = strchr(arg.attribName, '!'); if (arg.attribValue != NULL) { arg.attribNegate = TRUE; *arg.attribValue = '\0'; arg.attribValue = &arg.attribValue[1]; assert(*arg.attribValue == '='); } else { arg.attribNegate = FALSE; arg.attribValue = strchr(arg.attribName, '='); } assert(arg.attribValue != NULL); *arg.attribValue = '\0'; arg.attribValue = &arg.attribValue[1]; assert(*arg.attribValue == '\''); arg.attribValue = &(arg.attribValue[1]); attribEnd = strchr(arg.attribValue, '\''); assert(attribEnd != NULL); *attribEnd = '\0'; assert(attribEnd[1] == ']'); } c_walk(v_cfElement(node)->children, getChildren, &arg); os_free(arg.tagName); if (slash) { nrToProcess += c_iterLength(arg.children); } /* now append */ node = v_cfNode(c_iterTakeFirst(arg.children)); while (node != NULL) { c_iterAppend(result, node); node = v_cfNode(c_iterTakeFirst(arg.children)); } c_iterFree(arg.children); if (slash) { posInExpr = (const c_char *)(C_ADDRESS(slash) + 1U); slash = strchr(posInExpr, XPATH_SEPERATOR); } } } return result; }
void v_leaseRenew( v_lease lease, v_duration* leaseDuration /* may be NULL */) { c_iter observers = NULL; v_leaseManager observer; c_time newExpiryTime; c_equality cmp; if (lease != NULL) { assert(C_TYPECHECK(lease, v_lease)); v_leaseLock(lease); /* Is a new lease duration provided, if so replace the current lease * duration with the new one */ if(leaseDuration != NULL) { lease->duration = *leaseDuration; } /* else do nothing */ /* Calculate the new expiry time */ newExpiryTime = c_timeAdd(v_timeGet(), lease->duration); /* Is the new expiryTime earlier then the current expiryTime? */ cmp = c_timeCompare(newExpiryTime, lease->expiryTime); /* Always replace the current expiry time with the new expiryTime */ lease->expiryTime = newExpiryTime; /* If the new expiryTime is earlier then the previous expiryTime. Then * this means the observers must be notified so they can take the * earlier expiryTime into account */ if (cmp == C_LT) { /* Collect all observers, so they can be notified of the lease change * Must do a seperate collect as the lease mutex is 'lower' then the * leaseManager mutex. So to prevent deadlock we can not directly notify * the lease manager as we walk the collection */ if(lease->observers) { c_walk(lease->observers, v_leaseCollectObservers, &observers); } v_leaseUnlock(lease); if(observers) { observer = v_leaseManager(c_iterTakeFirst(observers)); while (observer != NULL) { v_leaseManagerNotify( observer, lease, V_EVENT_LEASE_RENEWED); c_free(observer); observer = v_leaseManager(c_iterTakeFirst(observers)); } c_iterFree(observers); } } else { /* No need to notify observers, the new expiryTime is not earlier * then what it was before. */ v_leaseUnlock(lease); } } }
static void printCollection( c_collectionType type, toolActionData actionData) { c_long size, i, offset, esize; c_object o; c_voidp p; c_object arrayElement; c_type subtype; c_bool isRef; o = c_iterObject(actionData->stack, 0); switch (type->kind) { case C_ARRAY: case C_SEQUENCE: /* Walk over all entries */ switch (type->kind) { case C_ARRAY: if (type->maxSize == 0) { size = c_arraySize((c_array)o); } else { size = type->maxSize; } break; case C_SEQUENCE: size = c_arraySize((c_array)o); break; default: size = 0; assert(FALSE); break; } if (c_typeIsRef(type->subType)) { esize = sizeof(c_voidp); isRef = TRUE; } else { esize = type->subType->size; isRef = FALSE; } p = o; offset = 0; for (i=0; i<size; i++) { iprintf("Element (%d) Offset (%d)\n",i,offset); arrayElement = isRef ? *((c_object *)p) : (c_object) p; if (arrayElement != NULL) { OBJECT_PUSH(actionData, arrayElement); if (isRef) { subtype = c_getType(arrayElement); printType(subtype, actionData); } else { iprintf(" "); printType(type->subType, actionData); } printf("\n"); OBJECT_POP(actionData); } else { iprintf(" <0x0>\n"); } p = C_DISPLACE(p, esize); offset += esize; } break; case C_STRING: printf(" \"%s\"",(c_char *)o); break; case C_SET: case C_LIST: case C_BAG: case C_DICTIONARY: case C_QUERY: { if (o != NULL) { /* Walk over the elements */ c_walk(o, (c_action)printCollectionAction, actionData); if (c_count(o) == 0) { iprintf("<EMPTY>"); } } else { iprintf("<NULL>"); } } break; case C_SCOPE: c_scopeWalk(o, printCollectionAction, actionData); break; default: printf("Specified type <0x"PA_ADDRFMT"> is not a valid collection type\n", (os_address)type); break; } }
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; }