Пример #1
0
c_bool
v_groupStreamUnSubscribe(
    v_groupStream stream,
    v_partition partition)
{
    c_iter list;
    v_group group;
    c_bool result;

    assert(C_TYPECHECK(stream, v_groupStream));
    assert(C_TYPECHECK(partition, v_partition));

    list = c_select(stream->groups, 0);
    group = c_iterTakeFirst(list);
    result = FALSE;

    while (group != NULL) {
        if(strcmp(v_partitionName(partition),
                  v_partitionName(group->partition)) == 0){
            result = v_groupStreamUnSubscribeGroup(stream, group);
        }
        c_free(group);
        group = c_iterTakeFirst(list);
    }
    c_iterFree(list);

    return result;
}
Пример #2
0
void
v_entryRemoveGroup(
    v_entry entry,
    v_group group)
{
    c_query query;
    q_expr qExpr;
    c_value params[2];
    c_iter groups;
    v_proxy proxy, proxy2;
    v_handle handle;

    assert(entry != NULL);
    assert(C_TYPECHECK(entry,v_entry));
    assert(group != NULL);
    assert(C_TYPECHECK(group,v_group));

    handle = v_publicHandle(v_public(group));
    qExpr = (q_expr)q_parse("source.index = %0 and source.server = %1");
    params[0] = c_longValue(handle.index);
    params[1] = c_addressValue(handle.server);

    query = c_queryNew(entry->groups, qExpr, params);
    q_dispose(qExpr);
    groups = c_select(query, 0);
    c_free(query);
    assert(c_iterLength(groups) <= 1);
    proxy = v_proxy(c_iterTakeFirst(groups));
    proxy2 = c_remove(entry->groups, proxy, NULL, NULL);
    c_iterFree(groups);
    c_free(proxy);
    c_free(proxy2);
}
Пример #3
0
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 */
}
Пример #4
0
static c_bool
v_partitionAdminRemoveExpression(
    v_partitionAdmin da,
    const char *partitionExpr)
{
    c_bool result = FALSE;
    v_partitionInterest partitionInterest, found;
    q_expr expr;
    c_collection q;
    c_iter list;
    c_value params[1];

    assert(!v_partitionExpressionIsAbsolute(partitionExpr));

    expr = (q_expr)q_parse("expression like %0");
    params[0] = c_stringValue((char *)partitionExpr);
    q = c_queryNew(da->partitionInterests, expr, params);
    q_dispose(expr);
    list = c_select(q,0);
    assert(c_iterLength(list) <= 1);
    partitionInterest = v_partitionInterest(c_iterTakeFirst(list));
    while (partitionInterest) {
       result = TRUE;
       found = c_tableRemove(da->partitionInterests, partitionInterest, NULL, NULL);
       c_free(partitionInterest);
       c_free(found);
       partitionInterest = v_partitionInterest(c_iterTakeFirst(list));
    }
    c_free(q);
    c_iterFree(list);

    return result;
}
Пример #5
0
c_bool
v_readerWaitForHistoricalData(
    v_reader r,
    c_time timeout)
{
    struct historicalWaitArg arg;
    c_iter entries;
    c_object e;

    v_readerEntrySetLock(r);
    entries = c_select(r->entrySet.entries, 0);
    v_readerEntrySetUnlock(r);

    arg._expire_time = c_timeAdd(v_timeGet(), timeout);
    arg._status = TRUE;

    e = c_iterTakeFirst(entries);
    while (e != NULL) {
        if (arg._status == TRUE) {
            if (r->qos->durability.kind == V_DURABILITY_VOLATILE) {
                getHistoricalData(e, NULL);
            }
            waitForHistoricalData(e, &arg);
        }
        c_free(e);
        e = c_iterTakeFirst(entries);
    }
    c_iterFree(entries);

    return(arg._status);
}
Пример #6
0
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;
}
Пример #7
0
int
select(long nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, struct timeval *timeout)
{
    int ret;

    OS_mutex_lock(g_main_mutex, &mtx_key);
    ret = c_select(nfds, readsds, writesds, exceptsds, timeout);
    OS_mutex_unlock(g_main_mutex, mtx_key);

    return(ret);
}
Пример #8
0
c_iter
v_partitionLookupSubscribers(
    v_partition partition)
{
    c_iter participants;
    c_iter result;
    c_iter entities;
    c_iter partitions;
    v_participant participant;
    v_entity entity;
    v_entity partition2;

    result = NULL;
    participants = v_resolveParticipants(v_objectKernel(partition), "*");
    participant = v_participant(c_iterTakeFirst(participants));

    while (participant != NULL) {
        c_lockRead(&participant->lock);
        entities = c_select(participant->entities, 0);
        c_lockUnlock(&participant->lock);
        entity = v_entity(c_iterTakeFirst(entities));

        while (entity != NULL) {
            if(v_objectKind(entity) == K_SUBSCRIBER) {
                partitions = v_subscriberLookupPartitions(v_subscriber(entity),
                                                    v_partitionName(partition));

                if (c_iterLength(partitions) > 0) {
                    result = c_iterInsert(result, entity); /* transfer refcount */
                } else {
                    c_free(entity);
                }
                partition2 = v_entity(c_iterTakeFirst(partitions));

                while (partition2 != NULL) {
                    c_free(partition2);
                    partition2 = v_entity(c_iterTakeFirst(partitions));
                }
                c_iterFree(partitions);
            }
            /* entity is already free or refcount transferred to result */
            entity = v_entity(c_iterTakeFirst(entities));
        }
        c_iterFree(entities);
        c_free(participant);
        participant = v_participant(c_iterTakeFirst(participants));
    }
    c_iterFree(participants);
    return result;
}
Пример #9
0
d_storeResult
d_storeMMFKernelBackupRestore(
    d_storeMMFKernel kernel,
    const d_store store,
    const d_nameSpace nameSpace)
{
    c_iter groups;
    d_groupInfo group;
    d_groupInfo restore, found;
    d_storeResult result;

    if(kernel && nameSpace){
        groups = c_select(kernel->backup, 0);
        group = d_groupInfo(c_iterTakeFirst(groups));
        result = D_STORE_RESULT_OK;

        while(group && (result == D_STORE_RESULT_OK)){
            if(d_nameSpaceIsIn(nameSpace, group->partition, group->topic->name)){
                restore = c_remove(kernel->backup, group, NULL, NULL);
                assert(restore);

                if(restore){
                    found = d_groupInfo(c_tableInsert(kernel->groups, restore));

                    if(found != restore){
                        c_remove(kernel->groups, found, NULL, NULL);
                        c_free(found);
                        found = d_groupInfo(c_tableInsert(kernel->groups, restore));
                        assert(found == restore);

                        if(found != restore){
                            result = D_STORE_RESULT_ERROR;
                        }
                    }
                } else {
                    result = D_STORE_RESULT_ERROR;
                }
            }
            c_free(group);
            group = d_groupInfo(c_iterTakeFirst(groups));
        }
        c_iterFree(groups);
    } else {
        result = D_STORE_RESULT_ILL_PARAM;
    }
    return result;
}
Пример #10
0
c_iter
v_readerCollectEntries(
    v_reader r)
{
    c_iter result;

    assert(C_TYPECHECK(r,v_reader));

    if(r){
        v_readerEntrySetLock(r);
        result = c_select(r->entrySet.entries, 0);
        v_readerEntrySetUnlock(r);
    } else {
        result = NULL;
    }
    return result;
}
Пример #11
0
    /* Do not use C_TYPECHECK on qos parameter, since it might be allocated on heap! */

    kernel = v_objectKernel(p);
    c_lockWrite(&p->lock);
    result = v_participantQosSet(p->qos, qos, &cm);

    if ((result == V_RESULT_OK) && (cm != 0)) {
        builtinMsg = v_builtinCreateParticipantInfo(kernel->builtin,p);
        c_lockUnlock(&p->lock);
        v_writeBuiltinTopic(kernel, V_PARTICIPANTINFO_ID, builtinMsg);
        c_free(builtinMsg);
    } else {
        c_lockUnlock(&p->lock);
    }

    return result;
}

v_leaseManager
v_participantGetLeaseManager(
    v_participant p)
{
    assert(C_TYPECHECK(p,v_participant));

    return c_keep(p->leaseManager);
}

#define RESEND_SECS      (0U)
#define RESEND_NANOSECS  (2000000U) /* 2 ms */
void
v_participantResendManagerMain(
    v_participant p)
{
    c_iter writerProxies;
    v_proxy wp;
    v_writer w;
    v_handleResult r;
    c_time waitTime = { RESEND_SECS, RESEND_NANOSECS };

    assert(C_TYPECHECK(p,v_participant));

    c_mutexLock(&p->resendMutex);
    while (!p->resendQuit) {

        if (c_count(p->resendWriters) == 0) {
            c_condWait(&p->resendCond, &p->resendMutex);
        } else {
            c_condTimedWait(&p->resendCond, &p->resendMutex, waitTime);
        }

        if (!p->resendQuit) {
            writerProxies = c_select(p->resendWriters, 0);
            c_mutexUnlock(&p->resendMutex);
            wp = v_proxy(c_iterTakeFirst(writerProxies));
            while (wp != NULL) {
                r = v_handleClaim(wp->source,(v_object *)&w);
                if (r == V_HANDLE_OK) {
                    assert(C_TYPECHECK(w,v_writer));
                    v_writerResend(w);
                    v_handleRelease(wp->source);
                }
                c_free(wp);
                wp = v_proxy(c_iterTakeFirst(writerProxies));
            }
            c_iterFree(writerProxies);

            c_mutexLock(&p->resendMutex);
        } /* already quiting */
    }
    c_mutexUnlock(&p->resendMutex);
}
Пример #12
0
d_storeResult
d_storeMMFKernelDeleteNonMatchingGroups(
    d_storeMMFKernel _this,
    c_string partitionExpr,
    c_string topicExpr)
{
    d_storeResult result;
    d_groupInfo group, removed;
    c_iter groups;
    c_bool match;

    if(_this && partitionExpr && topicExpr){
        result = D_STORE_RESULT_OK;
        groups = c_select(_this->groups, 0);
        group = d_groupInfo(c_iterTakeFirst(groups));

        while(group){
            match = d_patternMatch(group->partition, partitionExpr);

            if(match){
                match = d_patternMatch(group->topic->name, topicExpr);
            }

            if(!match){
                removed = c_remove(_this->groups, group, NULL, NULL);
                assert(removed == group);

                if(removed != group){
                    result = D_STORE_RESULT_MUTILATED;
                }
                c_free(removed);
            }
            c_free(group);
            group = d_groupInfo(c_iterTakeFirst(groups));
        }
        c_iterFree(groups);
    } else {
        result = D_STORE_RESULT_ILL_PARAM;
    }
    return result;
}
Пример #13
0
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;
}
Пример #14
0
c_iter
v_resolveTopics(
    v_kernel kernel,
    const c_char *name)
{
    c_iter list;
    c_collection q;
    q_expr expr;
    c_value params[1];

    assert(kernel != NULL);
    assert(C_TYPECHECK(kernel,v_kernel));

    expr = (q_expr)q_parse("name like %0");
    params[0] = c_stringValue((char *)name);
    q = c_queryNew(kernel->topics,expr,params);
    q_dispose(expr);
    c_lockRead(&kernel->lock);
    list = c_select(q,0);
    c_lockUnlock(&kernel->lock);
    c_free(q);
    return list;
}
Пример #15
0
void
v_groupStreamDeinit(
    v_groupStream stream)
{
    c_iter groups;
    v_group group;

    assert(C_TYPECHECK(stream, v_groupStream));

    v_readerDeinit(v_reader(stream));

    groups = 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;
}
Пример #16
0
static c_bool
v__partitionAdminRemove(
    v_partitionAdmin da,
    const char *partitionName,
    v_partition *partitionRemoved)
{
    c_bool result;
    v_partition partition, found;
    q_expr expr;
    c_collection q;
    c_iter list;
    c_value params[1];

    assert(v_partitionExpressionIsAbsolute(partitionName));

    expr = (q_expr)q_parse("name like %0");
    params[0] = c_stringValue((char *)partitionName);
    q = c_queryNew(da->partitions, expr, params);
    q_dispose(expr);
    list = c_select(q,0);
    assert(c_iterLength(list) <= 1);
    partition = v_partition(c_iterTakeFirst(list));
    if (partition) {
       found = c_tableRemove(da->partitions, partition, NULL, NULL);
       *partitionRemoved = found;
       c_free(partition);
       result = TRUE;
    } else {
       *partitionRemoved = NULL;
       result = FALSE;
    }
    c_free(q);
    c_iterFree(list);

    return result;
}
Пример #17
0
void
cmx_readerSnapshotNewAction(
    v_entity e, 
    c_voidp args)
{
    v_dataReader reader;
    c_iter instances;
    v_dataReaderInstance instance;
    v_dataReaderSample sample, prev;
    v_query query;
    c_bool release;
    sd_serializer ser;
    sd_serializedData data;
    struct cmx_readerSnapshotArg* arg;
    
    release = FALSE;
    arg = (struct cmx_readerSnapshotArg*)args;
    reader = NULL;
    instances = NULL;
    ser = NULL;
    
    switch(v_object(e)->kind){
    case K_DATAREADER:
        reader = v_dataReader(e);
        arg->success = TRUE;
        arg->snapshot = cmx_readerSnapshot(os_malloc(C_SIZEOF(cmx_readerSnapshot)));
        v_observerLock(v_observer(reader));
        
        if(reader->index->objects){
            instances = c_select(reader->index->notEmptyList, 0);
        }
    break;
    case K_QUERY:
    case K_DATAREADERQUERY:
        query = v_query(e);
        reader = v_dataReader(v_querySource(query));
        
        if(reader != NULL){
            release = TRUE;
            arg->success = TRUE;
            arg->snapshot = cmx_readerSnapshot(os_malloc(C_SIZEOF(cmx_readerSnapshot)));
            v_observerLock(v_observer(reader));
            
            switch(v_object(query)->kind){
            case K_DATAREADERQUERY:
                if(v_dataReaderQuery(query)->instanceQ){
                    instances = c_select((c_collection)(v_dataReaderQuery(query)->instanceQ), 0);
                }
            break;
            default:
                OS_REPORT_1(OS_ERROR, CM_XML_CONTEXT, 0, 
                    "cmx_readerSnapshotNewAction unknown kind (%d).",
                    v_object(query)->kind);
            break;
            }
        }
    break;
    default:
    break;
    }
    if(arg->success == TRUE){
        arg->snapshot->samples = c_iterNew(NULL);
    }
    if(instances != NULL){
        instance = v_dataReaderInstance(c_iterTakeFirst(instances));
        
        while(instance != NULL){
            sample = c_keep(v_dataReaderInstanceHead(instance));
            
            if(sample != NULL){
                prev = sample->prev;
                sample->prev = NULL;
                
                if(ser == NULL){
                    ser = sd_serializerXMLNewTyped(c_getType(c_object(sample)));
                }
                data = sd_serializerSerialize(ser, c_object(sample));
                arg->snapshot->samples = c_iterInsert(arg->snapshot->samples, 
                                                sd_serializerToString(ser, data));
                sd_serializedDataFree(data);
                sample->prev = prev;
                c_free(sample);
            }
            c_free(instance);
            instance = v_dataReaderInstance(c_iterTakeFirst(instances));
        }
        c_iterFree(instances);
    }
    if(reader != NULL){
        v_observerUnlock(v_observer(reader));
        
        if(release == TRUE){
            c_free(reader);
        }
    }
    if(ser != NULL){
        sd_serializerFree(ser);
    }
}
Пример #18
0
void BattleMagicEvent::excute(CallBackWithVoid callback)
{
	BattleHero * hero = BattleData::GetInstance()->m_bHero[m_side];
	// 0:  magic select target, 1: select card, 2, animation, 3 change data
	
	if(m_step == 0)
	{
		int selectSide, selectNum, selectElement;
		if (hero->PlayMagic_SelectCallBack(m_mindex, selectSide, selectNum, selectElement))
		{
			if (selectSide == -1 || selectNum == -1) // no one
			{
				EEventPtr skillShow_event(new BattleShowHintEvent("Do Not find target!\nMagic is being cancelled."));
				BattleEngine::GetInstance()->GetExecuteEventManager()->insertEvent(skillShow_event);
				callback();
				return;
			}

			CC_ASSERT(selectSide == 0 || selectSide == 1);
			CC_ASSERT(selectNum > 0 && selectNum < 5);
			CC_ASSERT(selectElement >= 0 && selectElement <= 5);
			EEventList m_nextEvent;
			//UI:
			BattleMagicEvent * step1 = new BattleMagicEvent(m_side, m_mindex, m_uiroot);
			step1->m_step = 1;

			EEventPtr select_e(new BattleMagicSelectTargetEvent(selectSide, selectNum, selectElement, [step1](const std::vector<int> & intarray)
			{
				// next step:
				step1->m_select = intarray;
				EEventPtr n_event(step1);
				BattleEngine::GetInstance()->GetExecuteEventManager()->insertEvent(n_event);
			}));

			m_nextEvent.push_back(select_e);

			BattleEngine::GetInstance()->GetExecuteEventManager()->insertEventList(m_nextEvent);
			callback();
			return;
		}
		else
		{
			m_step = 1;
		}
	}

	if (m_step == 1)
	{
		int  selectNum;
		if (hero->MagicEffect_CardCallBack(m_mindex, selectNum))
		{
			EEventList m_nextEvent;
			//UI:
			BattleMagicEvent * step2 = new BattleMagicEvent(m_side, m_mindex, m_uiroot);
			step2->m_step = 2;
			step2->m_select = m_select;

			EEventPtr c_select(new BattleCardSelectViewEvent(m_uiroot, selectNum, [step2](int cardNum) {
				// next step:
				step2->m_cardNum = cardNum;
				EEventPtr n_event(step2);
				BattleEngine::GetInstance()->GetExecuteEventManager()->insertEvent(n_event);
			}));
			
			m_nextEvent.push_back(c_select);

			BattleEngine::GetInstance()->GetExecuteEventManager()->insertEventList(m_nextEvent);
			callback();
			return;
		}
		else
		{
			m_step = 2;
		}
	}

	if (m_step == 2)
	{
		EEventList m_nextEvent;
		//UI:
		EEventPtr skillShow_event(new BattleShowHintEvent("Magic: " + hero->GetMagicName(m_mindex)));
		m_nextEvent.push_back(skillShow_event);

		// next step:
		BattleMagicEvent * nextStep = (new BattleMagicEvent(m_side, m_mindex, m_uiroot));
		nextStep->m_step = 3;
		nextStep->m_select = m_select;
		nextStep->m_cardNum = m_cardNum;
		EEventPtr n_event(nextStep);
		m_nextEvent.push_back(n_event);

		BattleEngine::GetInstance()->GetExecuteEventManager()->insertEventList(m_nextEvent);
		callback();
		return;
	}

	if (m_step == 3)
	{
		hero->PlayMagic(m_mindex, m_select, m_cardNum, callback);
	}
	
}
Пример #19
0
v_historyResult
v_readerWaitForHistoricalDataWithCondition(
    v_reader _this,
    c_char* filter,
    c_char* params[],
    c_ulong paramsLength,
    c_time minSourceTime,
    c_time maxSourceTime,
    struct v_resourcePolicy *resourceLimits,
    c_time timeout)
{
    c_iter entries;
    c_object e;
    v_historyResult result;
    v_historicalDataRequest request;
    c_bool doRequest, doWait;
    struct historicalWaitArg arg;
    C_STRUCT(v_event) event;

    arg._expire_time = c_timeAdd(v_timeGet(), timeout);
    arg._status = TRUE;

    request = v_historicalDataRequestNew(v_objectKernel(_this), filter, params,
                paramsLength, minSourceTime, maxSourceTime, resourceLimits);

    if(request){
        V_READER_LOCK(_this);

        if(_this->historicalDataRequest) {
            /* Historical data request already in progress or complete, check
             * whether request is equal to the original one.
             */
            doRequest = FALSE;

            if(v_historicalDataRequestEquals(request, _this->historicalDataRequest)){
                /* Request is equal to original request*/
                result = V_HISTORY_RESULT_OK;

                if(_this->historicalDataComplete){
                    /* Request has already been fulfilled. Consider this call
                     * a no-operation.
                     */
                    doWait = FALSE;
                } else {
                    /* Request is still in progress, wait for data to arrive*/
                    doWait = TRUE;
                }
            } else {
                /* The requested parameters are not equal to the originally
                 * requested set. Return a precondition not met.
                 */
                doWait = FALSE;
                result = V_HISTORY_RESULT_PRE_NOT_MET;
            }
            c_free(request);
        } else {
            /* No active request, so validate it now.*/
            if(v_historicalDataRequestIsValid(request, _this)){
                /* This request is valid, so request data.*/
                doRequest = TRUE;
                doWait    = TRUE;
                result    = V_HISTORY_RESULT_OK;
                _this->historicalDataRequest = request;
            } else {
                /* Request is not valid, so return bad parameter.*/
                doRequest = FALSE;
                doWait    = FALSE;
                result    = V_HISTORY_RESULT_BAD_PARAM;
                c_free(request);
            }
        }
        V_READER_UNLOCK(_this);
    } else {
        doRequest = FALSE;
        doWait    = FALSE;
        result    = V_HISTORY_RESULT_ERROR;
    }

    if(doWait){
        v_readerEntrySetLock(_this);
        entries = c_select(_this->entrySet.entries, 0);
        v_readerEntrySetUnlock(_this);

        if(doRequest){
            /* Historical data must be requested, since this is the first time
             * the operation is called and the request is valid.
             */
            if (_this->qos->durability.kind == V_DURABILITY_VOLATILE) {
                /* If reader is volatile, the historical data from the
                 * group(s) has/have not been retrieved yet, so do it now.
                 */
                e = c_iterTakeFirst(entries);
                while (e != NULL) {
                    getHistoricalData(e, _this->historicalDataRequest);
                    c_free(e);
                    e = c_iterTakeFirst(entries);
                }
                c_iterFree(entries);
            }
            event.kind = V_EVENT_HISTORY_REQUEST;
            event.source = v_publicHandle(v_public(_this));
            event.userData = _this->historicalDataRequest;
            v_observableNotify(v_observable(v_objectKernel(_this)),&event);
        }

        V_READER_LOCK(_this);

        if(!_this->historicalDataComplete){
            if (c_timeCompare(timeout, C_TIME_INFINITE) != C_EQ) {
                if (c_condTimedWait(&_this->historicalDataCondition,
                                    &V_READER_GET_LOCK(_this),
                                    timeout) != SYNC_RESULT_SUCCESS)
                {
                    result = V_HISTORY_RESULT_TIMEOUT;
                }
            } else if (c_condWait(&_this->historicalDataCondition,
                            &V_READER_GET_LOCK(_this)) != SYNC_RESULT_SUCCESS)
            {
                    result = V_HISTORY_RESULT_TIMEOUT;
            }
            assert( (result == V_HISTORY_RESULT_OK) ==
                     _this->historicalDataComplete);
        }
        V_READER_UNLOCK(_this);

    }
    return result;
}