/** Keep a DistributedObject with the dobject name * @param name the name of a dobject to keep * @param d distributed object to keep with the corresponding name * @return NULL */ void DistributedObjectMap::PutDistributedObject(const string& name, DistributedObject* d) { unique_lock<mutex> d_lock(*mutex_); dobject_map_->insert(make_pair(name, d)); d_lock.unlock(); }
/** Delete dobject with a corresponding name * @param name a name of dobject to delete * @return NULL */ void DistributedObjectMap::DeleteDobject(const string& name) { unique_lock<mutex> d_lock(*mutex_); dobject_map_->erase(name); d_lock.unlock(); }
d_readerRequest d_readerRequestNew( d_admin admin, v_handle source, c_char* filter, c_char** filterParams, c_long filterParamsCount, struct v_resourcePolicy resourceLimits, c_time minSourceTimestamp, c_time maxSourceTimestamp) { d_readerRequest request; c_long i; v_handleResult handleResult; v_reader vreader, *vreaderPtr; c_iter partitions; v_partition partition; v_topic topic; d_group dgroup; c_char *topicName; d_quality quality; request = d_readerRequest(os_malloc(C_SIZEOF(d_readerRequest))); if(request){ d_lockInit(d_lock(request), D_READER_REQUEST, d_readerRequestDeinit); request->admin = admin; request->readerHandle.index = source.index; request->readerHandle.serial = source.serial; request->readerHandle.server = source.server; request->requests = d_tableNew(d_chainCompare, d_chainFree); if(filter){ request->filter = os_strdup(filter); } else { request->filter = NULL; } request->resourceLimits = resourceLimits; request->minSourceTimestamp = minSourceTimestamp; request->maxSourceTimestamp = maxSourceTimestamp; request->filterParamsCount = filterParamsCount; if(filterParamsCount > 0){ request->filterParams = (c_char**)(os_malloc( filterParamsCount*sizeof(c_char*))); for(i=0; i<filterParamsCount; i++){ request->filterParams[i] = os_strdup(filterParams[i]); } } else { request->filterParams = NULL; } request->groups = d_tableNew(d_groupCompare, d_groupFree); handleResult = v_handleClaim(source, (v_object*)(vreaderPtr = &vreader)); if(handleResult == V_HANDLE_OK){ if(v_object(vreader)->kind == K_DATAREADER){ topic = v_dataReaderGetTopic(v_dataReader(vreader)); topicName = v_entity(topic)->name; partitions = ospl_c_select(v_subscriber(vreader->subscriber)->partitions->partitions, 0); partition = v_partition(c_iterTakeFirst(partitions)); while(partition){ quality.seconds = 0; quality.nanoseconds = 0; dgroup = d_groupNew( v_entity(partition)->name, topicName, topic->qos->durability.kind, D_GROUP_KNOWLEDGE_UNDEFINED, quality); d_tableInsert(request->groups, dgroup); c_free(partition); partition = v_partition(c_iterTakeFirst(partitions)); } c_free(topic); } else { d_readerRequestFree(request); request = NULL; } v_handleRelease(source); } else { d_readerRequestFree(request); request = NULL; } } return request; }
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; }
void Dispatcher::DispatchOne(const std::chrono::milliseconds& timeout) { Connection* c = nullptr; if (!d_->notify_.pop_for(c, timeout)) { sLOG << "DispatchOne timeout"; return; } if (c == nullptr) { sLOG << "DispatchOne interrupt"; return; } sLOG << "DispatchOne run"; std::unique_lock<std::mutex> d_lock(d_->mutex_); Data::Map::iterator it = d_->map_.find(c); if (it == d_->map_.end()) { sLOG << "DispatchOne expired connection?"; return; } Watch& w = it->second; assert(w.active); std::unique_lock<std::mutex> c_lock(c->d_->mutex_); // check for readability if (w.read_cb.size() && c->d_->inbound_.size()) { while (c->d_->inbound_.size() && w.read_cb.size()) { c_lock.unlock(); d_lock.unlock(); bool ret = true; try { ret = w.read_cb.front()(); } catch (std::exception& e) { LOG1 << "Dispatcher: exception " << typeid(e).name() << "in read callback."; LOG1 << " what(): " << e.what(); throw; } d_lock.lock(); c_lock.lock(); if (ret) break; w.read_cb.pop_front(); } if (w.read_cb.size() == 0 && w.write_cb.size() == 0) { // if all callbacks are done, listen no longer. c->d_->watcher_.erase(this); d_->map_.erase(it); return; } } // "check" for writable. virtual sockets are always writable. if (w.write_cb.size()) { while (w.write_cb.size()) { c_lock.unlock(); d_lock.unlock(); bool ret = true; try { ret = w.write_cb.front()(); } catch (std::exception& e) { LOG1 << "Dispatcher: exception " << typeid(e).name() << "in write callback."; LOG1 << " what(): " << e.what(); throw; } d_lock.lock(); c_lock.lock(); if (ret) break; w.write_cb.pop_front(); } if (w.read_cb.size() == 0 && w.write_cb.size() == 0) { // if all callbacks are done, listen no longer. c->d_->watcher_.erase(this); d_->map_.erase(it); return; } } }
/** * Creates a snapshots of the dialogs data and then calls the dumping function. * @returns 1 on success or 0 on failure */ int make_snapshot_dialogs() { bin_data x={0,0,0}; p_dialog *d; int i,k; time_t unique = time(0); FILE *f; switch (pcscf_persistency_mode) { case NO_PERSISTENCY: return 0; case WITH_FILES: f = bin_dump_to_file_create(pcscf_persistency_location,"pdialogs",unique); if (!f) return 0; for(i=0;i<p_dialogs_hash_size;i++){ if (!bin_alloc(&x,1024)) goto error; d_lock(i); d = p_dialogs[i].head; if (d){ while(d){ if (!bin_encode_p_dialog(&x,d)) goto error; d = d->next; } d_unlock(i); k = bind_dump_to_file_append(f,&x); if (k!=x.len) { LOG(L_ERR,"ERR:"M_NAME":make_snapshot_registrar: error while dumping to file - only wrote %d bytes of %d \n",k,x.len); d_unlock(i); bin_free(&x); return 0; } } else d_unlock(i); bin_free(&x); } return bind_dump_to_file_close(f,pcscf_persistency_location,"pdialogs",unique); break; case WITH_DATABASE_BULK: if (!bin_alloc(&x,1024)) goto error; for(i=0;i<p_dialogs_hash_size;i++){ d_lock(i); d = p_dialogs[i].head; while(d){ if (!bin_encode_p_dialog(&x,d)) goto error; d = d->next; } d_unlock(i); } return bin_dump_to_db(&x, P_DIALOGS); case WITH_DATABASE_CACHE: return bin_dump_to_db(NULL, P_DIALOGS); //ignore x, x is empty default: LOG(L_ERR,"ERR:"M_NAME":make_snapshot_registrar: Snapshot done but no such mode %d\n",pcscf_persistency_mode); return 0; } error: if (x.s) bin_free(&x); return 0; }
/** * Loads the dialogs data from the last snapshot. * @returns 1 on success or 0 on failure */ int load_snapshot_dialogs() { bin_data x; p_dialog *d; int k,max; FILE *f; switch (pcscf_persistency_mode){ case NO_PERSISTENCY: k=0; case WITH_FILES: f = bin_load_from_file_open(pcscf_persistency_location,"pdialogs"); if (!f) return 0; bin_alloc(&x,128*1024); k=bin_load_from_file_read(f,&x); max = x.max; x.max=0; LOG(L_INFO,"INFO:"M_NAME":load_snapshot_dialogs: max %d len %d\n",x.max,x.len); while(x.max<x.len){ d = bin_decode_p_dialog(&x); if (!d) return 0; LOG(L_INFO,"INFO:"M_NAME":load_snapshot_dialogs: Loaded p_dialog for <%.*s>\n",d->host.len,d->host.s); d_lock(d->hash); d->prev = p_dialogs[d->hash].tail; d->next = 0; if (p_dialogs[d->hash].tail) p_dialogs[d->hash].tail->next = d; p_dialogs[d->hash].tail = d; if (!p_dialogs[d->hash].head) p_dialogs[d->hash].head = d; d_unlock(d->hash); memmove(x.s,x.s+x.max,x.len-x.max); x.len -= x.max; x.max = max; k=bin_load_from_file_read(f,&x); max = x.max; x.max = 0; } bin_free(&x); bin_load_from_file_close(f); k = 1; break; case WITH_DATABASE_BULK: k=bin_load_from_db(&x, P_DIALOGS); x.max=0; LOG(L_INFO,"INFO:"M_NAME":load_snapshot_dialogs: max %d len %d\n",x.max,x.len); while(x.max<x.len){ d = bin_decode_p_dialog(&x); if (!d) return 0; LOG(L_INFO,"INFO:"M_NAME":load_snapshot_dialogs: Loaded p_dialog for <%.*s>\n",d->host.len,d->host.s); d_lock(d->hash); d->prev = p_dialogs[d->hash].tail; d->next = 0; if (p_dialogs[d->hash].tail) p_dialogs[d->hash].tail->next = d; p_dialogs[d->hash].tail = d; if (!p_dialogs[d->hash].head) p_dialogs[d->hash].head = d; d_unlock(d->hash); } bin_free(&x); break; case WITH_DATABASE_CACHE: k=bin_load_from_db(NULL, P_DIALOGS); //ignore x, x is empty break; default: LOG(L_ERR,"ERR:"M_NAME":load_snapshot_dialogs: Can't resume because no such mode %d\n",pcscf_persistency_mode); k=0; } if (!k) goto error; return 1; error: return 0; }