void test_cb_destroy () { cb_info_t *cb; cb = cb_create (&watch_list, "abc", "/test", 1, 0); cb_destroy (cb); CU_ASSERT (g_list_length (watch_list) == 1); cb_release (cb); CU_ASSERT (g_list_length (watch_list) == 0); }
bool sc_quit(girara_session_t* session, girara_argument_t* UNUSED(argument), girara_event_t* UNUSED(event), unsigned int UNUSED(t)) { g_return_val_if_fail(session != NULL, false); girara_argument_t arg = { GIRARA_HIDE, NULL }; girara_isc_completion(session, &arg, NULL, 0); cb_destroy(NULL, NULL); return false; }
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 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; }
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 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; }
/* 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; }