Пример #1
0
/* Create source */
c_iter
idl_fileMapGetObjects(
    const idl_fileMap fileMap,
    const char *fileName)
{
    idl_file file;
    c_iter result;

    result = 0;

    if(fileMap != NULL) {
        /* Lookup file */
        file = c_iterResolve(fileMap->files, idl_fileCompare, (c_iterResolveCompareArg)fileName);
        if (file) {
            result = c_iterNew(0);

            /* Walk metaobjects in filemap, add to source. */
            if(file->contains) {
                c_iterWalk(file->contains, (c_iterWalkAction)idl_fileMapFillList, result);
            }
        }
    }

    return result;
}
Пример #2
0
c_array
c_metaArray(
    c_metaObject scope,
    c_iter iter,
    c_metaKind kind)
{
    c_long i;
    struct copyToArrayArg arg;
    c_type type;

    if (kind) {
        /* suppress warnings */
    }
    i = c_iterLength(iter);
    if (i == 0) {
        arg.a = NULL;
    } else {
        type = c_object_t(c__getBase(scope));
        arg.a = c_arrayNew(type,i);
        arg.index = 0;
        c_iterWalk(iter,copyToArray,&arg);
        c_iterFree(iter);
        c_free(type);
    }
    return arg.a;
}
Пример #3
0
c_iter
u_readerLookupQueries(
    u_reader _this)
{
    c_iter queries = NULL;
    os_result r;

    if (_this) {
        if(u_entityOwner(u_entity(_this))) {
            r = os_mutexLock(&_this->mutex);
            if (r == os_resultSuccess) {
                c_iterWalk(_this->queries, collect_queries, &queries);
                os_mutexUnlock(&_this->mutex);
            } else {
                OS_REPORT(OS_WARNING,
                          "u_readerLookupQueries",0,
                          "Failed to lock Reader.");
            }
        }
    } else {
        OS_REPORT(OS_WARNING,
                  "u_readerLookupQueries",0,
                  "No Reader specified.");
    }
    return queries;
}
Пример #4
0
/* Resolve the file which is related to the specified meta object in the specified file map */
c_char *
idl_fileMapResolve(
    /* QAC EXPECT 3673; No solution to the message here, but no problem either */
    const idl_fileMap fileMap,
    const c_baseObject object)
{
    /* QAC EXPECT 5007; will not use wrapper */
    idl_map map = os_malloc((size_t)C_SIZEOF(idl_map));
    c_char *fileName = NULL;

    if (fileMap != NULL) {
	/* map will contain the meta object reference before the c_iterWalk */
        map->object = object;
        map->fileName = NULL;
        c_iterWalk(fileMap->files, (c_iterWalkAction)idl_searchObject, map);
	/* map will contain the meta object reference and fileName reference
	   after the c_iterWalk.
	*/
        fileName = map->fileName;
        if (fileName == NULL) {
            /* file name is undefined for implicit defined types */
            fileName = os_strdup("");
        }
        /* QAC EXPECT 5007; will not use wrapper */
        os_free(map);
    }
    return fileName;
}
Пример #5
0
static void *
dispatch(
    void *o)
{
    u_dispatcher _this;
    v_observer claim;
    struct listenerExecArg arg;
    u_result result;

    _this = u_dispatcher(o);
    if (_this != NULL) {
        if (_this->startAction) {
            _this->startAction(_this, _this->actionData);
        }
        os_mutexLock(&_this->mutex);
        result = u_entityReadClaim(u_entity(_this), (v_entity*)(&claim));
        if(result == U_RESULT_OK) {
            assert(claim);
            while ((!(_this->event & V_EVENT_OBJECT_DESTROYED)) &&
                   (_this->listeners != NULL) &&
                   (c_iterLength(_this->listeners) > 0)) {

                os_mutexUnlock(&_this->mutex);
                _this->event = v_observerWait(claim);
                os_mutexLock(&_this->mutex);
                if (!(_this->event & V_EVENT_OBJECT_DESTROYED)) {
                    /* do not call listeners when  object is destroyed! */
                    arg.mask = 0;
                    arg.o = _this;
                    c_iterWalk(_this->listeners,
                               (c_iterWalkAction)listenerExecute,
                               &arg);
                }
            }
            _this->threadId = OS_THREAD_ID_NONE;
            result = u_entityRelease(u_entity(_this));
            if (result != U_RESULT_OK) {
                OS_REPORT(OS_ERROR, "u_dispatcher::dispatch", 0,
                          "Release observer failed.");
            }
        } else {
            OS_REPORT(OS_WARNING, "u_dispatcher::dispatch", 0,
                      "Failed to claim Dispatcher.");
        }
        os_mutexUnlock(&_this->mutex);
        if (_this->stopAction) {
            _this->stopAction(_this, _this->actionData);
        }
    } else {
        OS_REPORT(OS_ERROR, "u_dispatcher::dispatch", 0,
                  "No dispatcher specified.");
    }
    return NULL;
}
Пример #6
0
c_bool idl_fileMapCheckFinalized(
    const idl_fileMap fileMap,
    const char* fileName)
{
    idl_file file;
    int count;

    count = 0;

    if(fileMap != NULL) {
        file = c_iterResolve(fileMap->files, (c_iterResolveCompare)idl_fileCompare, (c_iterResolveCompareArg)fileName);
        if(file) {

            c_iterWalk(file->contains, (c_iterWalkAction)idl_checkFinalized, &count);
        }
    }
    return !count;
}
Пример #7
0
void
v_groupStreamInit(
    v_groupStream stream,
    const c_char *name,
    v_subscriber subscriber,
    v_readerQos qos,
    v_statistics rs,
    c_iter expr)
{
    v_kernel kernel;

    assert(C_TYPECHECK(stream, v_groupStream));
    assert(C_TYPECHECK(subscriber, v_subscriber));

    kernel = v_objectKernel(subscriber);

    stream->groups = c_setNew(v_kernelType(kernel,K_GROUP));
    stream->expr = c_listNew(c_resolve(c_getBase(stream), "::c_string"));
    c_iterWalk(expr, fillExprList, stream->expr);

    v_readerInit(v_reader(stream),name,subscriber,qos,rs,TRUE);
    v_subscriberAddReader(subscriber,v_reader(stream));
}
Пример #8
0
c_iter
u_subscriberLookupReaders(
    u_subscriber _this,
    const c_char *topic_name)
{
    struct collect_readers_arg arg;
    u_result result;

    /* topic_name == NULL is treated as wildcard '*' */
    arg.topic_name = topic_name;
    arg.readers = NULL;

    result = u_entityLock(u_entity(_this));
    if (result == U_RESULT_OK) {
        c_iterWalk(_this->readers, collect_readers, &arg);
        u_entityUnlock(u_entity(_this));
    } else {
        OS_REPORT(OS_WARNING,
                  "u_subscriberLookupReaders",0,
                  "Failed to lock Subscriber.");
    }
    return arg.readers;
}
Пример #9
0
u_result
u_waitsetSetEventMask(
    const u_waitset _this,
    u_eventMask eventMask)
{
    u_result result;
    os_result osr;

    assert(_this != NULL);

    osr = os_mutexLock_s(&_this->mutex);
    if (osr == os_resultSuccess) {
        _this->eventMask = eventMask;
        c_iterWalk(_this->entries, set_event_mask, &eventMask);
        os_mutexUnlock(&_this->mutex);
        result = U_RESULT_OK;
    } else {
        result = U_RESULT_INTERNAL_ERROR;
        OS_REPORT(OS_WARNING, "u_waitSetEventMask", result,
                  "Could not claim waitset.");
    }
    return result;
}
Пример #10
0
c_iter
v_partitionAdminRemove(
    v_partitionAdmin da,
    const c_char *partitionExpr)
{
    /* partitionExpr: expression or absolute partition name */
    c_iter partitions;
    v_partition d;

    partitions = NULL;
    c_mutexLock(&da->mutex);
    if (v_partitionExpressionIsAbsolute(partitionExpr)) {
        v__partitionAdminRemove(da, partitionExpr, &d);
        partitions = c_iterNew(d);
    } else {
        if (v_partitionAdminRemoveExpression(da, partitionExpr)) {
            partitions = v_resolvePartitions(v_objectKernel(da), partitionExpr);
            c_iterWalk(partitions, removePartition, (c_voidp)da->partitions);
        } /* else expression already member */
    }
    c_mutexUnlock(&da->mutex);

    return partitions;
}
/* TODO: NOT THREAD SAFE */
static c_iter
updateNameSpaces(
    d_nameSpacesRequestListener listener)
{
    d_admin admin;
    c_ulong total;
    c_iter nameSpaces;
    struct updateNsWalkData walkData;

    admin = d_listenerGetAdmin (d_listener(listener));

    /* Update nameSpaces */
    nameSpaces = c_iterNew (NULL);
    walkData.listener = listener;
    walkData.nameSpaces = nameSpaces;

    d_adminNameSpaceWalk (admin, updateNameSpacesWalk, &walkData);
    total = c_iterLength (walkData.nameSpaces);

    /* Update totals */
    c_iterWalk (walkData.nameSpaces, updateNameSpacesTotalWalk, &total);

    return walkData.nameSpaces;
}
Пример #12
0
c_field
c_fieldNew (
    c_type type,
    const c_char *fieldName)
{
    c_array path;
    c_field field;
    c_metaObject o;
    c_long n,length;
    c_address offset;
    c_iter nameList, refsList;
    c_string name;
    c_base base;

    if ((fieldName == NULL) || (type == NULL)) {
        OS_REPORT(OS_ERROR,
                  "c_fieldNew failed",0,
                  "illegal parameter");
        return NULL;
    }

    base = c__getBase(type);
    if (base == NULL) {
        OS_REPORT(OS_ERROR,
                  "c_fieldNew failed",0,
                  "failed to retreive base");
        return NULL;
    }

    nameList = c_splitString(fieldName,".");
    length = c_iterLength(nameList);
    field = NULL;

    if (length > 0) {
        o = NULL;
        offset = 0;
        refsList = NULL;
        path = c_newArray(c_fieldPath_t(base),length);
        if (path) {
            for (n=0;n<length;n++) {
                name = c_iterTakeFirst(nameList);
                o = c_metaResolve(c_metaObject(type),name);
                os_free(name);
                if (o == NULL) {
                    c_iterWalk(nameList,(c_iterWalkAction)os_free,NULL);
                    c_iterFree(nameList);
                    c_iterFree(refsList);
                    c_free(path);
                    return NULL;
                }
                path[n] = o;
                switch (c_baseObject(o)->kind) {
                case M_ATTRIBUTE:
                case M_RELATION:
                    type = c_property(o)->type;
                    offset += c_property(o)->offset;
                break;
                case M_MEMBER:
                    type = c_specifier(o)->type;
                    offset += c_member(o)->offset;
                break;
                default:
                    c_iterWalk(nameList,(c_iterWalkAction)os_free,NULL);
                    c_iterFree(nameList);
                    c_iterFree(refsList);
                    c_free(path);
                    return NULL;
                }
                switch (c_baseObject(type)->kind) {
                case M_INTERFACE:
                case M_CLASS:
                case M_COLLECTION:
                    /*Longs are inserted in an iterator? Explanation please...*/
                    refsList = c_iterInsert(refsList,(c_voidp)offset);
                    offset = 0;
                break;
                default:
                break;
                }
            }
            if (offset > 0) {
                refsList = c_iterInsert(refsList,(c_voidp)offset);
            }


            field = c_new(c_field_t(base));
            field->name = c_stringNew(base,fieldName);
            field->path = path;
            field->type = c_keep(type);
            field->kind = c_metaValueKind(o);
            field->refs = NULL;

            if (refsList) {
                length = c_iterLength(refsList);
                field->offset = 0;
                if (length > 0) {
                    field->refs = c_newArray(c_fieldRefs_t(base),length);
                    if (field->refs) {
                        for (n=(length-1);n>=0;n--) {
                            field->refs[n] = c_iterTakeFirst(refsList);
                        }
                    } else {
                        OS_REPORT(OS_ERROR,
                                  "c_fieldNew failed",0,
                                  "failed to allocate field->refs array");
                        c_free(field);
                        field = NULL;
                    }
                }
                c_iterFree(refsList);
            } else {
                field->offset = offset;
            }
        } else {
            OS_REPORT(OS_ERROR,
                      "c_fieldNew failed",0,
                      "failed to allocate field->path array");
            c_iterWalk(nameList,(c_iterWalkAction)os_free,NULL);
            c_iterFree(nameList);
        }
        c_iterFree(nameList);
    } else {
        OS_REPORT_1(OS_ERROR,
                    "c_fieldNew failed",0,
                    "failed to process field name <%s>",
                    fieldName);
    }
    return field;
}
Пример #13
0
c_bool
v_partitionAdminSet(
    v_partitionAdmin da,
    v_partitionPolicy partitionExpr,
    c_iter *addedPartitions,
    c_iter *removedPartitions)
{
    c_iter                   dexpressions;    /* iterator of partition expressions */
    c_char                   *dexpr;          /* partition expression */
    v_partitionInterest         di;
    struct resolvePartitionsArg resolveArg;
    struct updatePartitionsArg  updateArg;

    assert(C_TYPECHECK(da, v_partitionAdmin));
    assert(removedPartitions != NULL);
    assert(addedPartitions != NULL);

    *removedPartitions = NULL;
    *addedPartitions = NULL;

    resolveArg.kernel = v_objectKernel(da);

    c_mutexLock(&da->mutex);
    /*
     * The absolute partition names will be added at the end of
     * the algorithm.
     * The partition expressions in the parameter of partitionExpr,
     * replace the existing in da->partitionInterests.
     */
    c_free(da->partitionInterests);
    da->partitionInterests = c_tableNew(v_kernelType(resolveArg.kernel, K_DOMAININTEREST),
                                        "expression");
    assert(c_count(da->partitionInterests) == 0);
    dexpressions = v_partitionPolicySplit(partitionExpr);
    if (dexpressions == NULL) {
        /* switch to default */
        *addedPartitions = c_iterInsert(*addedPartitions, v_partitionNew(resolveArg.kernel, "", NULL));
    } else {
        dexpr = (c_char *)c_iterTakeFirst(dexpressions);
        while (dexpr != NULL) {
            if (v_partitionExpressionIsAbsolute(dexpr)) {
                *addedPartitions = c_iterInsert(*addedPartitions,
                                                v_partitionNew(resolveArg.kernel, dexpr, NULL));
                /* ref transferred to addedPartitions */
            } else {
                di = v_partitionInterestNew(resolveArg.kernel, (const c_char *)dexpr);
                c_tableInsert(da->partitionInterests, di);
                c_free(di);
            }
            os_free(dexpr);
            dexpr = (c_char *)c_iterTakeFirst(dexpressions);
        }
        c_iterFree(dexpressions);
    }

    /*
     * The given expressions are now divided across
     * 'addedpartitions' and 'da->partitionInterests'.
     * Now first add partitions to 'addedpartitions' that fit the
     * expressions in 'da->partitionInterests'.
     */
    resolveArg.partitions = addedPartitions;
    c_tableWalk(da->partitionInterests, resolvePartitions, (c_voidp)&resolveArg);

    /*
     * Now 'addedpartitions' contains all partitions to be added
     * by the publisher/subscriber.
     * 'da->partitions' contains the old set of partitions.
     * We must check whether those partitions must remain in
     * the set or must be removed.
     * For every partition in 'da->partitions' do
     *    if partition in 'addedpartitions' then remove from 'addedpartitions'
     *    else add to 'removedpartitions'
     * For every partition in 'removedpartitions' remove from 'da->partitions'.
     */
    updateArg.addPartitions = addedPartitions;
    updateArg.removePartitions = removedPartitions;
    c_tableWalk(da->partitions, updatePartitions, (c_voidp)&updateArg);

    c_iterWalk(*removedPartitions, removePartition, (c_voidp)da->partitions);

    /*
     * The da->partitions now contains partitions that still comply to new
     * partitionPolicy. So all partitions in added partitions, must be added
     * to da->partitions, so it reflects all connected partitions.
     */
    c_iterWalk(*addedPartitions, addPartition, (c_voidp)da->partitions);
    c_mutexUnlock(&da->mutex);

    return TRUE;
}
Пример #14
0
static int
generate_cf_file(
   config_t *cfg,
   const cf_element root)
{
   int i = 0;
   c_iter services = NULL;
   c_iter apps = NULL;
   struct serviceInfo *si;
   struct applicationInfo *ai;
   FILE *file;
   FILE *xml;
   c_iter affinityIter;
   int success = 1;

   file = fopen( cfg->ofname, "w+" );
   if ( file )
   {
#ifdef TARGET_VXWORKS_KM
      fprintf( file,
               "#include \"os_EntryPoints.h\"\n"
               "#include \"include/os_dynamicLib_plugin.h\"\n"
               "#include \"os.h\"\n"
               "#include \"taskLib.h\"\n"
               "\n"
               "int ospl_spliced(char *);\n" );
#else
      fprintf( file,
               "#include \"os_EntryPoints.h\"\n"
               "#include \"os.h\"\n"
               "\n"
               "OS_API_IMPORT OPENSPLICE_ENTRYPOINT_DECL(ospl_spliced);\n" );
#endif
      if ( root != NULL )
      {
         services = getKnownServices(root);
         apps = getKnownApplications(root);
         c_iterWalk(services, genServiceEntryPointDecl, file);
         c_iterWalk(apps, genAppEntryPointDecl, file);
      }

      if ( cfg->enableDynamicLoad )
      {
         fprintf( file,
                  "\n"
                  "struct os_dynamicLoad_plugin *os_dynamicLibPlugin = &os_dynamicLibPluginImpl;\n");
      }
      else
      {
         fprintf( file,
                  "\n"
                  "struct os_dynamicLoad_plugin *os_dynamicLibPlugin = NULL;\n");
      }

      fprintf( file,
               "\n"
               "struct os_librarySymbols os_staticLibraries[] =\n"
               "{\n");
      if ( !cfg->excludeXML )
      {
         fprintf( file,
                  "   {\n"
                  "      \"spliced\",\n"
                  "      (os_entryPoint[])\n"
                  "      {\n"
                  "         { \"ospl_spliced\", ospl_spliced },\n"
                  "         { NULL, NULL }\n"
                  "      }\n"
                  "   },\n");
      }
      if ( root != NULL )
      {
         /* Generate address space entry for each service */
         while ( (si = (struct serviceInfo*)c_iterTakeFirst(services)) != 0
                 && success)
         {
#ifdef TARGET_VXWORKS_KM
            fprintf( file,
                     "   {\n"
                     "      \"%s\",\n"
                     "      (os_entryPoint[])\n"
                     "      {\n"
                     "         { \"%s\", ospl_%s },\n"
                     "         { NULL, NULL }\n"
                     "      }\n"
                     "   },\n",
                     si->command, si->command, si->command );
#else
            fprintf( file,
                     "   {\n"
                     "      \"%s\",\n"
                     "      (os_entryPoint[])\n"
                     "      {\n"
                     "         { \"ospl_%s\", ospl_%s },\n"
                     "         { NULL, NULL }\n"
                     "      }\n"
                     "   },\n",
                     si->command, si->command, si->command );
#endif
            os_free(si);
         }
         c_iterFree(services);

         while ( (ai = (struct applicationInfo*)c_iterTakeFirst(apps)) != 0
                 && success)
         {
            fprintf( file,
                     "   { \n"
                     "      \"%s\",\n"
                     "      (os_entryPoint[])\n"
                     "      {\n"
                     "         { \"%s\", %s },\n"
                     "         { \"\", NULL }\n"
                     "      }\n"
                     "   },\n",
                     ai->libname, ai->command, ai->command );
            os_free(ai);
         }
         c_iterFree(apps);
      }
      fprintf( file,
               "   {\n"
               "      NULL,\n"
               "      (os_entryPoint[])\n"
               "      {\n"
               "         { NULL, NULL }\n"
               "      }\n"
               "   }\n"
               "};\n" );

      /* Generate environment array */
      fprintf( file,
               "\n"
               "char *os_environ[] =\n"
               "{\n" );
      for ( i=0; cfg->env[i]; i++ )
      {
          fprintf( file, "   \"%s\",\n", cfg->env[i]);
      }
      fprintf( file,
               "   NULL\n"
               "};  \n" );


#ifdef TARGET_VXWORKS_KM
      fprintf( file,
               "\n"
               "void setCPUAffinityHook()\n"
               "{\n");
      if ( root != NULL )
      {
         affinityIter = getCPUAffinities(root);
         if ( affinityIter != NULL )
         {
            fprintf( file,
                     "   cpuset_t affinity;\n"
                     "   CPUSET_ZERO(affinity);\n");
            c_iterWalk(affinityIter, genCPUAffinity_SET, file);
            fprintf( file,
                     "   taskCpuAffinitySet (0, affinity);\n");
         }
      }
      fprintf( file,
               "}\n");
#endif

      if ( !cfg->excludeXML )
      {
         if ( !strncmp( cfg->ifuri, URI_FILESCHEMA, sizeof(URI_FILESCHEMA)-1 ))
         {
            size_t totalchars=0;
            char buf[16];
            size_t index;
            size_t readchars;
            /* Copy the xml file in as a hex array */
            fprintf( file,
                     "\n"
                     "char ospl_xml_data[] =\n"
                     "{\n");
            xml = fopen( &cfg->ifuri[sizeof(URI_FILESCHEMA)-1], "r" );
            if ( xml )
            {
               while ( (readchars = fread( buf, 1, sizeof(buf), xml )) != 0 )
               {
                  totalchars+=readchars;
                  fprintf(file, "   " );
                  for ( index=0; index<readchars; index++ )
                  {
                     fprintf(file, "0x%02x, ", buf[index]);
                  }
                  fprintf(file, "\n" );
               }
               fprintf(file,
                       "   0x0\n"
                       "};\n"
                       "size_t ospl_xml_data_size = %d;\n",
                       (int)totalchars);
               fclose(xml);
            }
            else
            {
               fprintf(stderr, "ERROR: could not open \"%s\"", &cfg->ifuri[sizeof(URI_FILESCHEMA)-1] );
               print_usage(cfg->progname);
            }
         }
         else
         {
            fprintf(stderr, "ERROR: only file URIs are supported\n");
            print_usage(cfg->progname);
         }
      }
      else
      {
         fprintf( file,
                  "\n"
                  "char ospl_xml_data[] = { '\\0' };\n"
                  "size_t ospl_xml_data_size = 0;\n");
      }
      fclose(file);
   }

   if ( !success )
   {
      /* Erase part generated file */
      unlink( cfg->ofname );
   }

   return(success);
}
Пример #15
0
void
d_nameSpacesListenerAction(
    d_listener listener,
    d_message message)
{
    d_durability durability;
    d_admin admin;
    d_publisher publisher;
    d_fellow fellow;
    c_bool allowed;
    d_nameSpace nameSpace, localNameSpace, oldFellowNameSpace;
    c_ulong count;
    d_configuration config;
    d_nameSpacesRequest nsRequest;
    d_networkAddress sender;
    d_subscriber subscriber;
    d_sampleChainListener sampleChainListener;
    struct compatibilityHelper helper;
    d_adminStatisticsInfo info;
    c_bool added;
    os_time srcTime , curTime, difTime, maxDifTime;
    struct checkFellowMasterHelper fellowMasterHelper;
    d_name role;
    c_iter fellowNameSpaces;
    d_nameSpace ns;

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

    admin               = d_listenerGetAdmin(listener);
    publisher           = d_adminGetPublisher(admin);
    durability          = d_adminGetDurability(admin);
    config              = d_durabilityGetConfiguration(durability);
    fellowNameSpaces    = NULL;

    d_printTimedEvent         (durability, D_LEVEL_FINE,
                               D_THREAD_NAMESPACES_LISTENER,
                               "Received nameSpace from fellow %d (his master: %d, confirmed: %d, mergeState: %s, %d).\n",
                               message->senderAddress.systemId,
                               d_nameSpaces(message)->master.systemId,
                               d_nameSpaces(message)->masterConfirmed,
                               d_nameSpaces(message)->state.role,
                               d_nameSpaces(message)->state.value);

    sender = d_networkAddressNew(message->senderAddress.systemId,
                               message->senderAddress.localId,
                               message->senderAddress.lifecycleId);

    fellow = d_adminGetFellow(admin, sender);

    if(!fellow){
        d_printTimedEvent (durability, D_LEVEL_FINE,
                           D_THREAD_NAMESPACES_LISTENER,
                           "Fellow %d unknown, administrating it.\n",
                           message->senderAddress.systemId);
        fellow = d_fellowNew(sender, message->senderState);
        d_fellowUpdateStatus(fellow, message->senderState, v_timeGet());
        added = d_adminAddFellow(admin, fellow);

        if(added == FALSE){
            d_fellowFree(fellow);
            fellow = d_adminGetFellow(admin, sender);
            assert(fellow);
        } else {
            fellow = d_adminGetFellow(admin, sender); /*Do this to allow fellowFree at the end*/
            nsRequest = d_nameSpacesRequestNew(admin);
            d_messageSetAddressee(d_message(nsRequest), sender);
            d_publisherNameSpacesRequestWrite(publisher, nsRequest, sender);
            d_nameSpacesRequestFree(nsRequest);
        }
    }
    d_fellowUpdateStatus(fellow, message->senderState, v_timeGet());

    nameSpace = d_nameSpaceFromNameSpaces(config, d_nameSpaces(message));

    if(d_fellowGetCommunicationState(fellow) == D_COMMUNICATION_STATE_APPROVED){

        /* Get old namespace of fellow */
        oldFellowNameSpace = d_nameSpaceCopy (d_fellowGetNameSpace (fellow, nameSpace));

        /* Update master of fellow nameSpace */
        added = d_fellowAddNameSpace(fellow, nameSpace);

        /* Create namespace with local policy (if a match exists) */
        localNameSpace = d_nameSpaceNew (config, d_nameSpaceGetName(nameSpace));

        /* If namespace is created, add to administration */
        if (localNameSpace) {
            /* Copy partitions to local nameSpace */
            d_nameSpaceCopyPartitions (localNameSpace, nameSpace);
            d_adminAddNameSpace (admin, localNameSpace);
            d_nameSpaceFree (localNameSpace);
        }

        /* If fellow is master for a namespace, report it to admin */
        fellowMasterHelper.admin = admin;
        fellowMasterHelper.fellow = d_fellowGetAddress(fellow);
        fellowMasterHelper.oldNameSpace = oldFellowNameSpace;
        checkFellowMasterWalk (nameSpace, &fellowMasterHelper);
        d_free (fellowMasterHelper.fellow);

        /* If the namespace was not added to the fellow (because it already existed there), free it */
        if(!added){
            d_nameSpaceFree(nameSpace);
        }

        d_nameSpaceFree (oldFellowNameSpace);

    } else {
        info = d_adminStatisticsInfoNew();
        d_fellowSetExpectedNameSpaces(fellow, d_nameSpaces(message)->total);
        d_fellowAddNameSpace(fellow, nameSpace);
        count = d_fellowNameSpaceCount(fellow);

        if(count == d_nameSpaces(message)->total){
            allowed = isFellowStateCompatible(durability, fellow);

            if(allowed == TRUE){
                config = d_durabilityGetConfiguration(durability);
                helper.fellow = fellow;
                helper.compatible = TRUE;

                d_adminNameSpaceWalk (admin, areFellowNameSpacesCompatible, &helper);

                if(helper.compatible == TRUE){

                    if(config->timeAlignment == TRUE){
                        curTime.tv_sec     = d_readerListener(listener)->lastInsertTime.seconds;
                        curTime.tv_nsec    = d_readerListener(listener)->lastInsertTime.nanoseconds;
                        srcTime.tv_sec     = d_readerListener(listener)->lastSourceTime.seconds;
                        srcTime.tv_nsec    = d_readerListener(listener)->lastSourceTime.nanoseconds;
                        maxDifTime.tv_sec  = 1; /*1s*/
                        maxDifTime.tv_nsec = 0;
                        difTime            = os_timeAbs(os_timeSub(curTime, srcTime));

                        if(os_timeCompare(difTime, maxDifTime) == OS_MORE){
                            d_printTimedEvent (durability, D_LEVEL_WARNING,
                               D_THREAD_NAMESPACES_LISTENER,
                               "Estimated time difference including latency with " \
                               "fellow %d is %f seconds, which is larger then " \
                               "expected.\n",
                               message->senderAddress.systemId,
                               os_timeToReal(difTime));
                            OS_REPORT_2(OS_WARNING, D_CONTEXT, 0,
                                "Estimated time difference including latency " \
                                "with fellow '%d' is larger then expected " \
                                "(%f seconds). Durability alignment might not be " \
                                "reliable. Please align time between these nodes " \
                                "and restart.",
                                message->senderAddress.systemId,
                                os_timeToReal(difTime));
                        } else {
                            d_printTimedEvent (durability, D_LEVEL_FINER,
                               D_THREAD_NAMESPACES_LISTENER,
                               "Estimated time difference including latency with " \
                               "fellow %d is %f seconds.\n",
                               message->senderAddress.systemId,
                               os_timeToReal(difTime));
                        }
                    }

                    /* Set role of fellow (take native role from namespace) */
                    role = d_nameSpaceGetRole(nameSpace);
                    d_fellowSetRole (fellow, role);
                    os_free (role);

                    d_fellowSetCommunicationState(fellow, D_COMMUNICATION_STATE_APPROVED);
                    info->fellowsApprovedDif += 1;
                    subscriber = d_adminGetSubscriber(admin);
                    sampleChainListener = d_subscriberGetSampleChainListener(subscriber);

                    if(sampleChainListener){
                        d_sampleChainListenerTryFulfillChains(sampleChainListener, NULL);
                    }

                    /* Check if the fellow is master for one or more namespaces and report this to admin */
                    fellowNameSpaces = c_iterNew(NULL);

                    /* Collect fellow namespaces */
                    d_fellowNameSpaceWalk (fellow, collectFellowNsWalk, fellowNameSpaces);

                    fellowMasterHelper.admin = admin;
                    fellowMasterHelper.fellow = d_fellowGetAddress(fellow);
                    fellowMasterHelper.oldNameSpace = NULL;
                    c_iterWalk (fellowNameSpaces, checkFellowMasterWalk, &fellowMasterHelper);

                    while ((ns = c_iterTakeFirst(fellowNameSpaces))) {
                        d_nameSpaceFree(ns);
                    }
                    c_iterFree(fellowNameSpaces);

                    d_free (fellowMasterHelper.fellow);

                } else {
                    info->fellowsIncompatibleDataModelDif += 1;

                    d_printTimedEvent (durability, D_LEVEL_WARNING,
                                   D_THREAD_NAMESPACES_LISTENER,
                                   "Communication with fellow %d NOT approved, because data model is not compatible\n",
                                   message->senderAddress.systemId);
                    d_fellowSetCommunicationState(fellow, D_COMMUNICATION_STATE_INCOMPATIBLE_DATA_MODEL);
                }
            } else {
                info->fellowsIncompatibleStateDif += 1;
                d_printTimedEvent (durability, D_LEVEL_WARNING,
                                   D_THREAD_NAMESPACES_LISTENER,
                                   "Communication with fellow %d NOT approved, because state is not compatible my state: %d, fellow state: %d\n",
                                   message->senderAddress.systemId,
                                   d_durabilityGetState(durability),
                                   message->senderState);
                d_fellowSetCommunicationState(fellow, D_COMMUNICATION_STATE_INCOMPATIBLE_STATE);
            }
        } else {
            d_printTimedEvent (durability, D_LEVEL_WARNING,
                               D_THREAD_NAMESPACES_LISTENER,
                               "Received %u of %u nameSpaces from fellow %u.\n",
                               count, d_nameSpaces(message)->total,
                               message->senderAddress.systemId);
        }
        d_adminUpdateStatistics(admin, info);
        d_adminStatisticsInfoFree(info);
    }
    d_fellowFree(fellow);
    d_networkAddressFree(sender);

    return;
}
Пример #16
0
u_result
u_waitsetAttach(
    const u_waitset _this,
    const u_observable observable,
    void *context)
{
    u_waitsetEntry entry;
    u_domain domain;
    u_result result;
    c_ulong length;
    u_bool changed = FALSE;
    os_result osr;

    assert(_this != NULL);
    assert(observable != NULL);

    osr = os_mutexLock_s(&_this->mutex);
    if (osr == os_resultSuccess) {
        length = c_iterLength(_this->entries);
        domain = u_observableDomain(observable);
        if (domain != NULL) {
            entry = c_iterResolve(_this->entries, compare_domain, domain);
        } else {
            entry = NULL;
        }
        if ((entry == NULL)&&(domain != NULL)) {
            result = u_domainAddWaitset(domain, _this);
            if (result == U_RESULT_OK) {
                entry = u_waitsetEntryNew(_this, domain, _this->eventMask);
                if (entry != NULL) {
                    _this->entries = c_iterInsert(_this->entries, entry);
                    changed = TRUE;
                }
            } else {
                result = U_RESULT_INTERNAL_ERROR;
                OS_REPORT(OS_ERROR, "u_waitSetAttach", result, "Failed to add waitset to domain.");
            }
        }
        if (entry != NULL) {
            result = u_waitsetEntryAttach(entry, observable, context);
        } else {
            result = U_RESULT_INTERNAL_ERROR;
            OS_REPORT(OS_ERROR, "u_waitSetAttach", result, "Failed to connect to domain.");
        }
        if (changed == TRUE) {
            if (length == 0) {
                /* Wakeup waitset because its no longer in zero domain mode */
                _this->multi_mode = OS_FALSE;
                os_condSignal(&_this->cv);
                result = U_RESULT_OK;
            } else if (length == 1) {
                _this->multi_mode = OS_TRUE;
                c_iterWalk(_this->entries, set_multi_mode, (c_voidp)&_this->multi_mode);
            }
        }
        os_mutexUnlock(&_this->mutex);
    } else {
        result = U_RESULT_INTERNAL_ERROR;
        OS_REPORT(OS_ERROR, "u_waitSetAttach", result, "Could not lock the waitset.");
    }
    return result;
}