예제 #1
0
void
DK_CollectionWriter_us_delete(
    DK_CollectionWriter* _this,
    void* userData)
{
    DK_CacheAdmin* cache = NULL;
    DLRL_Exception exception;
    u_result result;

    DLRL_INFO_OBJECT(INF_ENTER);
    assert(_this);
    /* userData may be null */

    if(_this->alive)
    {
        DLRL_Exception_init(&exception);
        if(_this->writer)
        {
            /* no duplicate done */
            cache = DK_ObjectHomeAdmin_us_getCache(DK_TopicInfo_us_getOwner(_this->topicInfo));
            dcpsUtilityBridge.deleteDataWriter(&exception, userData, cache, _this->writer,
                                                                                    _this->ls_writer);
            if(exception.exceptionID != DLRL_NO_EXCEPTION)
            {
                DLRL_REPORT(REPORT_ERROR, "Exception %s occured when attempting to delete the DCPS datawriter\n%s",
                    DLRL_Exception_exceptionIDToString(exception.exceptionID), exception.exceptionMessage);
                /* reset the exception, maybe it's used again later in this deletion function. We dont propagate the */
                /* exception here anyway, so it can do no harm as we already logged the exception directly above. */
                DLRL_Exception_init(&exception);
            }
            result = u_entityFree(u_entity(_this->writer));
            if(result != U_RESULT_OK)
            {
               DLRL_Exception_transformResultToException(
                   &exception,
                   result,
                   "Unable to free the user layer writer!");
               DLRL_REPORT(
                   REPORT_ERROR,
                   "Exception %s occured when attempting to delete the DCPS "
                        "user layer datawriter\n%s",
                    DLRL_Exception_exceptionIDToString(exception.exceptionID),
                   exception.exceptionMessage);
               DLRL_Exception_init(&exception);
            }
            _this->writer = NULL;
            /* ls_reader and userReader pointer become invalid once the datareader has been deleted. */
            _this->ls_writer = NULL;
        }
        if(_this->topicInfo)
        {
            DK_Entity_ts_release((DK_Entity*)_this->topicInfo);
            _this->topicInfo = NULL;
        }
        _this->alive = FALSE;
    }
    DLRL_INFO(INF_EXIT);
}
u_topic
DJA_DCPSUtilityBridge_us_createTopic(
    DLRL_Exception* exception,
    void* userData,
    DK_ObjectHomeAdmin* home,
    LOC_char* topicName,
    LOC_char* typeName,
    void** topicUserData,
    void** ls_topic,
    LOC_boolean isMainTopic)
{
    /* JNI thread env */
    JNIEnv* env = (JNIEnv*)userData;
    /* Cached JNI data used within this call */
    jmethodID createTopicMid = cachedJNI.dcpsUtil_createTopic_mid;
    /* java topic entity description */
    jobject jtopic = NULL;
    /* needed string representations of topic name and type */
    jstring jtypeName = NULL;
    jstring jtopicName = NULL;
    /* the java object home */
    jobject ls_objectHome = NULL;
    jobject ls_participant = NULL;
    DJA_CachedJNITypedObject* typedObjectCachedData = NULL;
    DJA_CachedJNITypedTopic* typedTopicCachedData = NULL;
    gapi_topic gapiTopic = NULL;
    _Topic _topic = NULL;
    gapi_returnCode_t result = GAPI_RETCODE_OK;
    u_topic utopic = NULL;

    DLRL_INFO(INF_ENTER);
    assert(exception);
    assert(userData);
    assert(home);
    assert(topicName);
    assert(typeName);

    /* get java objects */
    /* the cache getter on the object home doesnt require a release on the returned pointer */
    ls_participant = (jobject)DK_CacheAdmin_us_getLSParticipant(DK_ObjectHomeAdmin_us_getCache(home));
    ls_objectHome = (jobject)DK_ObjectHomeAdmin_us_getLSHome(home);

    typedObjectCachedData = (DJA_CachedJNITypedObject*)DK_ObjectHomeAdmin_us_getUserData(home);
    if(isMainTopic)
    {
        typedTopicCachedData = DJA_Initialisation_loadTypedTopicCache(exception, env, typedObjectCachedData, home, ls_objectHome);
        DLRL_Exception_PROPAGATE(exception);
        *topicUserData = (void*)typedTopicCachedData;
    }
    jtypeName = (*env)->NewStringUTF(env, typeName);
    DLRL_JavaException_PROPAGATE(env, exception);
    jtopicName = (*env)->NewStringUTF(env, topicName);
    DLRL_JavaException_PROPAGATE(env, exception);
    DLRL_INFO(INF_CALLBACK, "objectHome->createTopic(participant, topicName, typeName)");
    jtopic = (*env)->CallStaticObjectMethod(env, cachedJNI.dcpsUtil_class, createTopicMid, ls_participant, jtopicName, jtypeName);
    DLRL_JavaException_PROPAGATE(env, exception);
    if(!jtopic){
        DLRL_Exception_THROW(exception, DLRL_DCPS_ERROR,
                             "Unable to create the DCPS topic with name '%s' and type '%s' "
                             "Check DCPS error log file for (possibly) more information.",
                             topicName, typeName);
    }
    DLRL_INFO(INF_DCPS, "saj_read_gapi_address(topic)");
    gapiTopic = jtopic? (gapi_topic)saj_read_gapi_address(env, jtopic) : NULL;
    if(!gapiTopic){
        DLRL_Exception_THROW(exception, DLRL_DCPS_ERROR,
                             "Unable to create the DCPS Topic entity for "
                             "topic %s with type %s of %s '%p'. "
                             "Check DCPS error log file for (possibly) more "
                             "information.",
                             DLRL_VALID_NAME(topicName),
                             DLRL_VALID_NAME(typeName),
                             "DK_ObjectHomeAdmin",
                             home);
    }
    _topic = gapi_topicClaim(gapiTopic, &result);
    DLRL_Exception_PROPAGATE_GAPI_RESULT(exception, result,
                                         "Failed to claim the topic handle");
    utopic = _TopicUtopic(_topic);
    if(utopic)
    {
        /* now create a proxy to this user layer topic which can be used by the DLRL
         * in a safe manner, as the user layer topic returned by the _TopicUtopic
         * operation is owned by the gapi.
         */
        utopic = u_topic(DK_DCPSUtility_ts_createProxyUserEntity(exception, u_entity(utopic)));
    }
    _EntityRelease(_topic);/* before the propagate */
    DLRL_Exception_PROPAGATE(exception);/* after the release */
    if(!utopic){
        DLRL_Exception_THROW(exception, DLRL_DCPS_ERROR,
                             "Unable to create the DCPS Topic entity for "
                             "topic %s with type %s of %s '%p'. "
                             "Check DCPS error log file for (possibly) more "
                             "information.",
                             DLRL_VALID_NAME(topicName),
                             DLRL_VALID_NAME(typeName),
                             "DK_ObjectHomeAdmin",
                             home);
    }
    *ls_topic = (void*)(*(env))->NewGlobalRef (env, jtopic);
    if(!(*ls_topic))
    {
        u_entityFree(u_entity(utopic));
        utopic = NULL;
        DLRL_Exception_THROW(exception, DLRL_OUT_OF_MEMORY,
                             "Unable to create a global ref for the "
                             "type specific topic class.");
    }

    DLRL_Exception_EXIT(exception);
    if((exception->exceptionID != DLRL_NO_EXCEPTION) && typedTopicCachedData){
        DJA_Initialisation_us_destroyTypedTopicCache(env, typedTopicCachedData);
        *topicUserData = NULL;
    }
    if(jtopic){
        (*env)->DeleteLocalRef(env, jtopic);
    }
    if(jtopicName){
        (*env)->DeleteLocalRef(env, jtopicName);
    }
    if(jtypeName){
        (*env)->DeleteLocalRef(env, jtypeName);
    }
    /* returning NULL means an error has occured */
    DLRL_INFO(INF_EXIT);
    return utopic;
}
u_writer
DJA_DCPSUtilityBridge_us_createDataWriter(
    DLRL_Exception* exception,
    void* userData,
    DK_TopicInfo* topicInfo,
    void** ls_writer)
{
    /* JNI thread env */
    JNIEnv* env = NULL;

    DJA_CachedJNITypedTopic* typedTopicCachedData = NULL;
    /* java data writer & topic entities */
    jobject jdataWriter = NULL;
    jobject jtopic = NULL;
    jobject ls_publisher = NULL;
    DK_CacheAdmin* cache = NULL;
    DK_ObjectHomeAdmin* home = NULL;
    gapi_dataWriter gapiWriter = NULL;
    _DataWriter _writer = NULL;
    gapi_returnCode_t result = GAPI_RETCODE_OK;
    u_writer uwriter = NULL;

    DLRL_INFO(INF_ENTER);
    assert(exception);
    assert(userData);
    assert(topicInfo);

    home = DK_TopicInfo_us_getOwner(topicInfo);/* no duplicate done */
    env = (JNIEnv*)userData;
    typedTopicCachedData = (DJA_CachedJNITypedTopic*)DK_TopicInfo_us_getTopicUserData(topicInfo);
    /* typedTopicCachedData may be NULL */
    cache = DK_ObjectHomeAdmin_us_getCache(home);

    /* get java object */
    jtopic = (jobject)DK_TopicInfo_us_getLSTopic(topicInfo);
    ls_publisher = jtopic ? (jobject)DK_CacheAdmin_us_getLSPublisher(cache) : NULL;

    DLRL_INFO(INF_CALLBACK, "objectHome->createDataWriter(publisher, topic)");
    jdataWriter = jtopic ? (*env)->CallStaticObjectMethod(env, cachedJNI.dcpsUtil_class,
                                                cachedJNI.dcpsUtil_createDataWriter_mid, ls_publisher, jtopic) : NULL;
    DLRL_JavaException_PROPAGATE(env, exception);
    if(!jdataWriter){
        DLRL_Exception_THROW(exception, DLRL_DCPS_ERROR,
                             "Creation of data writer failed! "
                             "Check DCPS error log file for (possibly) more "
                             "information.");
    }
    if(typedTopicCachedData)
    {
        DJA_Initialisation_loadTypedWriterCache(exception, env, typedTopicCachedData, jdataWriter);
        DLRL_Exception_PROPAGATE(exception);
    }

    DLRL_INFO(INF_DCPS, "saj_read_gapi_address(datawriter)");
    gapiWriter = jdataWriter? (gapi_dataWriter)saj_read_gapi_address(env, jdataWriter) : NULL;
    if(!gapiWriter){
        DLRL_Exception_THROW(exception, DLRL_DCPS_ERROR,
                             "Unable to create the DCPS DataWriter entity. "
                             "Check DCPS error log file for (possibly) more "
                             "information.");
    }
    _writer = gapi_dataWriterClaim(gapiWriter, &result);
    DLRL_Exception_PROPAGATE_GAPI_RESULT(exception, result,
                                         "Unable to claim data writer handle");
    uwriter = U_WRITER_GET(_writer);
    if(uwriter)
    {
        /* now create a proxy to this user layer topic which can be used by the DLRL
         * in a safe manner, as the user layer topic returned by the _TopicUtopic
         * operation is owned by the gapi.
         */
        uwriter = u_writer(DK_DCPSUtility_ts_createProxyUserEntity(exception, u_entity(uwriter)));
    }
    _EntityRelease(_writer);/* before the propagate */
    DLRL_Exception_PROPAGATE(exception);/* after the release */
    if(!uwriter){
        DLRL_Exception_THROW(exception, DLRL_DCPS_ERROR,
                             "Unable to create the DCPS DataWriter entity. "
                             "Check DCPS error log file for (possibly) more "
                             "information.");
    }
    *ls_writer = (void*)(*(env))->NewGlobalRef (env, jdataWriter);
    if (!(*ls_writer))
    {
        u_entityFree(u_entity(uwriter));
        uwriter = NULL;
        DLRL_Exception_THROW(exception, DLRL_OUT_OF_MEMORY,
                             "Not enough memory to complete operation.");
    }

    DLRL_Exception_EXIT(exception);
    if(exception->exceptionID != DLRL_NO_EXCEPTION){
        /* return null if an exception occured,
           clean the data reader if it existed
           (later an exception will be set when
            JNI raises an exception as well */
        uwriter = NULL;
    }
    if(jdataWriter){
        (*env)->DeleteLocalRef(env, jdataWriter);
    }
    DLRL_INFO(INF_EXIT);
    return uwriter;
}
u_reader
DJA_DCPSUtilityBridge_us_createDataReader(
    DLRL_Exception* exception,
    void* userData,
    DK_TopicInfo* topicInfo,
    void** ls_reader)
{
    /* JNI thread env */
    JNIEnv* env = NULL;
    DJA_CachedJNITypedTopic* typedTopicCachedData = NULL;
    jobject jtopic = NULL;
    jobject ls_participant = NULL;
    jstring jtopicName = NULL;
    DK_CacheAdmin* cache = NULL;
    jobject ls_subscriber = NULL;
    jobject jdataReader= NULL;
    DK_ObjectHomeAdmin* home = NULL;
    LOC_char* topicName = NULL;
    gapi_dataReader gapiReader = NULL;
    _DataReader _reader = NULL;
    gapi_returnCode_t result = GAPI_RETCODE_OK;
    u_reader ureader = NULL;

    DLRL_INFO(INF_ENTER);
    assert(exception);
    assert(userData);
    assert(topicInfo);

    env = (JNIEnv*)userData;
    home = DK_TopicInfo_us_getOwner(topicInfo);/* no duplicate done */
    topicName = (LOC_char*)DK_TopicInfo_us_getTopicName(topicInfo);
    assert(topicName);
    typedTopicCachedData = (DJA_CachedJNITypedTopic*)DK_TopicInfo_us_getTopicUserData(topicInfo);
    /* typedTopicCachedData may be null*/

    /* get java object */
    jtopic = (jobject)DK_TopicInfo_us_getLSTopic(topicInfo);

    /* the cache getter on the object home doesnt require a release on the returned pointer */
    cache = DK_ObjectHomeAdmin_us_getCache(home);
    ls_participant = (jobject)DK_CacheAdmin_us_getLSParticipant(cache);
    ls_subscriber = (jobject)DK_CacheAdmin_us_getLSSubscriber(cache);
    jtopicName = (*env)->NewStringUTF(env, topicName);
    DLRL_JavaException_PROPAGATE(env, exception);

    DLRL_INFO(INF_CALLBACK, "objectHome->createDataReader(participant, subscriber, topic, topicName)");
    jdataReader = (*env)->CallStaticObjectMethod(env, cachedJNI.dcpsUtil_class,
                                                 cachedJNI.dcpsUtil_createDataReader_mid,
                                                 ls_participant,
                                                 ls_subscriber,
                                                 jtopic,
                                                 jtopicName);
    DLRL_JavaException_PROPAGATE(env, exception);
    if(!jdataReader){
        DLRL_Exception_THROW(exception, DLRL_DCPS_ERROR,
                             "Creation of data reader for topic %s failed! "
                             "Check DCPS error log file for (possibly) more information.",
                             topicName);
    }

    if(typedTopicCachedData)
    {
        /* no need to undo the following action in case of an exception later on, as the typedTopicCachedData is already  */
        /* managed by the DLRL whom will ensure its cleaned properly. */
        DJA_Initialisation_loadTypedReaderCache(exception, env, typedTopicCachedData, jdataReader);
        DLRL_Exception_PROPAGATE(exception);
    }

    DLRL_INFO(INF_DCPS, "saj_read_gapi_address(datareader)");
    gapiReader = jdataReader? (gapi_dataReader)saj_read_gapi_address(env, jdataReader) : NULL;
    if(!gapiReader){
        DLRL_Exception_THROW(exception, DLRL_DCPS_ERROR,
            "Unable to create the DCPS DataReader entity for topic %s of DLRL Kernel ObjectHomeAdmin '%s'. "
            "Check DCPS error log file for (possibly) more information.",
            DLRL_VALID_NAME(topicName), DLRL_VALID_NAME(DK_ObjectHomeAdmin_us_getName(home)));
    }
    _reader = gapi_dataReaderClaim(gapiReader, &result);
    DLRL_Exception_PROPAGATE_GAPI_RESULT(exception, result, "Failed to claim the data reader handle");
    ureader = u_reader(_DataReaderUreader(_reader));
    if(ureader)
    {
        /* now create a proxy to this user layer ureader which can be used by the DLRL
         * in a safe manner, as the user layer ureader returned by the _DataReaderUreader
         * operation is owned by the gapi.
         */
        ureader = u_reader(DK_DCPSUtility_ts_createProxyUserEntity(exception, u_entity(ureader)));
    }
    _EntityRelease(_reader);/* before the propagate */
    DLRL_Exception_PROPAGATE(exception);/* after the release */
    if(!ureader){
        DLRL_Exception_THROW(exception, DLRL_DCPS_ERROR,
            "Unable to create the DCPS DataReader entity for topic %s of DLRL Kernel ObjectHomeAdmin '%s'. "
            "Check DCPS error log file for (possibly) more information.",
            DLRL_VALID_NAME(topicName), DLRL_VALID_NAME(DK_ObjectHomeAdmin_us_getName(home)));
    }

    *ls_reader = (void*)(*(env))->NewGlobalRef (env, jdataReader);
    if(!(*ls_reader))
    {
        u_entityFree(u_entity(ureader));
        ureader = NULL;
        DLRL_Exception_THROW(exception, DLRL_OUT_OF_MEMORY, "Unable to create a global ref for the type specific DataReader class.");
    }

    DLRL_Exception_EXIT(exception);
    if(exception->exceptionID != DLRL_NO_EXCEPTION){
        /* return null if an exception occured, clean the data reader if it existed (later an exception will be set when  */
        /* JNI raises an exception as well */
        ureader = NULL;
    }
    if(jtopicName){
        (*env)->DeleteLocalRef(env, jtopicName);
    }
    if(jdataReader){
        (*env)->DeleteLocalRef(env, jdataReader);
    }

    DLRL_INFO(INF_EXIT);
    return ureader;
}
예제 #5
0
d_storeResult
d_groupInfoInject(
    d_groupInfo _this,
    const d_store store,
    u_participant participant,
    d_group* group)
{
    d_storeResult result;
    u_group ugroup;
    u_partition upartition;
    v_partitionQos partitionQos;
    v_duration timeout;
    c_string name;

    if(_this && store && participant){
        result = d_topicInfoInject(_this->topic, store, participant);

        if(result == D_STORE_RESULT_OK){
           partitionQos = u_partitionQosNew(NULL);

           if(partitionQos) {
               d_storeReport(store, D_LEVEL_FINE, "PartitionQoS created.\n");

               upartition = u_partitionNew(participant, _this->partition,
                       partitionQos);

               if(upartition) {
                   name = d_topicInfoGetName(_this->topic);
                   d_storeReport(store, D_LEVEL_FINE,
                           "Partition %s created.\n", _this->partition);

                   timeout.seconds = 0;
                   timeout.nanoseconds = 0;
                   ugroup = u_groupNew(participant, _this->partition, name,
                           timeout);

                   if(ugroup) {
                       d_storeReport(store,
                               D_LEVEL_INFO, "Group %s.%s created.\n",
                               _this->partition, name);

                       *group = d_groupNew(_this->partition, name,
                               D_DURABILITY_PERSISTENT, _this->completeness,
                               _this->quality);

                       u_entityAction(u_entity(ugroup), setKernelGroup, *group);
                       u_entityFree(u_entity(ugroup));
                       result = D_STORE_RESULT_OK;
                   } else {
                       result = D_STORE_RESULT_OUT_OF_RESOURCES;
                       d_storeReport(store, D_LEVEL_SEVERE,
                               "Group %s.%s could NOT be created.\n",
                               _this->partition, name);
                       OS_REPORT_2(OS_ERROR, "d_groupInfoInject",
                               (os_int32)result,
                               "Group %s.%s could NOT be created.\n",
                               _this->partition, name);
                   }
                   c_free(name);
                   u_partitionFree(upartition);
               } else {
                   result = D_STORE_RESULT_OUT_OF_RESOURCES;
                   d_storeReport(store, D_LEVEL_SEVERE,
                           "Partition %s could NOT be created.\n",
                           _this->partition);
                   OS_REPORT_1(OS_ERROR, "d_groupInfoInject", (os_int32)result,
                           "Partition %s could NOT be created.\n",
                           _this->partition);
               }
               u_partitionQosFree(partitionQos);
           } else {
               result = D_STORE_RESULT_OUT_OF_RESOURCES;
               d_storeReport(store, D_LEVEL_SEVERE,
                       "PartitionQos could NOT be created.\n");
               OS_REPORT(OS_ERROR, "d_groupInfoInject", (os_int32)result,
                       "PartitionQos could NOT be created.\n");
           }
        }
    } else {
        result = D_STORE_RESULT_ILL_PARAM;
    }
    return result;
}
예제 #6
0
_Subscriber
_BuiltinSubscriberNew (
    u_participant uParticipant,
    _DomainParticipantFactory factory,
    _DomainParticipant participant)
{
    u_subscriber s;
    _Status status;
    _Subscriber newSubscriber = _SubscriberAlloc();
    gapi_handle handle;
    _TypeSupport typeSupport;
    gapi_dataReaderQos rQos;
    long i;

    s = u_participantGetBuiltinSubscriber(uParticipant);

    if (s) {
        newSubscriber = _SubscriberAlloc();

        if (newSubscriber != NULL) {

            _EntityInit(_Entity(newSubscriber), _Entity(participant));

            U_SUBSCRIBER_SET(newSubscriber, s);

            status = _StatusNew(_Entity(newSubscriber),
                                STATUS_KIND_SUBSCRIBER,
                                NULL, 0);
            if (status) {
                for ( i = 0; i < MAX_BUILTIN_TOPIC; i++ ) {
                    _DataReader reader = NULL;
                    _Topic topic = NULL;

                    typeSupport = _DomainParticipantFindTypeSupport(participant,
                                                                    _BuiltinTopicTypeName(i));
                    if (typeSupport) {
                        c_iter uTopicList;
                        u_topic uTopic;

                        uTopicList = u_participantFindTopic(uParticipant,
                                                            _BuiltinTopicName(i),
                                                            C_TIME_ZERO);
                        uTopic = c_iterTakeFirst(uTopicList);
                        if (uTopic) {
                            topic = _TopicFromKernelTopic(uTopic,
                                                          _BuiltinTopicName(i),
                                                          _BuiltinTopicTypeName(i),
                                                          typeSupport,
                                                          participant,
                                                          NULL);
                            while (uTopic) {
                                uTopic = c_iterTakeFirst(uTopicList);
                                /* multiple instances should not occure but
                                 * just in case this loop frees all references.
                                 */
                                assert(uTopic == NULL);
                                u_entityFree(u_entity(uTopic));
                            }
                        } else {
                            OS_REPORT_2(OS_WARNING,"_BuiltinSubscriberNew",0,
                                        "failed to resolve User layer Topic "
                                        "'%s' for Participant 0x%x",
                                        _BuiltinTopicName(i), participant);
                        }
                    } else {
                        OS_REPORT_2(OS_WARNING,"_BuiltinSubscriberNew",0,
                                    "Builtin TypeSupport for type '%s' is not "
                                    "yet registered for Participant 0x%x",
                                    _BuiltinTopicTypeName(i), participant);
                    }

                    if (topic) {
                        initBuiltinDataReaderQos(&rQos);
                        reader = _DataReaderNew(_TopicDescription(topic),
                                                typeSupport,
                                                &rQos,
                                                NULL, 0,
                                                newSubscriber);

                        _EntityRelease(topic);
                    } else {
                        OS_REPORT_2(OS_WARNING,"_BuiltinSubscriberNew",0,
                                    "failed to create Builtin Topic '%s' "
                                    "for Participant 0x%x",
                                    _BuiltinTopicName(i), participant);
                    }

                    if ( reader ) {
                        _ENTITY_REGISTER_OBJECT(_Entity(newSubscriber),
                                                (_Object)reader);
                        handle = _EntityRelease(reader);
                        gapi_entity_enable(handle);
                    }
                }
                newSubscriber->builtin = TRUE;
                _EntityStatus(newSubscriber) = status;
            } else {
                _EntityDispose(_Entity(newSubscriber));
                newSubscriber = NULL;
            }
        }
    }
    return newSubscriber;
}
예제 #7
0
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;
}
예제 #8
0
void
d_groupRemoteListenerAction(
    d_listener listener,
    d_message message)
{
    d_newGroup remote;
    d_configuration config;
    d_durability durability;
    d_admin admin;
    d_group group, group2;
    d_fellow fellow;
    c_bool createLocally, added;
    v_duration duration;
    u_group ugroup;
    d_networkAddress addr;
    c_bool result;
    d_subscriber subscriber;
    d_sampleChainListener sampleChainListener;
    d_completeness localCompleteness;

    assert(d_listenerIsValid(d_listener(listener), D_GROUP_REMOTE_LISTENER));

    remote     = d_newGroup(message);
    admin      = d_listenerGetAdmin(listener);
    durability = d_adminGetDurability(admin);
    config     = d_durabilityGetConfiguration(durability);
    addr       = d_networkAddressNew(message->senderAddress.systemId,
                                     message->senderAddress.localId,
                                     message->senderAddress.lifecycleId);
    fellow     = d_adminGetFellow(admin, addr);

    if(remote->partition && remote->topic){
        d_printTimedEvent(durability, D_LEVEL_FINEST,
                          D_THREAD_GROUP_REMOTE_LISTENER,
                          "Received remote group '%s.%s'.\n",
                          remote->partition, remote->topic);
    }
    if(fellow){
        if(d_fellowGetCommunicationState(fellow) == D_COMMUNICATION_STATE_APPROVED){
            if(!(remote->partition) && !(remote->topic)){
                d_fellowSetExpectedGroupCount(fellow, remote->alignerCount);
            } else {
                group = d_adminGetLocalGroup(admin, remote->partition,
                                             remote->topic, remote->durabilityKind);
                if(!group){
                    d_printTimedEvent(durability, D_LEVEL_FINE,
                                            D_THREAD_GROUP_REMOTE_LISTENER,
                                            "Received remote group %s.%s which is locally unknown.\n",
                                            remote->partition, remote->topic);

                    /* Group unknown locally, check if it is in the alignee namespace.
                     */
                    createLocally = d_adminGroupInAligneeNS(
                                                admin, remote->partition,
                                                remote->topic,
                                                remote->durabilityKind);

                    if(createLocally == TRUE){
                        group = d_groupNew(remote->partition, remote->topic,
                                           remote->durabilityKind,
                                           remote->completeness, remote->quality);
                        added = d_fellowAddGroup(fellow, group);
                        d_fellowSetExpectedGroupCount(fellow, remote->alignerCount);

                        if(added == FALSE){
                            d_groupFree(group);
                            group = d_fellowGetGroup(fellow, remote->partition,
                                                     remote->topic,
                                                     remote->durabilityKind);

                            if(group){
                                d_groupUpdate(group, remote->completeness,
                                              remote->quality);
                                d_groupFree(group);
                            }
                        }
                        /* Group unknown locally, check if it should be aligned
                         * initially.
                         */
                        createLocally = d_adminGroupInInitialAligneeNS(
                                                    admin, remote->partition,
                                                    remote->topic,
                                                    remote->durabilityKind);

                        if(createLocally == TRUE){
                            d_printTimedEvent(durability, D_LEVEL_FINE,
                                                D_THREAD_GROUP_REMOTE_LISTENER,
                                                "Remote group %s.%s in initial alignee namespace.\n",
                                                remote->partition, remote->topic);

                            duration.seconds = 0;
                            duration.nanoseconds = 10000000;

                            ugroup = u_groupNew(
                                    u_participant(d_durabilityGetService(durability)),
                                    remote->partition, remote->topic, duration);

                            if(ugroup){
                                d_printTimedEvent(durability, D_LEVEL_FINE,
                                                D_THREAD_GROUP_REMOTE_LISTENER,
                                                "Remote group %s.%s with quality %d created locally.\n",
                                                remote->partition, remote->topic, remote->quality.seconds);
                                u_entityFree(u_entity(ugroup));
                            } else {
                                d_printTimedEvent(durability, D_LEVEL_WARNING,
                                    D_THREAD_GROUP_REMOTE_LISTENER,
                                    "Remote group %s.%s with quality %d could NOT be created locally.\n",
                                    remote->partition, remote->topic, remote->quality.seconds);
                                /**
                                 * TODO: quality must not be taken over
                                 * from remote.
                                 */
                                group2 = d_groupNew(remote->partition, remote->topic,
                                               remote->durabilityKind,
                                               D_GROUP_INCOMPLETE,
                                               remote->quality);
                                result = d_groupCreationQueueAdd(
                                    d_groupRemoteListener(listener)->groupCreationQueue,
                                    group2);

                                if(result == FALSE){
                                    d_printTimedEvent(durability, D_LEVEL_FINER,
                                            D_THREAD_GROUP_REMOTE_LISTENER,
                                            "Remote group %s.%s already in creation queue. Skipping this one.\n",
                                            remote->partition, remote->topic);
                                    d_groupFree(group2);
                                }
                            }
                        } else {
                            d_printTimedEvent(durability, D_LEVEL_FINE,
                                            D_THREAD_GROUP_REMOTE_LISTENER,
                                            "Remote group %s.%s in alignee namespace, but not initial.\n",
                                            remote->partition, remote->topic);
                        }
                    } else {
                        d_printTimedEvent(durability, D_LEVEL_INFO,
                            D_THREAD_GROUP_REMOTE_LISTENER,
                            "Remote group '%s.%s' is not in alignee namespace.\n",
                            remote->partition, remote->topic);
                    }
                } else {
                    localCompleteness = d_groupGetCompleteness(group);
                    group = d_fellowGetGroup(fellow, remote->partition,
                                                     remote->topic,
                                                     remote->durabilityKind);

                    if(group){
                        d_groupUpdate(group, remote->completeness,
                                      remote->quality);
                        d_printTimedEvent(durability, D_LEVEL_FINEST,
                              D_THREAD_GROUP_REMOTE_LISTENER,
                              "Updating remote group '%s.%s' completeness: '%d'.\n",
                              remote->partition, remote->topic, remote->completeness);
						d_groupFree(group);
                    } else if(localCompleteness != D_GROUP_COMPLETE){
                        group = d_groupNew(remote->partition, remote->topic,
                                           remote->durabilityKind,
                                           remote->completeness, remote->quality);
                        added = d_fellowAddGroup(fellow, group);

                        if(added == FALSE){
                            d_groupFree(group);
                            group = d_fellowGetGroup(fellow, remote->partition,
                                                     remote->topic,
                                                     remote->durabilityKind);

                            if(group){
                                d_groupUpdate(group, remote->completeness,
                                              remote->quality);
                                d_groupFree(group);
                            }
                        } else {

                            d_printTimedEvent(durability, D_LEVEL_FINEST,
                                                      D_THREAD_GROUP_REMOTE_LISTENER,
                                                      "Remote group '%s.%s' with completeness: '%d' registered for fellow.\n",
                                                      remote->partition, remote->topic, remote->completeness);
                        }
                    }
                    /* A complete group might be interesting in case there are
                     * still unfullfilled chain requests.
                     */
                    if(remote->completeness == D_GROUP_COMPLETE){
                        d_printTimedEvent(durability, D_LEVEL_FINEST,
                                                  D_THREAD_GROUP_REMOTE_LISTENER,
                                                  "Remote group '%s.%s' complete, check for unfullfilled chains.\n",
                                                  remote->partition, remote->topic);
                        subscriber = d_adminGetSubscriber(admin);
                        sampleChainListener = d_subscriberGetSampleChainListener(subscriber);

                        group = d_groupNew(remote->partition, remote->topic,
                                           remote->durabilityKind,
                                           remote->completeness, remote->quality);

                        d_sampleChainListenerTryFulfillChains(sampleChainListener, group);

                        d_groupFree(group);
                    }
                }
            }
        } else {
            d_printTimedEvent(durability, D_LEVEL_WARNING,
                       D_THREAD_GROUP_REMOTE_LISTENER,
                      "Fellow not approved, so ignore the message.\n");
        }
        d_fellowFree(fellow);
    } else {
        d_printTimedEvent(durability, D_LEVEL_WARNING,
                D_THREAD_GROUP_REMOTE_LISTENER,
                "Fellow unknown so far, so ignore the message.\n");
    }
    d_networkAddressFree(addr);

    return;
}