Example #1
0
/* Build the Command args list. The list represent the array sent
 to execv and the List contains the following entries: args[0]
 is the path to the program, the rest are arguments to the program */
static void buildArgs(T C, const char *path, const char *x, va_list ap) {
        freeStrings(C->args);
        List_append(C->args, Str_dup(path));
        va_list ap_copy;
        va_copy(ap_copy, ap);
        for (; x; x = va_arg(ap_copy, char *))
                List_append(C->args, Str_dup(x));
        va_end(ap_copy);
}
Example #2
0
File: Dict.c Project: kaiaie/bile
/**
*** \brief Stores a value in the dictionary with the specified key, maintaining the 
*** keys in alphabetical order.
*** 
*** If a value with that key already exists in the 
*** dictionary, it will be replaced with the new value 
*** \note This is a potential memory leak!
**/
bool Dict_putSorted(Dict *d, const char *key, void *value) {
	bool   retVal = false;
	bool   added  = false;
	size_t idx    = 0;
	Pair   *p     = NULL;
	Pair   *pp    = NULL;
	size_t ii;
	
	if (keyToIndex(d, key, &idx)) {
		p = (Pair *)List_get((List *)d, idx);
		p->value = value;
		retVal = true;
	}
	else {
		p = new_Pair(key, value);
		added = false;
		if (List_length((List *)d) > 0) {
			for (ii = 0; ii < List_length((List *)d); ++ii) {
				pp = (Pair *)List_get((List *)d, ii);
				if (strcmp(key, pp->key) < 0) {
					List_insert((List *)d, ii, p);
					added = true;
					break;
				}
			}
		}
		if (!added) retVal = List_append((List *)d, p);
	}
	Logging_tracef("++++ Added pointer 0x%x to Dict 0x%x", (unsigned int)value, (unsigned int)d);
	return retVal;
}
Example #3
0
/* all is an Oec_AList of DataObject entries */
oe_id Oed_Dispatcher_reg_group(T _this_,
                               DataObjectList all,
                               oe_time dur,
                               bool consume,
                               user_callback *match_handler,
                               user_callback *timeout_handler,
                               user_callback_arg args) {

    oe_id sid = 0;

    assert(all);
    List_T group = List_list(NULL);
    for (Iterator iter = DataObjectList_iterator(all, true);
        Iterator_hasMore(iter);) {
        DataObject o = Iterator_next(iter);
        oe_scalar *templ_p = DataObject_toArray(o);
        item_ *item = _create_reg_item(_this_, templ_p, dur, consume, match_handler, timeout_handler, args);
        sid = item->sid;
        group = List_append(group, List_list(item, NULL));
    }
    item_ **groupitems = (item_**) List_toArray(group, NULL);
    for (int i = 0; i < List_length(group); i++) {
        groupitems[i]->group = group;

        _schedule_item(_this_, groupitems[i]);
    }

    Mem_free(groupitems, __FILE__, __LINE__);

    return sid; //you can cancel the whole group by unreg'ing this one sid
}
Example #4
0
/* Env variables are stored in the environment list as "name=value" strings */
void Command_setEnv(Command_T C, const char *name, const char *value) {
        assert(C);
        assert(name);
        removeEnv(C, name);
        List_append(C->env, Str_cat("%s=%s", name, value ? value : ""));
        FREE(C->_env); // Recreate Command environment on exec
}
void Post_subscribeWantedCarTransist(Post_t self, void * receiver, PostEvent_CB cb, void * data){
    Event_t event = (Event_t)malloc(sizeof(struct Event));
    event->receiver = receiver;
    event->cb = cb;
    event->data = data;
    List_append(self->wantedCarEvents, event);
}
List_t Post_getWantedCars(Post_t self){
    int lSize = List_getSize(self->wantedCars);
    List_t retList = List_new();
    for(int i = 0; i < lSize; i++){
        List_append(retList, List_get(self->wantedCars, i, NULL));
    }
    return retList;
}
List_t Post_getTransists(Post_t self){
    int lSize = List_getSize(self->transists);
    List_t retList = List_new();
    for(int i = 0; i < lSize; i++){
        List_append(retList, List_get(self->transists, i, NULL));
    }
    return retList;
}
Example #8
0
File: path.c Project: kaiaie/bile
/** Removes "." and ".." from a path */
char *getCanonicalPath(const char *path){
	char   *prefix = NULL;
	char   *rest   = NULL;
	char   *tmp    = NULL;
	size_t offset  = 0;
	char   **src   = NULL;
	List   *dst    = NULL;
	size_t ii = 0;
	Buffer *buf    = NULL;
	char   *result = NULL;
	
	if (path != NULL && strlen(path) > 0) {
		tmp = strxreplace(astrcpy(path), '\\', '/');
		if (isDosPath(tmp) || isUncPath(tmp)) {
			if (isDosPath(tmp)) {
				prefix = getPathPart(tmp, PATH_DRIVE);
				offset = 0;
			}
			else if (isUncPath(tmp)) {
				prefix = getPathPart(tmp, PATH_HOST);
				offset = 2;
			}
			rest = astrcpy(strchr(&tmp[offset], '/'));
		}
		else {
			rest = astrcpy(tmp);
		}
		src = astrtok(rest, "/");
		dst = new_List();
		while (src[ii] != NULL) {
			if (strxequals(src[ii], "..")) {
				List_remove(dst, -1, false);
			}
			else if (!strxequals(src[ii], ".")) {
				List_append(dst, src[ii]);
			}
			ii++;
		}
		buf = new_Buffer(0);
		if (prefix != NULL) {
			Buffer_appendString(buf, prefix);
		}
		for (ii = 0; ii < List_length(dst); ++ii) {
			Buffer_appendString(buf, List_get(dst, ii));
			if (ii != (List_length(dst) - 1)) {
				Buffer_appendChar(buf, '/');
			}
		}
		result = astrcpy(buf->data);
		delete_Buffer(buf);
		delete_List(dst, false);
		astrtokfree(src);
		mu_free(prefix);
		mu_free(rest);
		mu_free(tmp);
	}
	return result;
}
Example #9
0
Errors EntryList_appendCString(EntryList    *entryList,
                               EntryTypes   type,
                               const char   *pattern,
                               PatternTypes patternType
                              )
{
  EntryNode *entryNode;
  #if   defined(PLATFORM_LINUX)
  #elif defined(PLATFORM_WINDOWS)
    String    string;
  #endif /* PLATFORM_... */
  Errors    error;

  assert(entryList != NULL);
  assert(pattern != NULL);

  // allocate entry node
  entryNode = LIST_NEW_NODE(EntryNode);
  if (entryNode == NULL)
  {
    HALT_INSUFFICIENT_MEMORY();
  }
  entryNode->type   = type;
  entryNode->string = String_newCString(pattern);

  // init pattern
  #if   defined(PLATFORM_LINUX)
    error = Pattern_initCString(&entryNode->pattern,
                                pattern,
                                patternType,
                                PATTERN_FLAG_NONE
                               );
  #elif defined(PLATFORM_WINDOWS)
    // escape all '\' by '\\'
    string = String_newCString(pattern);
    String_replaceAllCString(string,STRING_BEGIN,"\\","\\\\");

    error = Pattern_init(&entryNode->pattern,
                         string,
                         patternType,
                         PATTERN_FLAG_IGNORE_CASE
                        );

    // free resources
    String_delete(string);
  #endif /* PLATFORM_... */
  if (error != ERROR_NONE)
  {
    String_delete(entryNode->string);
    LIST_DELETE_NODE(entryNode);
    return error;
  }

  // add to list
  List_append(entryList,entryNode);

  return ERROR_NONE;
}
List_t Post_getLastNCars(Post_t self, unsigned int N){
    int lSize = List_getSize(self->transists);
    if (N >= lSize) printf("Post: invalid index %d", N);
    List_t retList = List_new();
    for(int i = lSize - N; i < lSize; i++){
        List_append(retList, Transist_getCar(List_get(self->transists, i, NULL)));
    }
    return retList;
}
Example #11
0
//Register an object as a handler for events
void EH_registerHandler(Rect touchableArea, EventHandler evHan, bool needsNotification, void* selfRef)
{
    if(!isInitialised) EH_init();
    EventHandlingObject obj;
    obj.touchableArea = touchableArea;
    obj.evHandler = evHan;
    obj.needsNoActionNotification = needsNotification;
    obj.selfRef = selfRef;
    List_append(&EventHandlers, &obj);
}
Example #12
0
void fire_callback(int delay) {
    if (player_firing) {
        Bullet* b;
        b = Player_fire(game->player);
        if (b != NULL) {
            List_append(game->bullets, (void*) b);
        }
        glutTimerFunc(delay, fire_callback, delay);
    }
}
Example #13
0
void Tree_add_child(Node *parent, Node *child)
{
    List *list = parent->list;
    if(list==NULL)
    {
        list = List_create();
        parent->list = list;
    }
    List_append(list, child);
    child->parent = parent;
}
List_t Post_getCars(Post_t self, TRANSIST_DEST dest){
    int lSize = List_getSize(self->transists);
    List_t retList = List_new();
    for(int i = 0; i < lSize; i++){
        Transist_t transist = List_get(self->transists, i, NULL);
        if(dest == transist->dest){
            List_append(retList, Transist_getCar(transist));
        }
    }
    return retList;
}
int main()
{
    List_t list = List_new();

    List_append(list, "1");
    List_append(list, "-2");
    List_append(list, "3");
    List_append(list, "-1.2");
    List_append(list, "1.1");

    procSequence(list, accmulateSumInt, accmulateSumDouble);
    procSequence(list, accmulateAbsSumInt, accmulateAbsSumDouble);

    printf("%d\n", accmulateSumInt(0));
    printf("%f\n\n", accmulateSumDouble(0));
    printf("%d\n", accmulateAbsSumInt(0));
    printf("%f", accmulateAbsSumDouble(0));

    List_delete(list);
    return 0;
}
Example #16
0
/*
 * _metric_list
 *
 * Output list of all available metrics
 */
static void
_metric_list(void)
{
  const char *func = __FUNCTION__;
  cerebro_namelist_t m = NULL;
  cerebro_namelist_iterator_t mitr = NULL;
  List l = NULL;
  ListIterator litr = NULL;
  char *str;

  if (!(m = cerebro_get_metric_names(handle)))
    {
      char *msg = cerebro_strerror(cerebro_errnum(handle));

      _clean_err_exit(cerebro_errnum(handle));
      err_exit("%s: cerebro_get_metric_names: %s", func, msg);
    }
  
  if (!(mitr = cerebro_namelist_iterator_create(m)))
    {
      char *msg = cerebro_strerror(cerebro_namelist_errnum(m));
      err_exit("%s: cerebro_namelist_iterator_create: %s", func, msg);
    }

  l = List_create(NULL);

  while (!cerebro_namelist_iterator_at_end(mitr))
    {
      if (cerebro_namelist_iterator_name(mitr, &str) < 0)
        {
          char *msg = cerebro_strerror(cerebro_namelist_iterator_errnum(mitr));
          err_exit("%s: cerebro_namelist_iterator_name: %s", func, msg);
        }

      List_append(l, str);

      if (cerebro_namelist_iterator_next(mitr) < 0)
        {
          char *msg = cerebro_strerror(cerebro_namelist_iterator_errnum(mitr));
          err_exit("%s: cerebro_namelist_iterator_next: %s", func, msg);
        }
    }
  
  litr = List_iterator_create(l);

  while ((str = list_next(litr)))
    fprintf(stdout, "%s\n", str);

  /* List_destroy() and cerebro_namelist_destory() destroy iterators too */
  List_destroy(l);
  (void)cerebro_namelist_destroy(m);
}
Example #17
0
T Command_new(const char *path, const char *arg0, ...) {
        T C;
        if (! File_exist(path))
                THROW(AssertException, "File '%s' does not exist", path ? path : "null");
        NEW(C);
        C->env = List_new();
        C->args = List_new();
        List_append(C->env, Str_dup(Command_Path));
        va_list ap;
        va_start(ap, arg0);
        buildArgs(C, path, arg0, ap);
        va_end(ap);
        return C;
}
void Post_pass(Post_t self, Transist_t transist){
    if(Post_carIsWanted(self, transist->car->id)){
        int lSize = List_getSize(self->wantedCarEvents);

        for(int i = 0; i < lSize; i++){
            Event_t ev = List_get(self->wantedCarEvents, i, NULL);
            if(ev->cb != NULL){
                PostEvent_CB fn = ev->cb;
                fn(ev->receiver, self, ev->data);
                break;
            }
        }
    }
    List_append(self->transists, transist);
}
Example #19
0
File: Dict.c Project: kaiaie/bile
/**
*** \brief Stores a value in the dictionary with the specified key.  
***
*** If a value with that key already exists in the dictionary, it will be 
*** replaced with the new value.
*** \note This is a potential memory leak!
**/
bool Dict_put(Dict *d, const char *key, void *value) {
	bool   retVal = false;
	size_t idx = 0;
	Pair   *p  = NULL;
	
	if(keyToIndex(d, key, &idx)){
		p = (Pair *)List_get((List *)d, idx);
		p->value = value;
		retVal = true;
	}
	else{
		p = new_Pair(key, value);
		retVal = List_append((List *)d, p);
	}
	Logging_tracef("++++ Added pointer 0x%x to Dict 0x%x", (unsigned int)value, (unsigned int)d);
	return retVal;
}
Example #20
0
T Command_new(const char *path, const char *arg0, ...) {
        T C;
        assert(path);
        if (! File_exist(path))
                THROW(AssertException, "File '%s' does not exist", path);
        NEW(C);
        C->env = List_new();
        C->args = List_new();
        va_list ap;
        va_start(ap, arg0);
        buildArgs(C, path, arg0, ap);
        va_end(ap);
        // Copy this process's environment for transit to sub-processes
        extern char **environ;
        for (char **e = environ; *e; e++) {
                List_append(C->env, Str_dup(*e));
        }
        return C;
}
FileFragmentNode *FileFragmentList_addFile(FileFragmentList *fileFragmentList, const String fileName, uint64 size)
{
  FileFragmentNode *fileFragmentNode;

  assert(fileFragmentList != NULL);
  assert(fileName != NULL);

  fileFragmentNode = LIST_NEW_NODE(FileFragmentNode);
  if (fileFragmentNode == NULL)
  {
    HALT_INSUFFICIENT_MEMORY();
  }
  fileFragmentNode->fileName = String_duplicate(fileName);
  fileFragmentNode->size     = size;
  List_init(&fileFragmentNode->fragmentList);

  List_append(fileFragmentList,fileFragmentNode);

  return fileFragmentNode;
}
Example #22
0
File: list.c Project: edma2/legolas
void List_test(void) {
  List *np, *head = NULL;
  int i;

  for (i = 0; i < 10; i++) {
    List_append(&head, (void *)i);
  }
  np = head;
  for (i = 0; i < 10; i++) {
    assert((int)np->data == i);
    np = np->next;
  }

  List_free(&head, NULL);
  // make sure free empty list doesn't choke
  head = NULL;
  List_free(&head, NULL);

  printf("%s: All tests pass.\n", __FILE__);
}
Example #23
0
/**
 * \brief Get a list of sources
 *
 * Get a list of sources available. Each item in the list is a string giving the
 * name of the source prefixed with either "c:" or "s:" for client and server
 * sources respectively.
 *
 * \return List of sources
 */
List* SVR_getSourcesList(void) {
    List* sources_list;
    SVR_Message* message;
    SVR_Message* response;

    message = SVR_Message_new(1);
    message->components[0] = SVR_Arena_strdup(message->alloc, "Source.getSourcesList");

    response = SVR_Comm_sendMessage(message, true);

    sources_list = List_new();
    for(int i = 1; i < response->count; i++) {
        List_append(sources_list, strdup(response->components[i]));
    }

    SVR_Message_release(message);
    SVR_Message_release(response);

    return sources_list;
}
Example #24
0
void
cerebrod_queue_event(struct cerebro_event *event, unsigned int index)
{
  struct cerebrod_event_to_send *ets;

  assert(event);
  assert(event_queue);

  Pthread_mutex_lock(&event_queue_lock);

  ets = (struct cerebrod_event_to_send *)Malloc(sizeof(struct cerebrod_event_to_send));
  ets->event_name = event->event_name;
  ets->index = index;
  ets->event = event;
  
  List_append(event_queue, ets);

  Pthread_cond_signal(&event_queue_cond);
  Pthread_mutex_unlock(&event_queue_lock);
}
Example #25
0
FragmentNode *FragmentList_add(FragmentList   *fragmentList,
                               const String   name,
                               uint64         size,
                               const void     *userData,
                               uint           userDataSize
                              )
{
  FragmentNode *fragmentNode;

  assert(fragmentList != NULL);
  assert(name != NULL);

  fragmentNode = LIST_NEW_NODE(FragmentNode);
  if (fragmentNode == NULL)
  {
    HALT_INSUFFICIENT_MEMORY();
  }
  fragmentNode->name = String_duplicate(name);
  fragmentNode->size = size;
  if (userData != NULL)
  {
    fragmentNode->userData = malloc(userDataSize);
    if (fragmentNode->userData == NULL)
    {
      HALT_INSUFFICIENT_MEMORY();
    }
    memcpy(fragmentNode->userData,userData,userDataSize);
    fragmentNode->userDataSize = userDataSize;
  }
  else
  {
    fragmentNode->userData     = NULL;
    fragmentNode->userDataSize = 0;
  }
  List_init(&fragmentNode->fragmentEntryList);

  List_append(fragmentList,fragmentNode);

  return fragmentNode;
}
Example #26
0
FragmentNode *FragmentList_add(FragmentList   *fragmentList,
                               const String   name,
                               uint64         size,
                               const void     *userData,
                               uint           userDataSize
                              )
{
  FragmentNode *fragmentNode;

  assert(fragmentList != NULL);
  assert(name != NULL);

  fragmentNode = LIST_NEW_NODE(FragmentNode);
  if (fragmentNode == NULL)
  {
    HALT_INSUFFICIENT_MEMORY();
  }
  FragmentList_initNode(fragmentNode,name,size,userData,userDataSize);

  List_append(fragmentList,fragmentNode);

  return fragmentNode;
}
Example #27
0
/* 
 * _event_node_timeout_data_add
 *
 * Create entries for the event_node_timeout_data list and index
 *
 * Returns 0 on success, -1 on error
 */
static int
_event_node_timeout_data_add(const char *nodename, u_int32_t time_now)
{
  struct cerebrod_event_node_timeout_data *ntd;
#if CEREBRO_DEBUG
  int rv;

  /* Should be called with lock already set */
  rv = Pthread_mutex_trylock(&event_node_timeout_data_lock);
  if (rv != EBUSY)
    CEREBROD_EXIT(("mutex not locked: rv=%d", rv));
#endif /* CEREBRO_DEBUG */

  ntd = (struct cerebrod_event_node_timeout_data *)Malloc(sizeof(struct cerebrod_event_node_timeout_data));
  ntd->nodename = (char *)nodename;
  ntd->last_received_time = time_now;
  ntd->timeout_occurred = 0;

  List_append(event_node_timeout_data, ntd);
  Hash_insert(event_node_timeout_data_index, ntd->nodename, ntd);
  event_node_timeout_data_index_numnodes++;
  return 0;
}
Example #28
0
Errors PatternList_appendCString(PatternList  *patternList,
                                 const char   *pattern,
                                 PatternTypes patternType
                                )
{
  PatternNode *patternNode;
  Errors      error;

  assert(patternList != NULL);
  assert(pattern != NULL);

  // allocate pattern node
  patternNode = LIST_NEW_NODE(PatternNode);
  if (patternNode == NULL)
  {
    HALT_INSUFFICIENT_MEMORY();
  }
  patternNode->string = String_newCString(pattern);

  // init pattern
  error = Pattern_initCString(&patternNode->pattern,
                              pattern,
                              patternType,
                              PATTERN_FLAG_IGNORE_CASE
                             );
  if (error != ERROR_NONE)
  {
    String_delete(patternNode->string);
    LIST_DELETE_NODE(patternNode);
    return error;
  }

  // add to list
  List_append(patternList,patternNode);

  return ERROR_NONE;
}
Example #29
0
static void	quick_sort(List *l,
		/*List_Iterator *first,
		List_Iterator *last,*/
		list_cmp_fct cmpf)
{
/*	
	A LITTLE MORE OPTIMIZED BUT BUGGED VERSION

	List_Iterator *pivot = last;
	List_Iterator *it = first;
	List_Iterator *next = NULL;
	void *data = NULL;
	last = NULL;

	if (!it || !pivot || it == pivot || !pivot->prev || !it->next)
	{
		return;
	}

	while (it != pivot)
	{
		next = it->next;
		if (cmpf(it->data, pivot->data) <= 0)
		{
			if (it == first)
				first = it->next;
			data = List_remove_it(l, it);
			assert(data);
			assert(List_insert_after_it(l, pivot, data));
			if (last == NULL)
				last = pivot->next;
		}
		it = next;
	}
	quick_sort(l, first, pivot->prev, cmpf);
	quick_sort(l, pivot->next, last, cmpf);*/

	void *pivot;
	int cmp = 0;
	List *less = NEW(List);
	List *greater = NEW(List);
	List *equal = NEW(List);
	List_Iterator *it;

	if (!less || !greater || !equal)
	{
		perror("malloc");
		return ;
	}
	if (COUNT(l) <= 1)
		return ;

	it = List_get_it(l, (COUNT(l)/2 - 1));
	pivot = it->data;
	List_remove_it(l, it);
	while (COUNT(l))
	{
		it = List_pop_first_it(l);
		cmp = cmpf(it->data, pivot);
		if (cmp > 0)
			List_append_it(less, it);
		else if (cmp < 0)
			List_append_it(greater, it);
		else
			List_append_it(equal, it);

	}
	// SUBLISTS
	if (COUNT(less)) {
		quick_sort(less, cmpf);
		List_concat(l, less);
	}
	else
		free(less);

	// 
	List_append(l, pivot);
	
	if (COUNT(equal)) {
		List_concat(l, equal);
	}
	else
		free(equal);


	if (COUNT(greater)) {
		quick_sort(greater, cmpf);
		List_concat(l, greater);
	}
	else
		free(greater);

}
/*
 * _setup_metric_modules
 *
 * Setup metric modules. Under almost any circumstance, don't return a
 * -1 error, cerebro can go on without loading metric modules.
 *
 * Returns 1 if modules are loaded, 0 if not, -1 on error
 */
static int
_setup_metric_modules(void)
{
    int i;
#if CEREBRO_DEBUG
#if !WITH_CEREBROD_NO_THREADS
    int rv;
#endif /* !WITH_CEREBROD_NO_THREADS */
#endif /* CEREBRO_DEBUG */

    assert(metric_list);

#if CEREBRO_DEBUG
#if !WITH_CEREBROD_NO_THREADS
    /* Should be called with lock already set */
    rv = Pthread_mutex_trylock(&metric_list_lock);
    if (rv != EBUSY)
        CEREBRO_EXIT(("mutex not locked: rv=%d", rv));
#endif /* !WITH_CEREBROD_NO_THREADS */
#endif /* CEREBRO_DEBUG */

    if (!(metric_handle = metric_modules_load()))
    {
        CEREBRO_DBG(("metric_modules_load"));
        goto cleanup;
    }

    if ((metric_handle_count = metric_modules_count(metric_handle)) < 0)
    {
        CEREBRO_DBG(("metric_module_count failed"));
        goto cleanup;
    }

    if (!metric_handle_count)
    {
#if CEREBRO_DEBUG
        if (conf.debug && conf.speak_debug)
        {
#if !WITH_CEREBROD_NO_THREADS
            Pthread_mutex_lock(&debug_output_mutex);
#endif /* !WITH_CEREBROD_NO_THREADS */
            fprintf(stderr, "**************************************\n");
            fprintf(stderr, "* No Metric Modules Found\n");
            fprintf(stderr, "**************************************\n");
#if !WITH_CEREBROD_NO_THREADS
            Pthread_mutex_unlock(&debug_output_mutex);
#endif /* !WITH_CEREBROD_NO_THREADS */
        }
#endif /* CEREBRO_DEBUG */
        goto cleanup;
    }

    for (i = 0; i < metric_handle_count; i++)
    {
        struct cerebrod_speaker_metric_info *metric_info;
#if !WITH_CEREBROD_NO_THREADS
        Cerebro_metric_thread_pointer threadPtr;
#endif /* !WITH_CEREBROD_NO_THREADS */
        char *module_name, *metric_name;
        int metric_period;
        u_int32_t metric_flags;

        module_name = metric_module_name(metric_handle, i);

        if (conf.metric_module_exclude_len)
        {
            int found_exclude = 0;
            int j;

            for (j = 0; j < conf.metric_module_exclude_len; j++)
            {
                if (!strcasecmp(conf.metric_module_exclude[j], module_name))
                {
                    found_exclude++;
                    break;
                }
            }

            if (found_exclude)
            {
#if CEREBRO_DEBUG
                if (conf.debug && conf.speak_debug)
                {
#if !WITH_CEREBROD_NO_THREADS
                    Pthread_mutex_lock(&debug_output_mutex);
#endif /* !WITH_CEREBROD_NO_THREADS */
                    fprintf(stderr, "**************************************\n");
                    fprintf(stderr, "* Skip Metric Module: %s\n", module_name);
                    fprintf(stderr, "**************************************\n");
#if !WITH_CEREBROD_NO_THREADS
                    Pthread_mutex_unlock(&debug_output_mutex);
#endif /* !WITH_CEREBROD_NO_THREADS */
                }
#endif /* CEREBRO_DEBUG */
                CEREBRO_ERR(("Dropping metric module: %s", module_name));
                continue;
            }
        }

#if CEREBRO_DEBUG
        if (conf.debug && conf.speak_debug)
        {
#if !WITH_CEREBROD_NO_THREADS
            Pthread_mutex_lock(&debug_output_mutex);
#endif /* !WITH_CEREBROD_NO_THREADS */
            fprintf(stderr, "**************************************\n");
            fprintf(stderr, "* Setup Metric Module: %s\n", module_name);
            fprintf(stderr, "**************************************\n");
#if !WITH_CEREBROD_NO_THREADS
            Pthread_mutex_unlock(&debug_output_mutex);
#endif /* !WITH_CEREBROD_NO_THREADS */
        }
#endif /* CEREBRO_DEBUG */

        if (metric_module_setup(metric_handle, i) < 0)
        {
            CEREBRO_DBG(("metric_module_setup: %s", module_name));
            continue;
        }

        if (!(metric_name = metric_module_get_metric_name(metric_handle, i)))
        {
            CEREBRO_DBG(("metric_module_get_metric_name: %s", module_name));
            metric_module_cleanup(metric_handle, i);
            continue;
        }

        if (metric_module_get_metric_period(metric_handle, i, &metric_period) < 0)
        {
            CEREBRO_DBG(("metric_module_get_metric_period: %s", module_name));
            metric_module_cleanup(metric_handle, i);
            continue;
        }

        if (metric_module_get_metric_flags(metric_handle, i, &metric_flags) < 0)
        {
            CEREBRO_DBG(("metric_module_get_metric_flags: %s", module_name));
            metric_module_cleanup(metric_handle, i);
            continue;
        }

        if (metric_flags & CEREBRO_METRIC_MODULE_FLAGS_SEND_ON_PERIOD
                && metric_period <= 0)
        {
            CEREBRO_DBG(("metric module period invalid: %s", module_name));
            metric_module_cleanup(metric_handle, i);
            continue;
        }

        if (metric_module_send_message_function_pointer(metric_handle, i, &cerebrod_send_message) < 0)
        {
            CEREBRO_DBG(("metric_module_send_message_function_pointer: %s", module_name));
            metric_module_cleanup(metric_handle, i);
            continue;
        }

        metric_info = Malloc(sizeof(struct cerebrod_speaker_metric_info));
        /* No need to Strdup() the name in this case */
        metric_info->metric_name = metric_name;
        metric_info->metric_origin = CEREBROD_METRIC_SPEAKER_ORIGIN_MODULE;

        metric_info->metric_period = metric_period;
        metric_info->metric_flags = metric_flags;
        metric_info->index = i;

        /*
         * If metric period is < 0, it presumably never will be sent
         * (metric is likely handled by a metric_thread), so set
         * next_call_time to UINT_MAX.
         *
         * If this is a metric that will be piggy-backed on heartbeats,
         * then initialize next_call_time to 0, so the data is sent on
         * the first heartbeat
         *
         * If this is a metric that will not be piggy-backed on
         * heartbeats, set the next_call_time to UINT_MAX.  Let the
         * speaker logic decide when packets should be sent.
         */
        if (metric_info->metric_period < 0
                || metric_info->metric_flags & CEREBRO_METRIC_MODULE_FLAGS_SEND_ON_PERIOD)
            metric_info->next_call_time = UINT_MAX;
        else
            metric_info->next_call_time = 0;

        List_append(metric_list, metric_info);
        metric_list_size++;

#if !WITH_CEREBROD_NO_THREADS
        if ((threadPtr = metric_module_get_metric_thread(metric_handle, i)))
        {
            pthread_t thread;
            pthread_attr_t attr;

            Pthread_attr_init(&attr);
            Pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
            Pthread_attr_setstacksize(&attr, CEREBROD_THREAD_STACKSIZE);
            Pthread_create(&thread, &attr, threadPtr, NULL);
            Pthread_attr_destroy(&attr);
        }
#endif /* !WITH_CEREBROD_NO_THREADS */
    }

    if (!metric_list_size)
        goto cleanup;

    cerebrod_speaker_data_metric_list_sort();
    return 1;

cleanup:
    if (metric_handle)
    {
        /* unload will call module cleanup functions */
        metric_modules_unload(metric_handle);
        metric_handle = NULL;
        metric_handle_count = 0;
    }
    metric_list_size = 0;
    return 0;
}