Core Dump Fix, So Help Me God.
git-svn-id: http://svn.code.sf.net/p/xqf/code/trunk@40 d2ac09be-c843-0410-8b1f-f8a84130e0ec
This commit is contained in:
parent
3bfcfa9d03
commit
82fe0199e3
@ -1,3 +1,13 @@
|
||||
Feb 14, 2001: Bill Adams <bill@evil.inetarena.com>
|
||||
-Oh dear god, I think I fixed the core dumps related
|
||||
to the reference counting on the server structures.
|
||||
At least to the best of my ability, I cannot make
|
||||
the server references increase or decrease
|
||||
over time: i.e. the program always exits with
|
||||
a reference count of one on all server structures.
|
||||
I could not figure out why it was 1 and not zero
|
||||
but I will deal with that later.
|
||||
|
||||
Feb 13, 2001: Bill Adams <bill@evil.inetarena.com>
|
||||
-Changed version to 0.9.6f, added announcement dir
|
||||
and announcement.
|
||||
|
@ -81,7 +81,8 @@ static struct server *server_new (struct host *h, unsigned short port,
|
||||
|
||||
server = g_malloc0 (sizeof (struct server));
|
||||
debug (6, "server_new() -- Server %lx", server);
|
||||
server_ref (server);
|
||||
|
||||
server_ref (server);
|
||||
|
||||
server->host = h;
|
||||
host_ref (h); /* Increse the refernece count on the host struct */
|
||||
@ -258,9 +259,12 @@ void userver_unref (struct userver *s) {
|
||||
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
|
||||
s->ref_count--;
|
||||
|
||||
debug (6, "userver_unref() -- UServer %lx ref now at %d",
|
||||
s, s->ref_count);
|
||||
|
||||
if (s->ref_count <= 0) {
|
||||
node = userver_hash_func (s->hostname, s->port);
|
||||
uservers.nodes[node] = g_slist_remove (uservers.nodes[node], s);
|
||||
@ -444,9 +448,12 @@ void uservers_to_servers (GSList **uservers, GSList **servers) {
|
||||
struct userver *us;
|
||||
GSList *tmp = *uservers;
|
||||
|
||||
debug (6, "uservers_to_servers() -- uservers %lx tmp %lx", uservers, tmp);
|
||||
while (tmp) {
|
||||
us = (struct userver *) tmp->data;
|
||||
debug (7, "uservers_to_servers() -- Check userver %lx", us);
|
||||
if (us->s) {
|
||||
debug (7, "uservers_to_servers() -- server %lx userver %lx", us->s, us);
|
||||
*servers = server_list_append (*servers, us->s);
|
||||
|
||||
*uservers = g_slist_remove (*uservers, us);
|
||||
@ -457,9 +464,17 @@ void uservers_to_servers (GSList **uservers, GSList **servers) {
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
debug (6, "uservers_to_servers() -- Done.");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
server_lists_intersect() -- Find servers that are
|
||||
in two lists (by reference). The first arg gets a list
|
||||
of servers not in both lists. The second list gets servers
|
||||
removed that are in both lists.
|
||||
*/
|
||||
|
||||
void server_lists_intersect (GSList **list1, GSList **list2) {
|
||||
GSList *list3 = NULL;
|
||||
GSList *tmp;
|
||||
|
@ -45,6 +45,7 @@ extern int servers_total (void);
|
||||
extern int uservers_total (void);
|
||||
extern GSList *all_servers (void);
|
||||
|
||||
|
||||
extern int parse_address (char *str, char **addr, unsigned short *port);
|
||||
|
||||
extern struct server *userver_set_host (struct userver *s, struct host *h);
|
||||
@ -86,6 +87,7 @@ static inline GSList *server_list_append (GSList *list, struct server *server) {
|
||||
}
|
||||
|
||||
static inline GSList *server_list_remove (GSList *list, struct server *s) {
|
||||
debug (6, "server_list_remove() -- remove server %lx from list %lx", s, list);
|
||||
if (g_slist_find (list, s)) {
|
||||
list = g_slist_remove (list, s);
|
||||
server_unref (s);
|
||||
|
@ -58,6 +58,7 @@ static void save_list (FILE *f, struct master *m) {
|
||||
|
||||
if (!m->servers)
|
||||
return;
|
||||
debug (6, "save_list() -- Saving Server List \"%s\"", m->name );
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "Saving server list \"%s\"...\n", m->name);
|
||||
@ -97,6 +98,7 @@ void save_favorites (void) {
|
||||
FILE *f;
|
||||
char *realname;
|
||||
|
||||
debug (6, "save_favorites() --");
|
||||
realname = file_in_dir (user_rcdir, FILENAME_FAVORITES);
|
||||
|
||||
while (1) {
|
||||
@ -125,6 +127,7 @@ static void save_lists (GSList *list, const char *filename) {
|
||||
char *realname;
|
||||
struct zstream z;
|
||||
|
||||
debug (6, "save_lists() -- %s", filename);
|
||||
realname = file_in_dir (user_rcdir, filename);
|
||||
|
||||
if (!list) {
|
||||
@ -363,6 +366,12 @@ static void master_add_server (struct master *m, char *str,
|
||||
host_ref (h);
|
||||
if ((s = server_add (h, port, type)) != NULL) {
|
||||
m->servers = server_list_prepend (m->servers, s);
|
||||
/* Since the server_add increments the ref count, and
|
||||
server_list_prepend ups the ref_count, we should
|
||||
unref it once because we are only keeping it in
|
||||
one list after this function.
|
||||
*/
|
||||
server_unref (s);
|
||||
}
|
||||
host_unref (h);
|
||||
}
|
||||
@ -1014,6 +1023,7 @@ void init_masters (int update) {
|
||||
void free_masters (void) {
|
||||
GSList *tmp;
|
||||
|
||||
debug (6, "free_masters() --");
|
||||
save_favorites ();
|
||||
|
||||
if (default_save_lists) {
|
||||
@ -1023,7 +1033,7 @@ void free_masters (void) {
|
||||
g_slist_free (tmp);
|
||||
|
||||
if (default_save_srvinfo) {
|
||||
tmp = all_servers ();
|
||||
tmp = all_servers (); /* free done in two lines */
|
||||
save_server_info (FILENAME_SRVINFO, tmp);
|
||||
server_list_free (tmp);
|
||||
}
|
||||
@ -1057,6 +1067,7 @@ static void master_list_add (GSList **masters, GSList **servers,
|
||||
GSList **uservers, struct master *m) {
|
||||
GSList *tmp;
|
||||
|
||||
debug (6, "master_list_add() -- master '%s'", m->name);
|
||||
if (m->isgroup || m == favorites) {
|
||||
if (servers) {
|
||||
*servers = server_list_append_list (*servers, favorites->servers,
|
||||
@ -1105,7 +1116,7 @@ void master_selection_to_lists (GSList *list, GSList **masters,
|
||||
GSList **servers, GSList **uservers) {
|
||||
struct master *m;
|
||||
GSList *tmp;
|
||||
|
||||
debug (6, "master_selection_to_lists() --");
|
||||
for (tmp = list; tmp; tmp = tmp->next) {
|
||||
m = (struct master *) tmp->data;
|
||||
uservers_to_servers (&m->uservers, &m->servers);
|
||||
|
@ -101,6 +101,8 @@ static int server_clist_refresh_row (struct server *s, int row) {
|
||||
assemble_server_address (buf1, 256, s);
|
||||
text[1] = buf1;
|
||||
|
||||
debug (7, "server_clist_refresh_row() -- Row %d", row);
|
||||
|
||||
if (s->ping >= 0) {
|
||||
g_snprintf (buf2, 32, "%d", (s->ping > MAX_PING)? MAX_PING : s->ping);
|
||||
text[2] = buf2;
|
||||
@ -326,10 +328,12 @@ void player_clist_redraw (void) {
|
||||
void server_clist_sync_selection (void) {
|
||||
GList *selection;
|
||||
|
||||
debug (7, "server_clist_sync_selection() --");
|
||||
if (!sync_selection_blocked) {
|
||||
selection = server_clist->selection;
|
||||
|
||||
if (cur_server) {
|
||||
debug (7, "server_clist_sync_selection() -- unref server %lx", cur_server);
|
||||
server_unref (cur_server);
|
||||
cur_server = NULL;
|
||||
}
|
||||
@ -372,9 +376,10 @@ int server_clist_refresh_server (struct server *s) {
|
||||
}
|
||||
else {
|
||||
if ((s->filters & cur_filter) == cur_filter) {
|
||||
debug (6, "server_clist_refresh_server() -- Server %lx needs to be added.");
|
||||
row = server_clist_refresh_row (s, -1);
|
||||
gtk_clist_set_row_data_full (server_clist, row, s,
|
||||
(GtkDestroyNotify) server_unref);
|
||||
(GtkDestroyNotify) server_unref);
|
||||
server_ref (s);
|
||||
return TRUE;
|
||||
}
|
||||
@ -385,6 +390,9 @@ int server_clist_refresh_server (struct server *s) {
|
||||
|
||||
|
||||
void server_clist_select_one (int row) {
|
||||
|
||||
debug (7, "server_clist_select_one() -- Row %d", row);
|
||||
|
||||
sync_selection_blocked = TRUE;
|
||||
gtk_clist_unselect_all (server_clist);
|
||||
sync_selection_blocked = FALSE;
|
||||
@ -435,6 +443,8 @@ void server_clist_selection_visible (void) {
|
||||
GtkVisibility vis;
|
||||
int min;
|
||||
|
||||
debug (7, "server_clist_selection_visible() -- ");
|
||||
|
||||
if (!rows)
|
||||
return;
|
||||
|
||||
@ -482,6 +492,7 @@ void server_clist_redraw (void) {
|
||||
char buf[256];
|
||||
int row;
|
||||
|
||||
debug (7, "server_clist_redraw() --");
|
||||
gtk_clist_freeze (server_clist);
|
||||
|
||||
for (row = 0; row < server_clist->rows; row++) {
|
||||
@ -503,6 +514,8 @@ void server_clist_set_list (GSList *servers) {
|
||||
int row;
|
||||
GSList *filtered;
|
||||
|
||||
debug (7, "server_clist_set_list() -- list %lx", servers);
|
||||
|
||||
filtered = build_filtered_list (cur_filter, servers);
|
||||
|
||||
gtk_clist_freeze (server_clist);
|
||||
@ -516,12 +529,13 @@ void server_clist_set_list (GSList *servers) {
|
||||
gtk_clist_set_row_data_full (server_clist, row, server,
|
||||
(GtkDestroyNotify) server_unref);
|
||||
/*
|
||||
Because the build_filtered_list add a reference count
|
||||
to the server structure and because we are going
|
||||
to free that list, we DO NOT need to add a reference
|
||||
count to the server structure.
|
||||
Because the a destroy event on the server_clist will
|
||||
call server_unref, we want to add a reference to
|
||||
count to the server. Note if we comment out both
|
||||
the ref line and the list_free line we have a net sum
|
||||
of zero. But just for clarity...
|
||||
*/
|
||||
/* server_ref (server); */
|
||||
server_ref (server);
|
||||
}
|
||||
|
||||
server_list_free (filtered);
|
||||
@ -534,6 +548,7 @@ void server_clist_set_list (GSList *servers) {
|
||||
pixmap_cache_clear (&server_pixmap_cache, 8);
|
||||
|
||||
server_clist_sync_selection ();
|
||||
debug (7, "server_clist_set_list() -- Done.");
|
||||
}
|
||||
|
||||
|
||||
@ -565,14 +580,17 @@ void server_clist_build_filtered (GSList *server_list, int update) {
|
||||
server = (struct server *) tmp->data;
|
||||
row = gtk_clist_find_row_from_data (server_clist, server);
|
||||
if (row >= 0) {
|
||||
debug (3, "server_clist_build_filtered() -- Delete server %lx, call gtk_clist_remove()", server);
|
||||
|
||||
/*
|
||||
Note: Each server clist item gets a server_unref call on
|
||||
a GtkDestroyNotify event.
|
||||
*/
|
||||
gtk_clist_remove (server_clist, row);
|
||||
debug (3, "server_clist_build_filtered() -- Delete server %lx", server);
|
||||
}
|
||||
/*
|
||||
Allways unref the server because the list returned
|
||||
to us had the count incremented by prepend.
|
||||
*/
|
||||
}
|
||||
/* Free the list of severs in this loop. */
|
||||
debug (7, "server_clist_build_filtered() -- Call server_list_free on [delete] list %lx", delete);
|
||||
server_list_free (delete);
|
||||
}
|
||||
|
||||
@ -596,9 +614,11 @@ void server_clist_build_filtered (GSList *server_list, int update) {
|
||||
for (tmp = add; tmp; tmp = tmp->next) {
|
||||
server = (struct server *) tmp->data;
|
||||
row = server_clist_refresh_row (server, -1);
|
||||
debug (7, "server_clist_build_filtered() -- add server %lx to row %d", server, row);
|
||||
gtk_clist_set_row_data_full (server_clist, row, server,
|
||||
(GtkDestroyNotify) server_unref);
|
||||
/*server_ref (server);*/
|
||||
|
||||
server_ref (server); /* See nots above about GtkDestroyNotify */
|
||||
}
|
||||
server_list_free (add);
|
||||
}
|
||||
|
@ -448,10 +448,10 @@ static void parse_qstat_record (struct stat_conn *conn) {
|
||||
count as does the prepend below. So we need to decrement it
|
||||
one just for fun.
|
||||
*/
|
||||
server_unref (server);
|
||||
job->delayed.queued_servers =
|
||||
server_list_prepend (job->delayed.queued_servers, server);
|
||||
job->progress.done++;
|
||||
server_unref (server);
|
||||
|
||||
debug (6, "parse_qstat_record() -- Server %lx in delayed list %lx.", server, job->delayed.queued_servers);
|
||||
|
||||
|
@ -165,7 +165,7 @@ static void collect_statistics (void) {
|
||||
enum OS os;
|
||||
enum CPU cpu;
|
||||
|
||||
servers = all_servers ();
|
||||
servers = all_servers (); /* Free at end of this function */
|
||||
|
||||
if (servers) {
|
||||
for (tmp = servers; tmp; tmp = tmp->next) {
|
||||
|
@ -409,7 +409,9 @@ static void start_filters_cfg_dialog (GtkWidget *widget, int page_num) {
|
||||
static void update_server_lists_from_selected_source (void) {
|
||||
GSList *cur_masters = NULL;
|
||||
|
||||
debug (6, "update_server_lists_from_selected_source() --");
|
||||
if (cur_server_list) {
|
||||
debug (6, "update_server_lists_from_selected_source() -- Free cur_server_list %lx", cur_server_list);
|
||||
server_list_free (cur_server_list);
|
||||
cur_server_list = NULL;
|
||||
}
|
||||
@ -429,7 +431,7 @@ static int stat_lists_refresh (struct stat_job *job) {
|
||||
int items;
|
||||
int freeze;
|
||||
|
||||
debug (6, "sta_lists_refresh() -- Job %lx", job);
|
||||
debug (6, "stat_lists_refresh() -- Job %lx", job);
|
||||
items = g_slist_length (job->delayed.queued_servers) +
|
||||
g_slist_length (job->delayed.queued_hosts);
|
||||
if (items) {
|
||||
@ -835,6 +837,7 @@ static int server_clist_compare_func (GtkCList *clist,
|
||||
GtkCListRow *row2 = (GtkCListRow *) ptr2;
|
||||
struct server *s1 = (struct server *) row1->data;
|
||||
struct server *s2 = (struct server *) row2->data;
|
||||
debug (7, "server_clist_compare_func() --");
|
||||
|
||||
return compare_servers (s1, s2, clist->sort_column);
|
||||
}
|
||||
@ -867,6 +870,7 @@ static void update_source_callback (GtkWidget *widget, gpointer data) {
|
||||
GSList *servers = NULL;
|
||||
GSList *uservers = NULL;
|
||||
|
||||
debug (6, "update_source_callback() -- ");
|
||||
if (stat_process || !cur_source)
|
||||
return;
|
||||
|
||||
@ -925,6 +929,7 @@ static void add_to_favorites_callback (GtkWidget *widget, gpointer data) {
|
||||
char buf[256]; /* if you change this, change the statement below */
|
||||
int server_list_size;
|
||||
|
||||
debug (7, "add_to_favorites_callback() -- ");
|
||||
if (stat_process || !selected)
|
||||
return;
|
||||
|
||||
@ -953,6 +958,7 @@ static void add_to_favorites_callback (GtkWidget *widget, gpointer data) {
|
||||
print_status (main_status_bar, buf );
|
||||
|
||||
}
|
||||
debug (7, "add_to_favorites_callback() -- Saving To Favorites");
|
||||
save_favorites ();
|
||||
server_list_free (list);
|
||||
}
|
||||
@ -962,6 +968,7 @@ static void add_to_favorites_callback (GtkWidget *widget, gpointer data) {
|
||||
static void add_server_real (struct stat_job *job, struct server *s) {
|
||||
int row;
|
||||
|
||||
debug (6, "add_server_real() -- Server %lx", s);
|
||||
favorites->servers = server_list_append (favorites->servers, s);
|
||||
save_favorites ();
|
||||
|
||||
@ -1060,6 +1067,7 @@ static void del_server_callback (GtkWidget *widget, gpointer data) {
|
||||
GSList *list;
|
||||
GSList *tmp;
|
||||
|
||||
debug (7, "del_server_callback() -- ");
|
||||
if (stat_process || !cur_source ||
|
||||
(struct master *) cur_source->data != favorites) {
|
||||
return;
|
||||
@ -1282,6 +1290,7 @@ static void resolve_callback (GtkWidget *widget, gpointer data) {
|
||||
GSList *hosts;
|
||||
struct server *s;
|
||||
|
||||
debug (7, "resolve_callback() --");
|
||||
if (stat_process)
|
||||
return;
|
||||
|
||||
@ -1361,7 +1370,7 @@ static void rcon_callback (GtkWidget *widget, gpointer data) {
|
||||
static void server_clist_select_callback (GtkWidget *widget, int row,
|
||||
int column, GdkEvent *event, GtkWidget *button) {
|
||||
GdkEventButton *bevent = (GdkEventButton *) event;
|
||||
|
||||
debug (7, "server_clist_select_callback() -- Row %d", row);
|
||||
server_clist_sync_selection ();
|
||||
|
||||
if (bevent && bevent->type == GDK_2BUTTON_PRESS && bevent->button == 1)
|
||||
@ -1371,6 +1380,7 @@ static void server_clist_select_callback (GtkWidget *widget, int row,
|
||||
|
||||
static void server_clist_unselect_callback (GtkWidget *widget, int row,
|
||||
int column, GdkEvent *event, GtkWidget *button) {
|
||||
debug (7, "server_clist_uselect_callback() -- Row %d", row);
|
||||
server_clist_sync_selection ();
|
||||
}
|
||||
|
||||
@ -1400,6 +1410,7 @@ static int server_clist_event_callback (GtkWidget *widget, GdkEvent *event) {
|
||||
GList *selection;
|
||||
int row;
|
||||
|
||||
/* debug (7, "server_clist_event_callback() -- "); */
|
||||
if (event->type == GDK_BUTTON_PRESS &&
|
||||
bevent->window == server_clist->clist_window) {
|
||||
|
||||
@ -1440,6 +1451,7 @@ static void source_selection_changed (void) {
|
||||
GtkCTreeNode *node;
|
||||
struct master *m;
|
||||
|
||||
debug (6, "souce_selection_changed() --");
|
||||
if (cur_source) {
|
||||
g_slist_free (cur_source);
|
||||
cur_source = NULL;
|
||||
@ -2532,11 +2544,13 @@ int main (int argc, char *argv[]) {
|
||||
stop_callback (NULL, NULL);
|
||||
|
||||
if (server_menu) {
|
||||
debug( 6, "EXIT: destroy server_menu");
|
||||
gtk_widget_destroy (server_menu);
|
||||
server_menu = NULL;
|
||||
}
|
||||
|
||||
if (player_menu) {
|
||||
debug( 6, "EXIT: destroy player_menu");
|
||||
gtk_widget_destroy (player_menu);
|
||||
player_menu = NULL;
|
||||
}
|
||||
@ -2553,6 +2567,7 @@ int main (int argc, char *argv[]) {
|
||||
filters_done ();
|
||||
props_free_all ();
|
||||
|
||||
debug( 6, "EXIT: Free Server Lists");
|
||||
g_slist_free (cur_source);
|
||||
server_list_free (cur_server_list);
|
||||
userver_list_free (cur_userver_list);
|
||||
@ -2565,7 +2580,10 @@ int main (int argc, char *argv[]) {
|
||||
host_cache_save ();
|
||||
host_cache_clear ();
|
||||
|
||||
debug( 6, "EXIT: Free Master Lists");
|
||||
free_masters ();
|
||||
|
||||
debug( 6, "EXIT: Call rcon_done.");
|
||||
rcon_done ();
|
||||
psearch_done ();
|
||||
add_server_done ();
|
||||
@ -2578,7 +2596,7 @@ int main (int argc, char *argv[]) {
|
||||
fprintf (stderr, "total uservers: %d\n", uservers_total ());
|
||||
fprintf (stderr, "total hosts: %d\n", hosts_total ());
|
||||
if (servers_total () > 0) {
|
||||
GSList *list = all_servers ();
|
||||
GSList *list = all_servers (); /* Debug code, free done in two lines */
|
||||
|
||||
server_list_fprintf (stderr, list);
|
||||
server_list_free (list);
|
||||
@ -2589,6 +2607,7 @@ int main (int argc, char *argv[]) {
|
||||
|
||||
config_sync ();
|
||||
config_drop_all ();
|
||||
debug( 6, "EXIT: Done.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user