/** 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();
}
Example #3
0
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;
}
Example #5
0
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;
        }
    }
}
Example #6
0
/**
 * 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;
}  
Example #7
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;
}