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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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 }
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; }
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; }
VolumeIntersectionValue View::TestAABB(const AABB& aabb) const { INC_COUNTER(g_count_bboxs); return _frustum.testIntersection(aabb); }
bool View::TestPlane(const Plane3& plane, const Matrix4& localToWorld) const { INC_COUNTER(g_count_oriented_planes); return _viewer.testPlane(plane, localToWorld); }
bool View::TestPlane(const Plane3& plane) const { INC_COUNTER(g_count_planes); return _viewer.testPlane(plane); }
VolumeIntersectionValue View::TestAABB(const AABB& aabb, const Matrix4& localToWorld) const { INC_COUNTER(g_count_oriented_bboxs); return _frustum.testIntersection(aabb, localToWorld); }
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; }
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; }
/* 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; }
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; }
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); }
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; }