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:
Bill Adams 2001-01-15 06:17:50 +00:00 committed by evilbill
parent 3bfcfa9d03
commit 82fe0199e3
8 changed files with 98 additions and 21 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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) {

View File

@ -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;
}