/** * Initialize web cache. */ void gwc_init(void) { uint i; gwc_known_url = hset_create(HASH_KEY_STRING, 0); gwc_failed_url = hset_create(HASH_KEY_STRING, 0); gwc_retrieve(); if (0 == hset_count(gwc_known_url)) { for (i = 0; i < N_ITEMS(boot_url) && boot_url[i]; i++) gwc_add(boot_url[i]); } }
static int subscribe_channel(sub_client *c, sds channel) { TrieData data; size_t len; AlphaChar *chan_alpha; len = sdslen(channel); chan_alpha = (AlphaChar *) malloc(sizeof(AlphaChar) * len + 1); conv_to_alpha(server.dflt_to_alpha_conv, channel, chan_alpha, len+1); /* channel not exists in trie, create */ if (!trie_retrieve(server.sub_trie, chan_alpha, &data)) { if (!trie_store(server.sub_trie, chan_alpha, TRIE_DATA_DFLT)) { srv_log(LOG_ERROR, "Failed to insert key %s into sub trie", channel); return SUBCLI_ERR; } /* create hashtable mapping from subscribe-channel to client id set */ hset *hs = hset_create(SUB_SET_LEN); hset_insert(hs, CLIENT_ID_LEN, c->id, c); if (ght_insert(server.subscibe_table, hs, len, channel) == -1) { hset_release(hs); srv_log(LOG_ERROR, "Failed to insert key[%s]->set into subscribe hashtable", channel); return SUBCLI_ERR; } } return SUBCLI_OK; }
/* * If we detect that stdio cannot handle file descriptors above 255, this * functions tries to reassign 'fd' to a file descriptor above 255 in order to * reserve lower file descriptors for stdio. File descriptors below 3 or above * 255 are returned as-is. The original file descriptor is closed if it was * reassigned. On systems which do not need this workaround, the original * file descriptor is returned. * * @note The FD_CLOEXEC flag set will be cleared on the new file descriptor if * the file descriptor is successfully reassigned. * * @return On success a new file descriptor above 255 is returned. * On failure or if reassigning was not necessary the original file * descriptor is returned. */ int fd_get_non_stdio(int fd) { if (fd_need_non_stdio() && fd > 2 && fd < 256) { int nfd, saved_errno; saved_errno = errno; nfd = fcntl(fd, F_DUPFD, 256); if (nfd > 0) { close(fd); compat_socket_duped(fd, nfd); fd = nfd; } errno = saved_errno; } /* * On Windows, files and sockets do not share the same ID space. * Therefore, on that platform we use this routine as a hook to * record active socket descriptors in a table. * --RAM, 2015-04-05 */ if (is_running_on_mingw()) { /* We don't expect thread race conditions here */ if G_UNLIKELY(NULL == fd_sockets) fd_sockets = hset_create(HASH_KEY_SELF, 0); if (is_a_socket(fd)) hset_insert(fd_sockets, int_to_pointer(fd)); } return fd; }
/** * Create a new search queue. */ squeue_t * sq_make(struct gnutella_node *node) { squeue_t *sq; /* * By initializing `last_sent' to the current time and not to `0', we * ensure that we won't send the query to the node during the first * "search_queue_spacing" seconds of its connection. This prevent * useless traffic on Gnet, because if the connection is held for that * long, chances are it will hold until we get some results back. * * --RAM, 01/05/2002 */ WALLOC(sq); sq->count = 0; sq->last_sent = tm_time(); sq->searches = NULL; sq->n_sent = 0; sq->n_dropped = 0; sq->node = node; sq->handles = hset_create(HASH_KEY_SELF, 0); return sq; }
MotoPP *motopp_createEnv(char *filename, int flags) { MotoPP *ppenv; ppenv = emalloc(sizeof(MotoPP)); ppenv->flags = flags; ppenv->mpool = mpool_create(10); ppenv->sysptrs = hset_create(M_SIZE, NULL, NULL, 0); ppenv->ptrs = hset_create(M_SIZE, NULL, NULL, 0); ppenv->out = buf_createDefault(); ppenv->err = buf_createDefault(); ppenv->argbuf = buf_createDefault(); ppenv->dirstack = istack_createDefault(); ppenv->macrostack = stack_createDefault(); ppenv->vallist = hset_create(M_SIZE, NULL, NULL, 0); ppenv->frames = stack_createDefault(); ppenv->frame = motopp_createFrame(ppenv, MAIN_FRAME,filename); ppenv->mb = NULL; return ppenv; }
/** * Register object in the supplied hash table (passed by reference, created * if not existing already). */ static void cq_register_object(hset_t **hptr, void *o) { hset_t *h = *hptr; g_assert(o != NULL); if (NULL == h) *hptr = h = hset_create(HASH_KEY_SELF, 0); g_assert(!hset_contains(h, o)); hset_insert(h, o); }
/** * Recreate keyinfo data from persisted information. */ static G_GNUC_COLD void keys_init_keyinfo(void) { struct keys_create_context ctx; if (GNET_PROPERTY(dht_keys_debug)) { size_t count = dbmw_count(db_keydata); g_debug("DHT KEYS scanning %u persisted key%s", (unsigned) count, plural(count)); } ctx.our_kuid = get_our_kuid(); ctx.dbkeys = hset_create(HASH_KEY_FIXED, sizeof(uint64)); dbmw_foreach_remove(db_keydata, reload_ki, &ctx); if (GNET_PROPERTY(dht_keys_debug)) { size_t count = dbmw_count(db_keydata); g_debug("DHT KEYS kept %u key%s, now loading associated values", (unsigned) count, plural(count)); } /* * FIXME: * Unfortunately, we have to reset the keydata database for each of * the keys we're going to recreate, because the logic adding values * back to the key will fill each of the keydata appropriately, and it * expects the amount of values in the keyinfo and the keydata to match. * * Therefore, we need to rename the old keydata database, open a new one, * write empty keydata values in it, then discard the old keydata if * everything goes well. In case of a crash in the middle of the * restoration, we'll be able to recover by opening the old keydata first * if it exists. * * It is far from critical though: if we reset the keydata database and * we crash in the middle of the restore, then we'll lose all the persisted * keys and values and will simply restart with an empty storage. * * Given the contorsions needed to fix that, and the little value for * the user, just leaving a FIXME note. * --RAM, 2012-11-17 */ hikset_foreach(keys, keys_reset_keydata, NULL); values_init_data(ctx.dbkeys); hset_foreach(ctx.dbkeys, keys_free_dbkey, NULL); hset_free_null(&ctx.dbkeys); hikset_foreach_remove(keys, keys_discard_if_empty, NULL); dbmw_foreach_remove(db_keydata, keys_delete_if_empty, NULL); dbstore_compact(db_keydata); g_soft_assert_log(hikset_count(keys) == dbmw_count(db_keydata), "keys reloaded: %zu, key data persisted: %zu", hikset_count(keys), dbmw_count(db_keydata)); if (GNET_PROPERTY(dht_keys_debug)) { g_debug("DHT KEYS reloaded %zu key%s", hikset_count(keys), plural(hikset_count(keys))); } gnet_stats_set_general(GNR_DHT_KEYS_HELD, hikset_count(keys)); }
/** * Extended XML formatting of a tree. * * Namespaces, if any, are automatically assigned a prefix, whose format * is "ns%u", the counter being incremented from 0. * * Users can supply a vector mapping namespaces to prefixes, so that they * can force specific prefixes for a given well-known namespace. * * If there is a default namespace, all the tags belonging to that namespace * are emitted without any prefix. * * The output stream must be explicitly closed by the user upon return. * * Options can be supplied to tune the output: * * - XFMT_O_SKIP_BLANKS will skip pure white space nodes. * - XFMT_O_COLLAPSE_BLANKS will replace consecutive blanks with 1 space * - XFMT_O_NO_INDENT requests that no indentation of the tree be made. * - XFMT_O_PROLOGUE emits a leading <?xml?> prologue. * - XFMT_O_FORCE_10 force generation of XML 1.0 * - XFMT_O_SINGLE_LINE emits XML as one big line (implies XFMT_O_NO_INDENT). * * @param root the root of the tree to dump * @param os the output stream where tree is dumped * @param options formatting options, as documented above * @param pvec a vector of prefixes to be used for namespaces * @param pvcnt amount of entries in vector * @param default_ns default namespace to install at root element * * @return TRUE on success. */ bool xfmt_tree_extended(const xnode_t *root, ostream_t *os, uint32 options, const struct xfmt_prefix *pvec, size_t pvcnt, const char *default_ns) { struct xfmt_pass1 xp1; struct xfmt_pass2 xp2; struct xfmt_invert_ctx ictx; const char *dflt_ns; g_assert(root != NULL); g_assert(os != NULL); if (options & XFMT_O_COLLAPSE_BLANKS) { /* FIXME */ g_carp("XFMT_O_COLLAPSE_BLANKS not supported yet"); stacktrace_where_print(stderr); } if (options & XFMT_O_SINGLE_LINE) options |= XFMT_O_NO_INDENT; /* * First pass: look at namespaces and construct a table recording the * earliest tree depth at which a namespace is used. */ ZERO(&xp1); xp1.uri2node = htable_create(HASH_KEY_STRING, 0); xp1.uri2prefix = nv_table_make(FALSE); if (default_ns != NULL) xp1.attr_uris = hset_create(HASH_KEY_STRING, 0); htable_insert_const(xp1.uri2node, VXS_XML_URI, root); xnode_tree_enter_leave(deconstify_pointer(root), xfmt_handle_pass1_enter, xfmt_handle_pass1_leave, &xp1); g_assert(0 == xp1.depth); /* Sound traversal */ /* * If there was a default namespace, make sure it is used in the tree. * Otherwise, discard it. */ if (default_ns != NULL) { if (NULL == htable_lookup(xp1.uri2node, default_ns)) { g_carp("XFMT default namespace '%s' is not needed", default_ns); dflt_ns = NULL; } else { dflt_ns = default_ns; } } else { dflt_ns = NULL; } /* * Prepare context for second pass. */ ZERO(&xp2); xp2.node2uri = htable_create(HASH_KEY_SELF, 0); xp2.os = os; xp2.options = options; xp2.default_ns = dflt_ns; xp2.attr_uris = xp1.attr_uris; xp2.uri2prefix = xp1.uri2prefix; xp2.uris = symtab_make(); xp2.prefixes = symtab_make(); xp2.depth = 0; xp2.pcount = 0; xp2.last_was_nl = TRUE; /* * Iterate over the hash table we've built to create a table indexed * by tree node and listing the namespaces to declare for that node. */ ictx.uri2node = xp1.uri2node; ictx.node2uri = xp2.node2uri; htable_foreach(xp1.uri2node, xfmt_invert_uri_kv, &ictx); htable_free_null(&xp1.uri2node); /* * Emit prologue if requested. */ if (options & XFMT_O_PROLOGUE) { if (options & XFMT_O_FORCE_10) { ostream_write(os, XFMT_DECL_10, CONST_STRLEN(XFMT_DECL_10)); } else { ostream_write(os, XFMT_DECL, CONST_STRLEN(XFMT_DECL)); } if (!(options & XFMT_O_SINGLE_LINE)) { ostream_putc(os, '\n'); } } xfmt_prefix_declare(&xp2, VXS_XML_URI, VXS_XML); /* * Prepare user-defined URI -> prefix mappings. */ if (pvcnt != 0) { size_t i; for (i = 0; i < pvcnt; i++) { const struct xfmt_prefix *p = &pvec[i]; xfmt_prefix_declare(&xp2, p->uri, p->prefix); } } /* * Second pass: generation. */ xnode_tree_enter_leave(deconstify_pointer(root), xfmt_handle_pass2_enter, xfmt_handle_pass2_leave, &xp2); g_assert(0 == xp2.depth); /* Sound traversal */ /* * Done, cleanup. */ nv_table_free_null(&xp2.uri2prefix); symtab_free_null(&xp2.prefixes); symtab_free_null(&xp2.uris); htable_free_null(&xp2.node2uri); hset_free_null(&xp2.attr_uris); return !ostream_has_ioerr(os); }
HashSet *hset_createDefault() { return hset_create(HSET_DEFAULT_SIZE, NULL, NULL, 0); }
/** * Allocate the fd_preserved set if not done already. */ static void fd_preserved_allocate(void) { fd_preserved = hset_create(HASH_KEY_SELF, 0); hset_thread_safe(fd_preserved); }