Example #1
0
static void
apteryx__timestamp (Apteryx__Server_Service *service,
                        const Apteryx__Get *get,
                        Apteryx__TimeStampResult_Closure closure, void *closure_data)
{
    Apteryx__TimeStampResult result = APTERYX__TIME_STAMP_RESULT__INIT;
    uint64_t value = 0;

    /* Check parameters */
    if (get == NULL || get->path == NULL)
    {
        ERROR ("TIMESTAMP: Invalid parameters.\n");
        closure (NULL, closure_data);
        INC_COUNTER (counters.timestamp_invalid);
        return;
    }
    INC_COUNTER (counters.timestamp);

    DEBUG ("TIMESTAMP: %s\n", get->path);

    /* Proxy first */
    if ((value = proxy_timestamp (get->path)) == 0)
    {
        /* Lookup value */
        value = db_timestamp (get->path);
    }

    /* Send result */
    DEBUG ("     = %"PRIu64"\n", value);
    result.value = value;
    closure (&result, closure_data);
    return;
}
Example #2
0
static void
apteryx__get (Apteryx__Server_Service *service,
              const Apteryx__Get *get,
              Apteryx__GetResult_Closure closure, void *closure_data)
{
    Apteryx__GetResult result = APTERYX__GET_RESULT__INIT;
    char *value = NULL;

    /* Check parameters */
    if (get == NULL || get->path == NULL)
    {
        ERROR ("GET: Invalid parameters.\n");
        closure (NULL, closure_data);
        INC_COUNTER (counters.get_invalid);
        return;
    }
    INC_COUNTER (counters.get);

    DEBUG ("GET: %s\n", get->path);

    /* Lookup value */
    value = get_value (get->path);

    /* Send result */
    DEBUG ("     = %s\n", value);
    result.value = value;
    closure (&result, closure_data);
    if (value)
        g_free (value);
    return;
}
Example #3
0
static void
apteryx__traverse (Apteryx__Server_Service *service,
                 const Apteryx__Traverse *traverse,
                 Apteryx__TraverseResult_Closure closure, void *closure_data)
{
    Apteryx__TraverseResult result = APTERYX__TRAVERSE_RESULT__INIT;
    GList *iter, *pvlist = NULL;
    (void) service;

    /* Check parameters */
    if (traverse == NULL || traverse->path == NULL)
    {
        ERROR ("TRAVERSE: Invalid parameters.\n");
        closure (NULL, closure_data);
        INC_COUNTER (counters.traverse_invalid);
        return;
    }
    INC_COUNTER (counters.traverse);

    DEBUG ("TRAVERSE: %s\n", traverse->path);

    /* Proxy first */
    pvlist = proxy_traverse (traverse->path);
    if (!pvlist)
    {
        /* Traverse (local) paths */
        _traverse_paths (&pvlist, traverse->path);
    }

    if (pvlist)
    {
        result.n_pv = 0;
        result.pv = g_malloc (g_list_length (pvlist) * sizeof (Apteryx__PathValue *));
        for (iter = pvlist; iter; iter = g_list_next (iter))
        {
            Apteryx__PathValue *pv = (Apteryx__PathValue *) iter->data;
            pv->base.descriptor = &apteryx__path_value__descriptor;
            DEBUG ("  %s = %s\n", pv->path, pv->value);
            result.pv[result.n_pv++] = pv;
        }
    }

    /* Send result */
    closure (&result, closure_data);
    if (pvlist)
    {
        for (iter = pvlist; iter; iter = g_list_next (iter))
        {
            Apteryx__PathValue *pv = (Apteryx__PathValue *) iter->data;
            g_free (pv->path);
            g_free (pv->value);
            g_free (pv);
        }
        g_free (result.pv);
        g_list_free (pvlist);
    }
    return;
}
Example #4
0
static void
apteryx__prune (Apteryx__Server_Service *service,
                const Apteryx__Prune *prune,
                Apteryx__OKResult_Closure closure, void *closure_data)
{
    Apteryx__OKResult result = APTERYX__OKRESULT__INIT;
    result.result = 0;
    GList *paths = NULL, *iter;
    (void) service;

    /* Check parameters */
    if (prune == NULL || prune->path == NULL)
    {
        ERROR ("PRUNE: Invalid parameters.\n");
        result.result = -EINVAL;
        closure (&result, closure_data);
        INC_COUNTER (counters.prune_invalid);
        return;
    }
    INC_COUNTER (counters.prune);

    DEBUG ("PRUNE: %s\n", prune->path);

    /* Proxy first */
    if (proxy_prune (prune->path))
    {
        /* Return result */
        closure (&result, closure_data);
        return;
    }

    /* Collect the list of deleted paths for notification */
    paths = g_list_prepend(paths, g_strdup(prune->path));
    _search_paths (&paths, prune->path);

    /* Prune from database */
    db_delete (prune->path, UINT64_MAX);

    /* Return result */
    closure (&result, closure_data);

    /* Call watchers for each pruned path */
    for (iter = paths; iter; iter = g_list_next (iter))
    {
        notify_watchers ((const char *)iter->data);
    }

    g_list_free_full (paths, g_free);
    return;
}
Example #5
0
static char *
proxy_get (const char *path)
{
    ProtobufCService *rpc_client;
    Apteryx__Get get = APTERYX__GET__INIT;
    get_data_t data = {0};
    cb_info_t *proxy = NULL;
    char *value = NULL;

    /* Find and connect to a proxied instance */
    rpc_client = find_proxy (&path, &proxy);
    if (!rpc_client)
        return NULL;

    /* Do remote get */
    get.path = (char *) path;
    apteryx__server__get (rpc_client, &get, handle_get_response, &data);
    if (!data.done)
    {
        INC_COUNTER (counters.proxied_timeout);
        ERROR ("No response from proxy for path \"%s\"\n", (char *)path);
        rpc_client_release (rpc, rpc_client, false);
    }
    else
    {
        rpc_client_release (rpc, rpc_client, true);
        value = data.value;
    }

    return value;
}
Example #6
0
static uint64_t
proxy_timestamp (const char *path)
{
    ProtobufCService *rpc_client;
    Apteryx__Get get = APTERYX__GET__INIT;
    uint64_t value = 0;
    cb_info_t *proxy = NULL;

    /* Find and connect to a proxied instance */
    rpc_client = find_proxy (&path, &proxy);
    if (!rpc_client)
        return 0;

    /* Do remote timestamp */
    get.path = (char *) path;
    apteryx__server__timestamp (rpc_client, &get, handle_timestamp_response, &value);
    if (!value)
    {
        INC_COUNTER (counters.proxied_timeout);
        ERROR ("No response from proxy for path \"%s\"\n", (char *)path);
        rpc_client_release (rpc, rpc_client, false);
        return value;
    }
    rpc_client_release (rpc, rpc_client, true);

    return value;
}
Example #7
0
static ProtobufCService *
find_proxy (const char **path, cb_info_t **proxy_pt)
{
    ProtobufCService *rpc_client = NULL;
    GList *proxies = NULL;
    GList *iter = NULL;

    *proxy_pt = NULL;

    /* Retrieve a list of proxies for this path */
    proxies = cb_match (&proxy_list, *path,
            CB_MATCH_EXACT|CB_MATCH_WILD|CB_MATCH_CHILD);
    if (!proxies)
        return NULL;

    /* Find the first good proxy */
    for (iter = proxies; iter; iter = g_list_next (iter))
    {
        cb_info_t *proxy = iter->data;
        int len = strlen (proxy->path);

        /* Setup IPC */
        rpc_client = rpc_client_connect (proxy_rpc, proxy->uri);
        if (!rpc_client)
        {
            ERROR ("Invalid PROXY CB %s (%s)\n", proxy->path, proxy->uri);
            cb_destroy (proxy);
            INC_COUNTER (counters.proxied_no_handler);
            continue;
        }
        INC_COUNTER (counters.proxied);
        INC_COUNTER (proxy->count);

        /* Strip proxied path */
        if (proxy->path[len-1] == '*')
            len -= 1;
        if (proxy->path[len-1] == '/')
            len -= 1;
        *path = *path  + len;
        DEBUG ("PROXY CB \"%s\" to \"%s\"\n", *path, proxy->uri);
        *proxy_pt = proxy;
        break;
    }
    g_list_free_full (proxies, (GDestroyNotify) cb_release);
    return rpc_client;
}
Example #8
0
static void
apteryx__search (Apteryx__Server_Service *service,
                 const Apteryx__Search *search,
                 Apteryx__SearchResult_Closure closure, void *closure_data)
{
    Apteryx__SearchResult result = APTERYX__SEARCH_RESULT__INIT;
    GList *results = NULL;
    GList *iter = NULL;
    int i;
    (void) service;

    /* Check parameters */
    if (search == NULL || search->path == NULL)
    {
        ERROR ("SEARCH: Invalid parameters.\n");
        closure (NULL, closure_data);
        INC_COUNTER (counters.search_invalid);
        return;
    }
    INC_COUNTER (counters.search);

    DEBUG ("SEARCH: %s\n", search->path);

    results = search_path (search->path);

    /* Prepare the results */
    result.n_paths = g_list_length (results);
    if (result.n_paths > 0)
    {
        result.paths = (char **) g_malloc (result.n_paths * sizeof (char *));
        for (i = 0, iter = results; iter; iter = g_list_next (iter), i++)
        {
            DEBUG ("         = %s\n", (char *) iter->data);
            result.paths[i] = (char *) iter->data;
        }
    }

    /* Send result */
    closure (&result, closure_data);
    g_list_free_full (results, g_free);
    if (result.paths)
        g_free (result.paths);
    return;
}
Example #9
0
StackingAllocator::~StackingAllocator()
{
    WRAPPER_CONTRACT;

    Clear(NULL);

    if (m_DeferredFreeBlock)
    {
        delete [] (char*)m_DeferredFreeBlock;
        m_DeferredFreeBlock = NULL;
    }

#ifdef _DEBUG
    INC_COUNTER(L"Allocs", m_Allocs);
    INC_COUNTER(L"Checkpoints", m_Checkpoints);
    INC_COUNTER(L"Collapses", m_Collapses);
    INC_COUNTER(L"BlockAllocs", m_BlockAllocs);
    MAX_COUNTER(L"MaxAlloc", m_MaxAlloc);
#endif
}
Example #10
0
static GList *
proxy_search (const char *path)
{
    const char *in_path = path;
    ProtobufCService *rpc_client;
    Apteryx__Search search = APTERYX__SEARCH__INIT;
    search_data_t data = {0};
    cb_info_t *proxy = NULL;

    /* Find and connect to a proxied instance */
    rpc_client = find_proxy (&path, &proxy);
    if (!rpc_client)
        return NULL;

    /* Do remote search */
    search.path = (char *) path;
    apteryx__server__search (rpc_client, &search, handle_search_response, &data);
    if (!data.done)
    {
        INC_COUNTER (counters.proxied_timeout);
        ERROR ("No response from proxy for path \"%s\"\n", (char *)path);
        rpc_client_release (rpc, rpc_client, false);
    }
    else
    {
        rpc_client_release (rpc, rpc_client, true);
        /* Prepend local path to start of all search results */
        size_t path_len = path - in_path;
        char *local_path = g_malloc0 (path_len + 1);
        strncpy (local_path, in_path, path_len);
        GList *itr = data.paths;
        for (; itr; itr = itr->next)
        {
            char *tmp = g_strdup_printf ("%s%s", local_path, (char *)itr->data);
            g_free (itr->data);
            itr->data = tmp;
        }
        g_free (local_path);
    }

    return data.paths;
}
Example #11
0
static GList *
proxy_traverse (const char *path)
{
    const char *in_path = path;
    ProtobufCService *rpc_client;
    Apteryx__Traverse traverse = APTERYX__TRAVERSE__INIT;
    traverse_data_t data = {0};
    cb_info_t *proxy = NULL;

    /* Find and connect to a proxied instance */
    rpc_client = find_proxy (&path, &proxy);
    if (!rpc_client)
        return NULL;

    /* Do remote traverse */
    traverse.path = (char *) path;
    data.path = path;
    apteryx__server__traverse (rpc_client, &traverse, handle_traverse_response, &data);
    if (!data.done)
    {
        INC_COUNTER (counters.proxied_timeout);
        ERROR ("No response from proxy for path \"%s\"\n", (char *)path);
        rpc_client_release (rpc, rpc_client, false);
    }
    else
    {
        DEBUG ("TRAVERSE: %s (proxies as %s)\n", in_path, path);
        rpc_client_release (rpc, rpc_client, true);
        /* Prepend full path to start of all search results */
        GList *itr = data.paths;
        for (; itr; itr = itr->next)
        {
            Apteryx__PathValue *pv = (Apteryx__PathValue *) itr->data;
            char *tmp = g_strconcat (in_path, pv->path, NULL);
            g_free (pv->path);
            pv->path = tmp;
        }
    }

    return data.paths;
}
Example #12
0
VolumeIntersectionValue View::TestAABB(const AABB& aabb) const
{
	INC_COUNTER(g_count_bboxs);
    return _frustum.testIntersection(aabb);
}
Example #13
0
bool View::TestPlane(const Plane3& plane, const Matrix4& localToWorld) const
{
	INC_COUNTER(g_count_oriented_planes);
	return _viewer.testPlane(plane, localToWorld);
}
Example #14
0
bool View::TestPlane(const Plane3& plane) const
{
	INC_COUNTER(g_count_planes);
	return _viewer.testPlane(plane);
}
Example #15
0
VolumeIntersectionValue View::TestAABB(const AABB& aabb, const Matrix4& localToWorld) const
{
	INC_COUNTER(g_count_oriented_bboxs);
	return _frustum.testIntersection(aabb, localToWorld);
}
Example #16
0
static void
apteryx__find (Apteryx__Server_Service *service,
              const Apteryx__Find *find,
              Apteryx__SearchResult_Closure closure, void *closure_data)
{
    Apteryx__SearchResult result = APTERYX__SEARCH_RESULT__INIT;
    GList *possible_matches = NULL;
    GList *iter = NULL;
    char *tmp = NULL;
    char *ptr = NULL;
    char *chunk;
    GList *matches = NULL;
    int i;

    /* Check parameters */
    if (find == NULL || find->n_matches == 0 || find->matches == NULL)
    {
        ERROR ("FIND: Invalid parameters.\n");
        INC_COUNTER (counters.find_invalid);
        goto exit;
    }
    INC_COUNTER (counters.find);

    /* Debug */
    for (i = 0; apteryx_debug && i < find->n_matches; i++)
    {
        DEBUG ("FIND: %s = %s\n", find->matches[i]->path, find->matches[i]->value);
    }

    /* Grab first level (from root) */
    tmp = g_strdup (find->path);
    chunk = strtok_r( tmp, "*", &ptr);
    if (chunk)
    {
        possible_matches = search_path (chunk);
    }

    /* For each * do a search + add keys, then re-search */
    while ((chunk = strtok_r (NULL, "*", &ptr)) != NULL)
    {
        GList *last_round = possible_matches;
        possible_matches = NULL;
        for (iter = g_list_first (last_round); iter; iter = g_list_next (iter))
        {
            char *next_level = NULL;
            next_level = g_strdup_printf("%s%s", (char*) iter->data, chunk);
            possible_matches = g_list_concat (search_path (next_level), possible_matches);
            g_free (next_level);
        }
        g_list_free_full (last_round, g_free);
    }

    /* Go through each path match and see if all keys match */
    for (iter = g_list_first (possible_matches); iter; iter = g_list_next (iter))
    {
        bool possible_match = true;
        for (i = 0; i < find->n_matches && possible_match; i++)
        {
            char *key = NULL;
            char *value = NULL;

            key = g_strdup_printf("%s%s", (char*)iter->data,
                              strrchr (find->matches[i]->path, '*') + 1);
            value = get_value (key);


            /* A "" value on a match maps to no return value from provider / database */
            if (strlen (find->matches[i]->value) == 0 && value == NULL)
            {
                possible_match = true;
            }
            else if ((strlen (find->matches[i]->value) == 0 && value != NULL) ||
                    (value == NULL && strlen (find->matches[i]->value) > 0))
            {
                /* Match miss - we can stop checking */
                possible_match = false;
            }
            else if (strcmp (value, find->matches[i]->value) != 0)
            {
                /* Match miss - we can stop checking */
                possible_match = false;
            }

            g_free (key);
            g_free (value);
        }

        /* All keys match, so this is a good path */
        if (possible_match)
        {
            matches = g_list_prepend (matches, g_strdup ((char*)iter->data));
        }
    }
    g_list_free_full (possible_matches, g_free);

    DEBUG ("FIND: matches:\n");
    /* Prepare the results */
    result.n_paths = g_list_length (matches);
    if (result.n_paths > 0)
    {
        result.paths = (char **) g_malloc (result.n_paths * sizeof (char *));
        for (i = 0, iter = g_list_first (matches); iter; iter = g_list_next (iter), i++)
        {
            DEBUG ("         = %s\n", (char *) iter->data);
            result.paths[i] = (char *) iter->data;
        }
    }
    else
    {
        DEBUG ("         NONE\n");
    }

exit:
    /* Return result */
    closure (&result, closure_data);

    /* Cleanup */
    g_free (tmp);
    g_list_free_full (matches, g_free);
    if (result.paths)
        g_free (result.paths);

    return;
}
Example #17
0
static void
apteryx__set (Apteryx__Server_Service *service,
              const Apteryx__Set *set,
              Apteryx__OKResult_Closure closure, void *closure_data)
{
    Apteryx__OKResult result = APTERYX__OKRESULT__INIT;
    const char *path = NULL;
    const char *value = NULL;
    result.result = 0;
    int validation_result = 0;
    int validation_lock = 0;
    int proxy_result = 0;
    bool db_result = false;
    int i;

    /* Check parameters */
    if (set == NULL || set->n_sets == 0 || set->sets == NULL)
    {
        ERROR ("SET: Invalid parameters.\n");
        result.result = -EINVAL;
        closure (&result, closure_data);
        INC_COUNTER (counters.set_invalid);
        return;
    }
    INC_COUNTER (counters.set);

    /* Debug */
    for (i=0; apteryx_debug && i<set->n_sets; i++)
    {
        DEBUG ("SET: %s = %s\n", set->sets[i]->path, set->sets[i]->value);
    }

    /* Proxy first */
    for (i=0; i<set->n_sets; i++)
    {
        path = set->sets[i]->path;
        value = set->sets[i]->value;
        if (value && value[0] == '\0')
            value = NULL;

        proxy_result = proxy_set (path, value, set->ts);
        if (proxy_result == 0)
        {
            /*  Result success */
            DEBUG ("SET: %s = %s proxied\n", path, value);
            /* Mark the set as processed */
            notify_watchers (set->sets[i]->path);
            free (set->sets[i]->path);
            set->sets[i]->path = NULL;
        }
        else if (proxy_result < 0)
        {
            result.result = proxy_result;
            goto exit;
        }
    }

    /* Validate */
    for (i=0; i<set->n_sets; i++)
    {
        path = set->sets[i]->path;
        if (!path)
            continue;
        value = set->sets[i]->value;
        if (value && value[0] == '\0')
            value = NULL;

        /* Validate new data */
        validation_result = validate_set (path, value);
        if (validation_result != 0)
            validation_lock++;
        if (validation_result < 0)
        {
            DEBUG ("SET: %s = %s refused by validate\n", path, value);
            result.result = validation_result;
            goto exit;
        }
    }

    /* Set in the database */
    pthread_rwlock_wrlock (&db_lock);
    for (i=0; i<set->n_sets; i++)
    {
        path = set->sets[i]->path;
        if (!path)
            continue;
        value = set->sets[i]->value;
        if (value && value[0] == '\0')
            value = NULL;

        /* Add/Delete to/from database */
        if (value)
            db_result = db_add_no_lock (path, (unsigned char*)value, strlen (value) + 1, set->ts);
        else
            db_result = db_delete_no_lock (path, set->ts);
        if (!db_result)
        {
            DEBUG ("SET: %s = %s refused by DB\n", path, value);
            result.result = -EBUSY;
            pthread_rwlock_unlock (&db_lock);
            goto exit;
        }
    }
    pthread_rwlock_unlock (&db_lock);

    /* Set succeeded */
    result.result = 0;

exit:
    /* Return result and notify watchers */
    if (validation_result >= 0 && result.result == 0)
    {
        /* Notify watchers */
        for (i=0; i<set->n_sets; i++)
        {
            if (set->sets[i]->path)
                notify_watchers (set->sets[i]->path);
        }
    }

    /* Return result */
    closure (&result, closure_data);

    /* Release validation lock - this is a sensitive value */
    while (validation_lock)
    {
        DEBUG("SET: unlocking mutex\n");
        pthread_mutex_unlock (&validating);
        validation_lock--;
    }
    return;
}
Example #18
0
/* This function returns true if indexers were called (list may still be NULL) */
static bool
index_get (const char *path, GList **result)
{
    GList *indexers = NULL;
    GList *results = NULL;
    GList *iter = NULL;

    /* Retrieve a list of providers for this path */
    indexers = cb_match (&index_list, path,
            CB_MATCH_EXACT|CB_MATCH_WILD|CB_MATCH_CHILD);
    if (!indexers)
    {
        *result = NULL;
        return false;
    }

    /* Find the first good indexer */
    for (iter = indexers; iter; iter = g_list_next (iter))
    {
        cb_info_t *indexer = iter->data;
        ProtobufCService *rpc_client;
        Apteryx__Index index = APTERYX__INDEX__INIT;
        search_data_t data = {0};

        /* Check for local provider */
        if (indexer->id == getpid ())
        {
            apteryx_index_callback cb = (apteryx_index_callback) (long) indexer->cb;
            DEBUG ("INDEX LOCAL \"%s\" (0x%"PRIx64",0x%"PRIx64")\n",
                    indexer->path, indexer->id, indexer->cb);
            results = cb (path);
            break;
        }

        DEBUG ("INDEX CB \"%s\" (0x%"PRIx64",0x%"PRIx64")\n",
                indexer->path, indexer->id, indexer->cb);

        /* Setup IPC */
        rpc_client = rpc_client_connect (rpc, indexer->uri);
        if (!rpc_client)
        {
            /* Throw away the no good validator */
            ERROR ("Invalid INDEX CB %s (0x%"PRIx64",0x%"PRIx64")\n",
                    indexer->path, indexer->id, indexer->cb);
            cb_destroy (indexer);
            INC_COUNTER (counters.indexed_no_handler);
            continue;
        }

        /* Do remote get */
        index.path = (char *) path;
        index.id = indexer->id;
        index.cb = indexer->cb;
        apteryx__client__index (rpc_client, &index, handle_search_response, &data);
        if (!data.done)
        {
            INC_COUNTER (counters.indexed_timeout);
            ERROR ("No response from indexer for path \"%s\"\n", (char *)path);
            rpc_client_release (rpc, rpc_client, false);
        }
        else
        {
            rpc_client_release (rpc, rpc_client, true);
        }

        /* Result */
        INC_COUNTER (counters.indexed);
        INC_COUNTER (indexer->count);
        if (data.paths)
        {
            results = data.paths;
            break;
        }
    }
    g_list_free_full (indexers, (GDestroyNotify) cb_release);

    *result = results;
    return true;
}
Example #19
0
static int
validate_set (const char *path, const char *value)
{
    GList *validators = NULL;
    GList *iter = NULL;
    int32_t result = 0;

    /* Retrieve a list of validators for this path */
    validators = cb_match (&validation_list, path,
            CB_MATCH_EXACT|CB_MATCH_WILD|CB_MATCH_CHILD|CB_MATCH_WILD_PATH);
    if (!validators)
        return 0;

    /* Protect sensitive values with this lock - released in apteryx_set */
    pthread_mutex_lock (&validating);

    /* Call each validator */
    for (iter = validators; iter; iter = g_list_next (iter))
    {
        cb_info_t *validator = iter->data;
        ProtobufCService *rpc_client;
        Apteryx__Validate validate = APTERYX__VALIDATE__INIT;

        /* Check for local validator */
        if (validator->id == getpid ())
        {
            apteryx_watch_callback cb = (apteryx_watch_callback) (long) validator->cb;
            DEBUG ("VALIDATE LOCAL \"%s\" (0x%"PRIx64",0x%"PRIx64")\n",
                    validator->path, validator->id, validator->cb);
            cb (path, value);
            continue;
        }

        DEBUG ("VALIDATE CB %s = %s (0x%"PRIx64",0x%"PRIx64")\n",
                 validator->path, value, validator->id, validator->cb);

        /* Setup IPC */
        rpc_client = rpc_client_connect (rpc, validator->uri);
        if (!rpc_client)
        {
            /* Throw away the no good validator */
            ERROR ("Invalid VALIDATE CB %s (0x%"PRIx64",0x%"PRIx64")\n",
                    validator->path, validator->id, validator->cb);
            cb_destroy (validator);
            INC_COUNTER (counters.validated_no_handler);
            continue;
        }

        /* Do remote validate */
        validate.path = (char *)path;
        validate.value = (char *)value;
        validate.id = validator->id;
        validate.cb = validator->cb;
        apteryx__client__validate (rpc_client, &validate, handle_validate_response, &result);
        if (result < 0)
        {
            DEBUG ("Set of %s to %s rejected by process %"PRIu64" (%d)\n",
                    (char *)path, (char*)value, validator->id, result);
            INC_COUNTER (counters.validated_timeout);
            rpc_client_release (rpc, rpc_client, false);
            break;
        }
        else
        {
            rpc_client_release (rpc, rpc_client, true);
        }

        INC_COUNTER (counters.validated);
    }
    g_list_free_full (validators, (GDestroyNotify) cb_release);

    /* This one is fine, but lock is still held */
    return result < 0 ? result : 1;
}
Example #20
0
static void
notify_watchers (const char *path)
{
    GList *watchers = NULL;
    GList *iter = NULL;
    char *value = NULL;
    size_t vsize;

    /* Retrieve a list of watchers for this path */
    watchers = cb_match (&watch_list, path,
            CB_MATCH_EXACT|CB_MATCH_WILD|CB_MATCH_CHILD|CB_MATCH_WILD_PATH);
    if (!watchers)
        return;

    /* Find the new value for this path */
    value = NULL;
    vsize = 0;
    db_get (path, (unsigned char**)&value, &vsize);

    /* Call each watcher */
    for (iter = watchers; iter; iter = g_list_next (iter))
    {
        cb_info_t *watcher = iter->data;
        ProtobufCService *rpc_client;
        protobuf_c_boolean is_done = false;
        Apteryx__Watch watch = APTERYX__WATCH__INIT;

        /* Check for local watcher */
        if (watcher->id == getpid ())
        {
            apteryx_watch_callback cb = (apteryx_watch_callback) (long) watcher->cb;
            DEBUG ("WATCH LOCAL \"%s\" (0x%"PRIx64",0x%"PRIx64")\n",
                    watcher->path, watcher->id, watcher->cb);
            cb (path, value);
            continue;
        }

        DEBUG ("WATCH CB %s = %s (%s 0x%"PRIx64",0x%"PRIx64",%s)\n",
                path, value, watcher->path, watcher->id, watcher->cb, watcher->uri);

        /* Setup IPC */
        rpc_client = rpc_client_connect (rpc, watcher->uri);
        if (!rpc_client)
        {
            /* Throw away the no good validator */
            ERROR ("Invalid WATCH CB %s (0x%"PRIx64",0x%"PRIx64")\n",
                   watcher->path, watcher->id, watcher->cb);
            cb_destroy (watcher);
            INC_COUNTER (counters.watched_no_handler);
            continue;
        }

        /* Do remote watch */
        watch.path = (char *)path;
        watch.value = value;
        watch.id = watcher->id;
        watch.cb = watcher->cb;
        apteryx__client__watch (rpc_client, &watch, handle_watch_response, &is_done);
        if (!is_done)
        {
            INC_COUNTER (counters.watched_timeout);
            ERROR ("Failed to notify watcher for path \"%s\"\n", (char *)path);
            rpc_client_release (rpc, rpc_client, false);
        }
        else
        {
            rpc_client_release (rpc, rpc_client, true);
        }

        INC_COUNTER (counters.watched);
        INC_COUNTER (watcher->count);
    }
    g_list_free_full (watchers, (GDestroyNotify) cb_release);

    /* Free memory if allocated */
    if (value)
        g_free (value);
}
Example #21
0
static char *
provide_get (const char *path)
{
    GList *providers = NULL;
    char *value = NULL;
    GList *iter = NULL;

    /* Retrieve a list of providers for this path */
    providers = cb_match (&provide_list, path,
            CB_MATCH_EXACT|CB_MATCH_WILD|CB_MATCH_CHILD|CB_MATCH_WILD_PATH);
    if (!providers)
        return 0;

    /* Find the first good provider */
    for (iter = providers; iter; iter = g_list_next (iter))
    {
        cb_info_t *provider = iter->data;
        ProtobufCService *rpc_client;
        get_data_t data = {0};
        Apteryx__Provide provide = APTERYX__PROVIDE__INIT;

        /* Check for local provider */
        if (provider->id == getpid ())
        {
            apteryx_provide_callback cb = (apteryx_provide_callback) (long) provider->cb;
            DEBUG ("PROVIDE LOCAL \"%s\" (0x%"PRIx64",0x%"PRIx64")\n",
                                       provider->path, provider->id, provider->cb);
            value = cb (path);
            break;
        }

        DEBUG ("PROVIDE CB \"%s\" (0x%"PRIx64",0x%"PRIx64")\n",
               provider->path, provider->id, provider->cb);

        /* Setup IPC */
        rpc_client = rpc_client_connect (rpc, provider->uri);
        if (!rpc_client)
        {
            /* Throw away the no good validator */
            ERROR ("Invalid PROVIDE CB %s (0x%"PRIx64",0x%"PRIx64")\n",
                   provider->path, provider->id, provider->cb);
            cb_destroy (provider);
            INC_COUNTER (counters.provided_no_handler);
            continue;
        }

        /* Do remote get */
        provide.path = (char *) path;
        provide.id = provider->id;
        provide.cb = provider->cb;
        apteryx__client__provide (rpc_client, &provide, handle_get_response, &data);
        if (!data.done)
        {
            INC_COUNTER (counters.provided_timeout);
            ERROR ("No response from provider for path \"%s\"\n", (char *)path);
            rpc_client_release (rpc, rpc_client, false);
        }
        else
        {
            rpc_client_release (rpc, rpc_client, true);
        }

        /* Result */
        INC_COUNTER (counters.provided);
        INC_COUNTER (provider->count);
        if (data.value)
        {
            value = data.value;
            break;
        }
    }
    g_list_free_full (providers, (GDestroyNotify) cb_release);

    return value;
}