コード例 #1
0
ファイル: aging.c プロジェクト: Haxe/gtk-gnutella
/**
 * Add value to the table.
 *
 * If it was already present, its lifetime is augmented by the aging delay.
 *
 * The key argument is freed immediately if there is a free routine for
 * keys and the key was present in the table.
 *
 * The previous value is freed and replaced by the new one if there is
 * an insertion conflict and the value pointers are different.
 */
void
aging_insert(aging_table_t *ag, const void *key, void *value)
{
	gboolean found;
	void *okey, *ovalue;
	time_t now = tm_time();
	struct aging_value *aval;

	g_assert(ag->magic == AGING_MAGIC);

	found = g_hash_table_lookup_extended(ag->table, key, &okey, &ovalue);
	if (found) {
		aval = ovalue;

		g_assert(aval->key == okey);

		if (aval->key != key && ag->kvfree != NULL) {
			/*
			 * We discard the new and keep the old key instead.
			 * That way, we don't have to update the hash table.
			 */

			(*ag->kvfree)(deconstify_gpointer(key), aval->value);
		}

		g_assert(aval->cq_ev != NULL);

		/*
		 * Value existed for this key, prolonge its life.
		 */

		aval->value = value;
		aval->ttl -= delta_time(now, aval->last_insert);
		aval->ttl += ag->delay;
		aval->ttl = MAX(aval->ttl, 1);
		aval->ttl = MIN(aval->ttl, INT_MAX / 1000);
		aval->last_insert = now;

		cq_resched(aval->cq_ev, 1000 * aval->ttl);
	} else {
		WALLOC(aval);
		aval->value = value;
		aval->key = deconstify_gpointer(key);
		aval->ttl = ag->delay;
		aval->ttl = MAX(aval->ttl, 1);
		aval->ttl = MIN(aval->ttl, INT_MAX / 1000);
		aval->last_insert = now;
		aval->ag = ag;

		aval->cq_ev = cq_insert(aging_cq, 1000 * aval->ttl, aging_expire, aval);
		gm_hash_table_insert_const(ag->table, key, aval);
	}
}
コード例 #2
0
ファイル: nodes.c プロジェクト: Longdengyu/gtk-gnutella
/**
 * Adds the given node to the gui.
 */
void
nodes_gui_add_node(gnet_node_info_t *n)
{
    GtkCList *clist_nodes;
	const gchar *titles[c_gnet_num];
	gchar proto_tmp[32];
    gint row;

    g_assert(n != NULL);

   	str_bprintf(proto_tmp, sizeof proto_tmp, "%d.%d",
		n->proto_major, n->proto_minor);

    titles[c_gnet_host]       = host_addr_port_to_string(n->addr, n->port);
    titles[c_gnet_flags]      = "...";
    titles[c_gnet_user_agent] = n->vendor
									? lazy_utf8_to_locale(n->vendor)
									: "...";
    titles[c_gnet_loc]        = iso3166_country_cc(n->country);
    titles[c_gnet_version]    = proto_tmp;
    titles[c_gnet_connected]  = "...";
    titles[c_gnet_uptime]     = "...";
    titles[c_gnet_info]       = "...";

    clist_nodes = GTK_CLIST(gui_main_window_lookup("clist_nodes"));

    row = gtk_clist_append(clist_nodes, (gchar **) titles); /* override const */
    gtk_clist_set_row_data(clist_nodes, row,
		deconstify_gpointer(nid_ref(n->node_id)));
}
コード例 #3
0
ファイル: nodes.c プロジェクト: Longdengyu/gtk-gnutella
/**
 * Removes all references to the given node handle in the gui.
 */
void
nodes_gui_remove_node(const struct nid *node_id)
{
    GtkWidget *clist_nodes;
    gint row;

    clist_nodes = gui_main_window_lookup("clist_nodes");

    /*
     * Make sure node is remove from the "changed" hash table so
     * we don't try an update.
     */
    g_assert(NULL != hs_node_info_changed);
    g_assert(NULL != hs_node_flags_changed);

    remove_item(hs_node_info_changed, node_id);
    remove_item(hs_node_flags_changed, node_id);

	row = gtk_clist_find_row_from_data(GTK_CLIST(clist_nodes),
				deconstify_gpointer(node_id));
    if (row != -1) {
        gtk_clist_remove(GTK_CLIST(clist_nodes), row);
		nid_unref(node_id);
	} else {
        g_warning("%s(): no matching row found", G_STRFUNC);
	}
}
コード例 #4
0
ファイル: nodes.c プロジェクト: lucab/gtk-gnutella
static inline void
nodes_gui_reverse_lookup_selected_helper(GtkTreeModel *model,
		GtkTreePath *unused_path, GtkTreeIter *iter, gpointer unused_data)
{
	struct node_data *data;
	gnet_node_info_t info;

	(void) unused_path;
	(void) unused_data;

	gtk_tree_model_get(model, iter, 0, &data, (-1));
	g_assert(NULL != find_node(data->node_id));

	if (hset_contains(ht_pending_lookups, data->node_id))
		return;

	guc_node_fill_info(data->node_id, &info);
	g_assert(data->node_id == info.node_id);

	if (!info.is_pseudo) {
		const struct nid *key = nid_ref(data->node_id);

		WFREE_NULL(data->host, data->host_size);
		data->host_size = w_concat_strings(&data->host,
				_("Reverse lookup in progress..."),
				" (", host_addr_port_to_string(info.addr, info.port), ")",
				(void *) 0);

		hset_insert(ht_pending_lookups, key);
		adns_reverse_lookup(info.addr, host_lookup_callback,
			deconstify_gpointer(nid_ref(key)));
	}
	guc_node_clear_info(&info);
}
コード例 #5
0
void
upload_stats_gui_add(struct ul_stats *us)
{
	GtkCList *clist = clist_ul_stats();
	const gchar *rowdata[c_us_num];
	enum c_us i;
	int row;
	char size_tmp[16];
	char attempts_tmp[16];
	char complete_tmp[16];
	char norm_tmp[16];
	char rtime_tmp[64];
	char dtime_tmp[64];

	g_strlcpy(size_tmp, short_size(us->size, show_metric_units()),
		sizeof size_tmp);
	gm_snprintf(attempts_tmp, sizeof attempts_tmp, "%u", us->attempts);
	gm_snprintf(complete_tmp, sizeof complete_tmp, "%u", us->complete);
	gm_snprintf(norm_tmp, sizeof norm_tmp, "%.3f", us->norm);
	if (us->rtime) {
		timestamp_to_string_buf(us->rtime, rtime_tmp, sizeof rtime_tmp);
	} else {
		rtime_tmp[0] = '\0';
	}
	if (us->dtime) {
		timestamp_to_string_buf(us->dtime, dtime_tmp, sizeof dtime_tmp);
	} else {
		dtime_tmp[0] = '\0';
	}

	for (i = 0; i < c_us_num; i++)
	switch (i) {
	case c_us_filename:
		rowdata[i] = lazy_utf8_to_ui_string(us->filename);
		break;
	case c_us_size: 	rowdata[i] = size_tmp; break;
	case c_us_attempts: rowdata[i] = attempts_tmp; break;
	case c_us_complete: rowdata[i] = complete_tmp; break;
	case c_us_norm: 	rowdata[i] = norm_tmp; break;
	case c_us_rtime: 	rowdata[i] = rtime_tmp; break;
	case c_us_dtime: 	rowdata[i] = dtime_tmp; break;
	case c_us_num:		g_assert_not_reached();
	}

    row = gtk_clist_append(clist, deconstify_gpointer(rowdata));
	g_return_if_fail(row >= 0);

	ul_stats_set_row(us, row);
	gtk_clist_set_row_data_full(clist, row, us, on_clist_ul_stats_row_removed);

    /* FIXME: should use auto_sort? */
	if (0 == clist->freeze_count) {
		gtk_clist_sort(clist);
		clist_sync_rows(clist, on_clist_ul_stats_row_moved);
	}
}
コード例 #6
0
ファイル: nodes.c プロジェクト: lucab/gtk-gnutella
static inline void
nodes_gui_remove_selected_helper(GtkTreeModel *model,
		GtkTreePath *unused_path, GtkTreeIter *iter, gpointer list_ptr)
{
	GSList **list = list_ptr;
	const struct node_data *data;

	(void) unused_path;

	gtk_tree_model_get(model, iter, 0, &data, (-1));
	*list = g_slist_prepend(*list, deconstify_gpointer(data->node_id));
}
コード例 #7
0
ファイル: nodes.c プロジェクト: Longdengyu/gtk-gnutella
/**
 * Update the row with the given nodeinfo. If row is -1 the row number
 * is determined by the node_id contained in the gnet_node_info_t.
 */
static void
nodes_gui_update_node_info(gnet_node_info_t *n, gint row)
{
    GtkCList *clist = GTK_CLIST(gui_main_window_lookup("clist_nodes"));

    g_assert(n != NULL);

    if (row == -1) {
        row = gtk_clist_find_row_from_data(clist,
					deconstify_gpointer(n->node_id));
    }

    if (row != -1) {
		gchar ver_buf[64];
        gnet_node_status_t status;
        time_t now = tm_time();

        if (guc_node_get_status(n->node_id, &status)) {
			gtk_clist_set_text(clist, row, c_gnet_user_agent,
					n->vendor ? lazy_utf8_to_locale(n->vendor) : "...");

			gtk_clist_set_text(clist, row, c_gnet_loc,
					deconstify_gchar(iso3166_country_cc(n->country)));

			str_bprintf(ver_buf, sizeof ver_buf, "%d.%d",
					n->proto_major, n->proto_minor);
			gtk_clist_set_text(clist, row, c_gnet_version, ver_buf);

			if (status.status == GTA_NODE_CONNECTED)
				gtk_clist_set_text(clist, row, c_gnet_connected,
						short_uptime(delta_time(now, status.connect_date)));

			if (status.up_date)
				gtk_clist_set_text(clist, row, c_gnet_uptime,
						status.up_date
						? short_uptime(delta_time(now, status.up_date)) : "...");

			gtk_clist_set_text(clist, row, c_gnet_info,
					nodes_gui_common_status_str(&status));
		}
    } else {
        g_warning("%s(): no matching row found", G_STRFUNC);
    }
}
コード例 #8
0
ファイル: nodes.c プロジェクト: Longdengyu/gtk-gnutella
/**
 * Updates the flags for given node and row.
 */
static void
nodes_gui_update_node_flags(const struct nid *node_id, gnet_node_flags_t *flags,
	gint row)
{
    GtkCList *clist = GTK_CLIST(gui_main_window_lookup("clist_nodes"));

    if (row == -1)
        row = gtk_clist_find_row_from_data(clist, deconstify_gpointer(node_id));

    if (row != -1) {
        gtk_clist_set_text(clist, row, c_gnet_flags,
			guc_node_flags_to_string(flags));
	if (NODE_P_LEAF == flags->peermode || NODE_P_NORMAL == flags->peermode) {
		GdkColor *color = &(gtk_widget_get_style(GTK_WIDGET(clist))
			->fg[GTK_STATE_INSENSITIVE]);
		gtk_clist_set_foreground(clist, row, color);
	}

    } else {
        g_warning("%s(): no matching row found", G_STRFUNC);
    }
}
コード例 #9
0
static void
dbg_property_show_list(const GSList *props)
{
	GtkCList *clist;
	const GSList *sl;

   	clist = GTK_CLIST(gui_dlg_prefs_lookup("clist_dbg_property"));
	gtk_clist_freeze(clist);
	gtk_clist_clear(clist);

	for (sl = props; NULL != sl; sl = g_slist_next(sl)) {
		static const gchar * const titles[num_dbg_cols] = { "", "", "", "", };
		property_t prop = GPOINTER_TO_UINT(sl->data);
		gint row;
		
    	row = gtk_clist_append(clist, deconstify_gpointer(titles));
		dbg_property_set_row(clist, row, prop);	
	}
	gtk_clist_sort(clist);
	gtk_clist_columns_autosize(clist);
	gtk_clist_thaw(clist);
}
コード例 #10
0
ファイル: bh_upload.c プロジェクト: Haxe/gtk-gnutella
/**
 * Writes the browse host data of the context ``ctx'' to the buffer
 * ``dest''. This must be called multiple times to retrieve the complete
 * data until zero is returned i.e., the end of file is reached.
 *
 * This routine deals with query hit data generation.
 *
 * @param ctx an initialized browse host context.
 * @param dest the destination buffer.
 * @param size the amount of bytes ``dest'' can hold.
 *
 * @return -1 on failure, zero at the end-of-file condition or if size
 *         was zero. On success, the amount of bytes copied to ``dest''
 *         is returned.
 */
static ssize_t
browse_host_read_qhits(struct special_upload *ctx,
                       gpointer const dest, size_t size)
{
    struct browse_host_upload *bh = cast_to_browse_host_upload(ctx);
    size_t remain = size;
    char *p = dest;

    /*
     * If we have no hit pending that we can send, build some more.
     */

    if (NULL == bh->hits) {
        GSList *files = NULL;
        int i;

        for (i = 0; i < BH_SCAN_AHEAD; i++) {
            const shared_file_t *sf;

            do {
                /* Skip holes in indices */
                bh->file_index++;
                sf = shared_file_sorted(bh->file_index);
            } while (NULL == sf && bh->file_index <= shared_files_scanned());

            if (SHARE_REBUILDING == sf || NULL == sf)
                break;

            files = g_slist_prepend(files, deconstify_gpointer(sf));
        }

        if (NULL == files)		/* Did not find any more file to include */
            return 0;			/* We're done */

        /*
         * Now build the query hits containing the files we selected.
         */

        files = g_slist_reverse(files);			/* Preserve order */

        qhit_build_results(files, i, BH_MAX_QHIT_SIZE,
                           browse_host_record_hit, bh, &blank_guid, FALSE, &zero_array);

        g_assert(bh->hits != NULL);		/* At least 1 hit enqueued */

        bh->hits = g_slist_reverse(bh->hits);	/* Preserve order */
        gm_slist_free_null(&files);
    }

    /*
     * Read each query hit in turn.
     */

    while (remain > 0 && NULL != bh->hits) {
        pmsg_t *mb = bh->hits->data;
        int r;

        r = pmsg_read(mb, p, remain);
        p += r;
        remain -= r;

        if (r == 0 || 0 == pmsg_size(mb)) {
            bh->hits = g_slist_remove(bh->hits, mb);
            pmsg_free(mb);
        }
    }

    return size - remain;
}
コード例 #11
0
ファイル: upload_stats.c プロジェクト: Haxe/gtk-gnutella
/**
 * Locate statistics structure for the file.
 *
 * If a SHA1 is given, we search by SHA1. Otherwise we search by (name, size)
 * and if the record is missing the SHA1, probably because it was not
 * available at the time of insertion, then it is added to the structure
 * and recorded as such.
 */
static struct ul_stats *
upload_stats_find(const struct sha1 *sha1, const char *pathname, guint64 size)
{
	struct ul_stats *s = NULL;

	if (upload_stats_list) {
		static const struct ul_stats zero_stats;
		struct ul_stats key;
		gconstpointer orig_key;

		g_assert(upload_stats_by_sha1);

		if (sha1) {
			s = g_hash_table_lookup(upload_stats_by_sha1, sha1);
			if (s)
				goto done;		/* Found it by SHA1 */
		}

		key = zero_stats;
		key.pathname = atom_str_get(pathname);
		key.size = size;

		if (hash_list_find(upload_stats_list, &key, &orig_key))
			s = deconstify_gpointer(orig_key);
		atom_str_free_null(&key.pathname);

		if (s && sha1) {
			/* Was missing from the by-SHA1 table */
			if (NULL == s->sha1) {
				/* SHA1 was unknown */

				s->sha1 = atom_sha1_get(sha1);
			} else {
				/* SHA1 changed, file was modified */
				struct ul_stats *old =
					g_hash_table_lookup(upload_stats_by_sha1, s->sha1);

				g_assert(old == s);		/* Must be the same filename entry */

				g_hash_table_remove(upload_stats_by_sha1, s->sha1);
				atom_sha1_free(s->sha1);
				s->sha1 = atom_sha1_get(sha1);
			}
			gm_hash_table_insert_const(upload_stats_by_sha1, s->sha1, s);
		}
	}

done:

	/* We guarantee the SHA1 is present in the record if known */
	g_assert(!(s && sha1) || s->sha1);

	/* Postcondition: if we return something, it must be "correct" */
	if (s != NULL) {
		g_assert(atom_is_str(s->pathname));
		g_assert(atom_is_str(s->filename));
		g_assert(s->norm >= 0.0);
	}

	return s;
}