c_bool d_readerRequestRemoveChain( d_readerRequest request, d_chain chain) { d_chain found; c_bool result; assert(d_objectIsValid(d_object(request), D_READER_REQUEST) == TRUE); assert(d_objectIsValid(d_object(chain), D_CHAIN) == TRUE); if(request && chain){ d_lockLock(d_lock(request)); found = d_tableRemove(request->requests, chain); d_lockUnlock(d_lock(request)); if(found){ result = TRUE; d_chainFree(found); } else { result = FALSE; } } else { result = FALSE; } return result; }
c_bool d_readerRequestAddGroup( d_readerRequest request, d_group group) { c_bool result; d_group found; assert(d_objectIsValid(d_object(request), D_READER_REQUEST) == TRUE); if(request){ d_lockLock(d_lock(request)); found = d_tableInsert(request->groups, group); d_lockUnlock(d_lock(request)); if(!found){ d_objectKeep(d_object(group)); result = TRUE; } else { result = FALSE; } } else { result = FALSE; } return result; }
void d_waitsetDeinit( d_object object) { d_waitset waitset; d_waitsetEntity we; d_waitsetHelper helper; assert(d_objectIsValid(object, D_WAITSET) == TRUE); if(object){ waitset = d_waitset(object); waitset->terminate = TRUE; if(waitset->runToCompletion == TRUE){ if(os_threadIdToInteger(waitset->thread)) { u_waitsetNotify(waitset->uwaitset, NULL); os_threadWaitExit(waitset->thread, NULL); } } else { if(waitset->threads){ helper = d_waitsetHelper(c_iterTakeFirst(waitset->threads)); while(helper){ helper->terminate = TRUE; u_waitsetNotify(helper->userWaitset, NULL); os_threadWaitExit(helper->tid, NULL); u_waitsetDetach(helper->userWaitset, u_entity(helper->entity->dispatcher)); u_waitsetFree(helper->userWaitset); os_free(helper); helper = d_waitsetHelper(c_iterTakeFirst(waitset->threads)); } c_iterFree(waitset->threads); waitset->threads = NULL; } } d_lockLock(d_lock(waitset)); if(waitset->entities) { we = d_waitsetEntity(c_iterTakeFirst(waitset->entities)); while(we) { if(waitset->runToCompletion == TRUE){ u_waitsetDetach(waitset->uwaitset, u_entity(we->dispatcher)); } d_waitsetEntityFree(we); we = d_waitsetEntity(c_iterTakeFirst(waitset->entities)); } c_iterFree(waitset->entities); } if(waitset->runToCompletion == TRUE){ if(waitset->uwaitset) { u_waitsetFree(waitset->uwaitset); } } d_lockUnlock(d_lock(waitset)); } }
static void* d_waitsetEventHandlerRunToCompletion( void* userData) { d_subscriber subscriber; d_durability durability; d_admin admin; d_waitset waitset; c_iter events = NULL; d_waitsetEntity we; c_time time; u_waitsetEvent event; waitset = d_waitset(userData); subscriber = d_waitsetGetSubscriber(waitset); admin = d_subscriberGetAdmin(subscriber); durability = d_adminGetDurability(admin); time.seconds = 1; time.nanoseconds = 0; while(waitset->terminate == FALSE) { if(waitset->timedWait == TRUE){ u_waitsetTimedWaitEvents(waitset->uwaitset, time,&events); } else { u_waitsetWaitEvents(waitset->uwaitset,&events); } if(d_durabilityGetState(durability) != D_STATE_TERMINATING){ if(waitset->terminate == FALSE){ d_lockLock(d_lock(waitset)); event = u_waitsetEvent(c_iterTakeFirst(events)); while(event){ we = c_iterResolve(waitset->entities, d_waitsetEntityFind, event->entity); if(we){ we->action(we->dispatcher, event, we->usrData); } u_waitsetEventFree(event); event = u_waitsetEvent(c_iterTakeFirst(events)); } } d_lockUnlock(d_lock(waitset)); } if(events){/* events may be null if waitset was deleted */ c_iterFree(events); } } return NULL; }
c_bool d_waitsetDetach( d_waitset waitset, d_waitsetEntity we) { u_result ur; c_bool result = FALSE; int i; d_waitsetHelper helper; helper = NULL; assert(d_objectIsValid(d_object(waitset), D_WAITSET) == TRUE); assert(d_objectIsValid(d_object(we), D_WAITSET_ENTITY) == TRUE); if(waitset && we){ d_lockLock(d_lock(waitset)); if(c_iterContains(waitset->entities, we) == TRUE) { if(waitset->runToCompletion == TRUE){ ur = u_waitsetDetach(waitset->uwaitset, u_entity(we->dispatcher)); } else { for(i=0; i<c_iterLength(waitset->threads) && !helper; i++){ helper = d_waitsetHelper(c_iterObject(waitset->threads, i)); if(helper->entity != we){ helper = NULL; } } assert(helper); c_iterTake(waitset->threads, helper); helper->terminate = TRUE; u_waitsetNotify(helper->userWaitset, NULL); os_threadWaitExit(helper->tid, NULL); ur = u_waitsetDetach(helper->userWaitset, u_entity(we->dispatcher)); u_waitsetFree(helper->userWaitset); os_free(helper); } if(ur == U_RESULT_OK) { c_iterTake(waitset->entities, we); we->waitset = NULL; result = TRUE; } } d_lockUnlock(d_lock(waitset)); } return result; }
c_bool d_readerRequestAreGroupsComplete( d_readerRequest request) { c_bool result; assert(d_objectIsValid(d_object(request), D_READER_REQUEST) == TRUE); if(request){ d_lockLock(d_lock(request)); result = d_tableWalk(request->groups, checkCompleteness, NULL); d_lockUnlock(d_lock(request)); } else { result = FALSE; } return result; }
c_bool d_readerRequestHasChains( d_readerRequest request) { c_bool result; assert(d_objectIsValid(d_object(request), D_READER_REQUEST) == TRUE); if(request){ d_lockLock(d_lock(request)); result = (d_tableSize(request->requests) != 0); d_lockUnlock(d_lock(request)); } else { result = FALSE; } return result; }
d_table d_readerRequestGetGroups( d_readerRequest request) { d_table result; assert(d_objectIsValid(d_object(request), D_READER_REQUEST) == TRUE); if(request){ d_lockLock(d_lock(request)); result = d_tableNew(d_groupCompare, d_groupFree); d_tableWalk(request->groups, addGroup, result); d_lockUnlock(d_lock(request)); } else { result = NULL; } return result; }
c_bool d_groupCreationQueueAdd( d_groupCreationQueue queue, d_group group) { c_bool result; d_group found; d_durability durability; assert(d_objectIsValid(d_object(queue), D_GROUP_CREATION_QUEUE) == TRUE); result = FALSE; if(queue) { d_lockLock(d_lock(queue)); found = c_iterResolve(queue->groups, (c_iterResolveCompare)compareGroups, group); if(found == NULL){ queue->groups = c_iterInsert(queue->groups, group); switch(d_groupGetKind(group)){ case D_DURABILITY_VOLATILE: queue->groupsToCreateVolatile++; break; case D_DURABILITY_TRANSIENT: case D_DURABILITY_TRANSIENT_LOCAL: queue->groupsToCreateTransient++; break; case D_DURABILITY_PERSISTENT: queue->groupsToCreatePersistent++; break; default: assert(FALSE); break; } durability = d_adminGetDurability(queue->admin); d_durabilityUpdateStatistics(durability, d_statisticsUpdateGroupsToCreate, queue); result = TRUE; } d_lockUnlock(d_lock(queue)); } return result; }
void d_readerRequestRemoveGroup( d_readerRequest request, d_group group) { d_group dgroup; assert(d_objectIsValid(d_object(request), D_READER_REQUEST) == TRUE); if(request){ d_lockLock(d_lock(request)); dgroup = d_tableRemove(request->groups, group); d_lockUnlock(d_lock(request)); if(dgroup){ d_groupFree(dgroup); } } return; }
c_bool d_groupCreationQueueIsEmpty( d_groupCreationQueue queue) { c_bool result; assert(d_objectIsValid(d_object(queue), D_GROUP_CREATION_QUEUE) == TRUE); d_lockLock(d_lock(queue)); if((queue->groupsToCreateVolatile == 0) && (queue->groupsToCreateTransient == 0) && (queue->groupsToCreatePersistent == 0)){ result = TRUE; } else { result = FALSE; } d_lockUnlock(d_lock(queue)); return result; }
c_bool d_waitsetAttach( d_waitset waitset, d_waitsetEntity we) { c_bool result = FALSE; u_result ur; os_result osr; d_waitsetHelper helper; c_ulong mask; d_admin admin; d_durability durability; assert(d_objectIsValid(d_object(waitset), D_WAITSET) == TRUE); assert(d_objectIsValid(d_object(we), D_WAITSET_ENTITY) == TRUE); if(waitset && we){ d_lockLock(d_lock(waitset)); if(!we->waitset) { if(c_iterContains(waitset->entities, we) == FALSE) { waitset->entities = c_iterInsert(waitset->entities, we); if(waitset->runToCompletion == TRUE){ ur = u_waitsetAttach(waitset->uwaitset, u_entity(we->dispatcher), (c_voidp)we->dispatcher); if(ur == U_RESULT_OK) { we->waitset = waitset; result = TRUE; } } else { admin = d_subscriberGetAdmin(waitset->subscriber); durability = d_adminGetDurability(admin); helper = os_malloc(C_SIZEOF(d_waitsetHelper)); helper->waitset = waitset; helper->entity = we; helper->terminate = FALSE; helper->tid = OS_THREAD_ID_NONE; helper->userWaitset = u_waitsetNew(u_participant(d_durabilityGetService(durability))); mask = V_EVENT_DATA_AVAILABLE; mask |= V_EVENT_NEW_GROUP; mask |= V_EVENT_HISTORY_DELETE; mask |= V_EVENT_HISTORY_REQUEST; mask |= V_EVENT_PERSISTENT_SNAPSHOT; mask |= V_EVENT_TRIGGER; u_waitsetSetEventMask(helper->userWaitset, mask); ur = u_waitsetAttach(helper->userWaitset, u_entity(we->dispatcher), (c_voidp)we->dispatcher); if(ur != U_RESULT_OK) { assert(FALSE); } else { result = TRUE; } if(result){ waitset->threads = c_iterInsert(waitset->threads, helper); osr = os_threadCreate(&(helper->tid), we->name, &(we->attr), d_waitsetEventHandler, helper); if(osr != os_resultSuccess){ c_iterTake(waitset->threads, helper); u_waitsetDetach(helper->userWaitset, u_entity(we->dispatcher)); u_waitsetFree(helper->userWaitset); os_free(helper); result = FALSE; } } else { u_waitsetFree(helper->userWaitset); os_free(helper); } } } } d_lockUnlock(d_lock(waitset)); } return result; }
static void* d_groupCreationQueueRun( void* userData) { d_groupCreationQueue queue; c_iter groupsToCreate, reinsert; d_group group, localGroup; d_durability durability; d_durabilityKind kind; u_participant uservice; c_char *partition, *topic; v_duration duration; u_group ugroup; c_long creationCountVolatile, creationCountTransient, creationCountPersistent; c_ulong maxBurst; os_time sleepTime, maxBurstSleepTime; c_bool update; sleepTime.tv_sec = 1; sleepTime.tv_nsec = 0; duration.seconds = 0; duration.nanoseconds = 5000000; /*5ms*/ creationCountVolatile = 0; creationCountTransient = 0; creationCountPersistent = 0; maxBurstSleepTime.tv_sec = 0; maxBurstSleepTime.tv_nsec = 10000000; /*10ms*/ queue = d_groupCreationQueue(userData); groupsToCreate = c_iterNew(NULL); reinsert = c_iterNew(NULL); durability = d_adminGetDurability(queue->admin); uservice = u_participant(d_durabilityGetService(durability)); d_waitForCompletenessDCPSTopic(queue); while(queue->terminate == FALSE) { d_lockLock(d_lock(queue)); queue->groupsToCreateVolatile -= creationCountVolatile; assert(queue->groupsToCreateVolatile >= 0); queue->groupsToCreateTransient -= creationCountTransient; assert(queue->groupsToCreateTransient >= 0); queue->groupsToCreatePersistent -= creationCountPersistent; assert(queue->groupsToCreatePersistent >= 0); group = d_group(c_iterTakeFirst(queue->groups)); while(group){ groupsToCreate = c_iterInsert(groupsToCreate, group); group = d_group(c_iterTakeFirst(queue->groups)); } assert((queue->groupsToCreateVolatile + queue->groupsToCreateTransient + queue->groupsToCreatePersistent) == c_iterLength(groupsToCreate)); durability = d_adminGetDurability(queue->admin); d_durabilityUpdateStatistics(durability, d_statisticsUpdateGroupsToCreate, queue); d_lockUnlock(d_lock(queue)); creationCountVolatile = 0; creationCountTransient = 0; creationCountPersistent = 0; maxBurst = 10; group = c_iterTakeFirst(groupsToCreate); while(group && (queue->terminate == FALSE)){ partition = d_groupGetPartition(group); topic = d_groupGetTopic(group); kind = d_groupGetKind(group); localGroup = d_adminGetLocalGroup(queue->admin, partition, topic, kind); update = FALSE; if(localGroup) { d_printTimedEvent(durability, D_LEVEL_FINE, D_THREAD_GROUP_CREATION, "Remote group %s.%s has already been created locally.\n", partition, topic); update = TRUE; } else { ugroup = u_groupNew(uservice, partition, topic, duration); if(ugroup){ d_printTimedEvent(durability, D_LEVEL_FINE, D_THREAD_GROUP_CREATION, "Remote group %s.%s created locally.\n", partition, topic); update = TRUE; u_entityFree(u_entity(ugroup)); maxBurst--; if(maxBurst == 0){ os_nanoSleep(maxBurstSleepTime); maxBurst = 10; } } else { maxBurst++; d_printTimedEvent(durability, D_LEVEL_FINE, D_THREAD_GROUP_CREATION, "Remote group %s.%s could not be created locally.\n", partition, topic); if(d_durabilityGetState(durability) == D_STATE_COMPLETE){ d_printTimedEvent(durability, D_LEVEL_FINE, D_THREAD_GROUP_CREATION, "I am complete so it will not be available anymore.\n"); update = TRUE; } else if(d_adminGetFellowCount(queue->admin) == 0){ d_printTimedEvent(durability, D_LEVEL_WARNING, D_THREAD_GROUP_CREATION, "No fellows available to provide me with group information. " \ "Ignoring group.\n", partition, topic); update = TRUE; } else { reinsert = c_iterInsert(reinsert, group); } } } if(update){ switch(d_groupGetKind(group)){ case D_DURABILITY_VOLATILE: creationCountVolatile++; break; case D_DURABILITY_TRANSIENT: case D_DURABILITY_TRANSIENT_LOCAL: creationCountTransient++; break; case D_DURABILITY_PERSISTENT: creationCountPersistent++; break; default: assert(FALSE); break; } d_groupFree(group); } os_free(partition); os_free(topic); group = c_iterTakeFirst(groupsToCreate); } group = d_group(c_iterTakeFirst(reinsert)); while(group){ groupsToCreate = c_iterInsert(groupsToCreate, group); group = d_group(c_iterTakeFirst(reinsert)); } if(queue->terminate == FALSE){ os_nanoSleep(sleepTime); } } group = d_group(c_iterTakeFirst(groupsToCreate)); while(group) { d_groupFree(group); group = d_group(c_iterTakeFirst(groupsToCreate)); } c_iterFree(groupsToCreate); c_iterFree(reinsert); d_lockLock(d_lock(queue)); group = d_group(c_iterTakeFirst(queue->groups)); while(group) { d_groupFree(group); group = d_group(c_iterTakeFirst(queue->groups)); } d_lockUnlock(d_lock(queue)); return NULL; }