/** * Unregister object from the hash table. */ static void cq_unregister_object(hset_t *h, void *o) { g_assert(h != NULL); g_assert(o != NULL); g_assert(hset_contains(h, o)); hset_remove(h, o); }
/** * Notifies that a socket descriptor has been closed. * * This is only required on Windows, since we need to keep track of opened * socket descriptors, in order to close them before exec(). Failure to * do so would leave listen sockets around, and because we use SO_REUSEADDR * to bind our listening sockets, we would have two processes listening on * the same socket -- a recipe for blackouts on Windows! */ void fd_notify_socket_closed(socket_fd_t fd) { if (!is_running_on_mingw()) { s_carp_once("%s(): not needed on UNIX", G_STRFUNC); return; } else { if G_LIKELY(fd_sockets != NULL) hset_remove(fd_sockets, int_to_pointer(fd)); } }
/** * Remove search handle from the hash table. */ static void sqh_remove(squeue_t *sq, gnet_search_t sh) { const void *key; bool found; g_assert(sq != NULL); found = hset_contains_extended(sq->handles, uint_to_pointer(sh), &key); g_assert(found); g_assert((gnet_search_t) pointer_to_uint(key) == sh); hset_remove(sq->handles, key); }
static void result_data_free(search_t *search, struct result_data *rd) { record_check(rd->record); g_assert(hset_contains(search->dups, rd->record)); hset_remove(search->dups, rd->record); search_gui_unref_record(rd->record); search_gui_unref_record(rd->record); /* * rd->record may point to freed memory now if this was the last reference */ WFREE(rd); }
static bool remove_item(hset_t *hs, const struct nid *node_id) { const void *orig_key; g_return_val_if_fail(hs, FALSE); g_return_val_if_fail(node_id, FALSE); if (hset_contains_extended(hs, node_id, &orig_key)) { hset_remove(hs, orig_key); nid_unref(orig_key); return TRUE; } else { return FALSE; } }
static gboolean remove_item(hset_t *hs, const struct nid *node_id) { void *orig_key; g_return_val_if_fail(hs, FALSE); g_return_val_if_fail(node_id, FALSE); orig_key = hset_lookup(hs, node_id); if (orig_key) { hset_remove(hs, orig_key); nid_unref(orig_key); return TRUE; } else { return FALSE; } }
/** * Closes the file and sets the descriptor to -1. Does nothing if * the descriptor is already -1. * * @param fd_ptr Must point to a non-negative file descriptor or -1. * * @return 0 on success, -1 on error. */ int fd_close(int *fd_ptr) { int ret, fd; g_assert(NULL != fd_ptr); fd = *fd_ptr; g_assert(fd >= -1); if (fd < 0) { ret = 0; } else { if (fd_preserved != NULL) hset_remove(fd_preserved, int_to_pointer(fd)); ret = close(fd); *fd_ptr = -1; } return ret; }
/** * Removes the URL from the set of known URL, but do not free its memory * and keeps it in the set of failed URLs for the session. */ static void gwc_forget_url(const char *url) { struct gwc url_tmp[MAX_GWC_URLS]; /* Temporary copy */ int count = hset_count(gwc_known_url); int i; int j = 0; g_assert(count > 0); g_assert(count <= MAX_GWC_URLS); g_assert(count == MAX_GWC_URLS || gwc_url_slot < count); g_assert(gwc_url_slot >= 0); STATIC_ASSERT(sizeof(url_tmp) == sizeof(gwc_url)); if (GNET_PROPERTY(bootstrap_debug)) g_warning("forgetting GWC URL \"%s\"", url); /* * It is possible that the URL we're trying to forget was * already removed from the cache if it was at a slot overridden * in the round-robin buffer, should we have got new GWC URL since * it was selected. */ if (hset_contains(gwc_known_url, url)) hset_remove(gwc_known_url, url); else { if (GNET_PROPERTY(bootstrap_debug)) g_warning("URL was already gone from GWC"); return; } hset_insert(gwc_failed_url, url); /* * Because we have a round-robin buffer, removing something in the * middle of the buffer is not straightforward. The `gwc_url_slot' * variable points to the last filled value in the buffer. * * We're going to build a copy in url_tmp[], filled from 0 to "count - 1", * and we'll move back that copy into the regular gwc_url[] cache. * The reason is that since there will be less entries in the cache * than the maximum amount, the round-robin buffer must be linearily * filled from 0 and upwards. */ memset(url_tmp, 0, sizeof(url_tmp)); if (count == MAX_GWC_URLS) { /* Buffer was full */ for (i = gwc_url_slot;;) { if (gwc_url[i].url != url) /* Atoms: we can compare addresses */ url_tmp[j++] = gwc_url[i]; i++; if (i == MAX_GWC_URLS) i = 0; if (i == gwc_url_slot) /* Back to where we started */ break; } } else { /* Buffer was partially filled */ for (i = 0; i <= gwc_url_slot; i++) { if (gwc_url[i].url != url) /* Atoms: we can compare addresses */ url_tmp[j++] = gwc_url[i]; } } count--; /* New amount of data in cache */ gwc_url_slot = j - 1; /* Last position we filled */ gwc_url_slot = MAX(0, gwc_url_slot); /* If we removed ALL entries */ g_assert(gwc_url_slot == MAX(0, count - 1)); memcpy(gwc_url, url_tmp, sizeof(gwc_url)); g_assert(gwc_url_slot >= 0 && gwc_url_slot < MAX_GWC_URLS); gwc_file_dirty = TRUE; }
/** * Add new URL to cache, possibly pushing off an older one if cache is full. * * @return TRUE if the URL was added, FALSE otherwise. */ static bool gwc_add(const char *new_url) { const char *url_atom; const char *old_url; char *url, *ret; url = h_strdup(new_url); /* url_normalize() can modify the URL */ ret = url_normalize(url, URL_POLICY_GWC_RULES); if (!ret) { g_warning("%s(): ignoring bad web cache URL \"%s\"", G_STRFUNC, new_url); HFREE_NULL(url); return FALSE; } if (ret != url) { HFREE_NULL(url); url = ret; } /* * Don't add duplicates to the cache. */ if ( hset_contains(gwc_known_url, url) || hset_contains(gwc_failed_url, url) ) { HFREE_NULL(url); return FALSE; } /* * OK, record new entry at the `gwc_url_slot'. */ if (++gwc_url_slot >= MAX_GWC_URLS) gwc_url_slot = 0; g_assert(url != NULL); url_atom = atom_str_get(url); HFREE_NULL(url); /* * Expire any entry present at the slot we're about to write into. */ old_url = gwc_url[gwc_url_slot].url; if (old_url != NULL) { g_assert(hset_contains(gwc_known_url, old_url)); hset_remove(gwc_known_url, old_url); atom_str_free_null(&old_url); gwc_url[gwc_url_slot].url = NULL; } hset_insert(gwc_known_url, url_atom); gwc_url[gwc_url_slot].url = url_atom; gwc_url[gwc_url_slot].stamp = 0; gwc_file_dirty = TRUE; if (GNET_PROPERTY(bootstrap_debug)) { g_debug("%s(): loaded GWC URL %s", G_STRFUNC, url_atom); } return TRUE; }
void motopp_freeEnv(MotoPP *ppenv) { Enumeration *e; log_debug(__FILE__, ">>> motopp_freeEnv\n"); buf_free(ppenv->out); buf_free(ppenv->err); buf_free(ppenv->argbuf); istack_free(ppenv->dirstack); stack_free(ppenv->frames); /* free vals */ e = hset_elements(ppenv->vallist); while (enum_hasNext(e)) { MotoPPVal *val = enum_next(e); if (shared_check(val->sval)) { free(val->sval); hset_remove(ppenv->ptrs, val->sval); } free(val); } enum_free(e); hset_free(ppenv->vallist); /* free macros */ while (stack_size(ppenv->macrostack) > 0) { SymbolTable *macros = stack_pop(ppenv->macrostack); e = stab_getKeys(macros); while (enum_hasNext(e)) { char *name = (char *)enum_next(e); MotoMacro *m = (MotoMacro *)stab_get(macros, name); motopp_freeMacro(m); } stab_free(macros); enum_free(e); } /* free all remaining sys pointers */ e = hset_elements(ppenv->sysptrs); while (enum_hasNext(e)) { void *ptr = enum_next(e); if (ptr) { sys_free(ptr); } } enum_free(e); /* free all remaining pointers */ e = hset_elements(ppenv->ptrs); while (enum_hasNext(e)) { void *ptr = enum_next(e); if (shared_check(ptr)) { free(ptr); } } enum_free(e); /* free remaining pooled memory */ mpool_free(ppenv->mpool); /* free remainder of env struct */ hset_free(ppenv->sysptrs); hset_free(ppenv->ptrs); stack_free(ppenv->macrostack); free(ppenv); log_debug(__FILE__, "<<< motopp_freeEnv\n"); }