New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert more of the netsplit print optimisation to fix crashes #824

Merged
merged 1 commit into from Feb 5, 2018

Conversation

Projects
None yet
2 participants
@dequis
Member

dequis commented Jan 20, 2018

Now iterating over all servers to avoid crashes on server_ischannel(), which is a macro for server->ischannel(), so it dies horribly when it's null.

Fixes #819

@dequis

This comment has been minimized.

Member

dequis commented Jan 20, 2018

Ref #812, #420

@dequis

This comment has been minimized.

Member

dequis commented Jan 22, 2018

Oh. You're right. I'm copying this stuff back to #819 because my mistake was there, not here (after all this PR just copypastes the older working code, a change of the analysis won't change the code here)

@irssi irssi deleted a comment from dequis Jan 22, 2018

rec = IRC_SERVER(dest->server);
if (rec->split_servers != NULL)
print_splits(rec, NULL);
if (IS_IRC_SERVER(dest->server) && rec->split_servers != NULL)

This comment has been minimized.

@ailin-nemui

ailin-nemui Jan 25, 2018

Contributor

the reversion here is incomplete, the original code was checking IS_IRC_SERVER(rec)

Revert more of the netsplit print optimisation to fix crashes
Now iterating over all servers to avoid crashes on server_ischannel(),
which is a macro for server->ischannel(), so it dies horribly when it's
null. Doesn't help that IS_IRC_SERVER() always returns true on null.
@dequis

This comment has been minimized.

Member

dequis commented Jan 29, 2018

Computers are hard.

The diffs look more harmless now:

git diff lemon-netsplit-base HEAD src/fe-common/irc/fe-netsplit.c

diff --git a/src/fe-common/irc/fe-netsplit.c b/src/fe-common/irc/fe-netsplit.c
index 3eb307965..edd3fc34e 100644
--- a/src/fe-common/irc/fe-netsplit.c
+++ b/src/fe-common/irc/fe-netsplit.c
@@ -142,12 +142,14 @@ static void get_server_splits(void *key, NETSPLIT_REC *split,
 	}
 }
 
-static void print_server_splits(IRC_SERVER_REC *server, TEMP_SPLIT_REC *rec)
+static void print_server_splits(IRC_SERVER_REC *server, TEMP_SPLIT_REC *rec, const char *filter_channel)
 {
 	GString *destservers;
 	char *sourceserver;
 	GSList *tmp;
 
+	g_return_if_fail(rec->servers != NULL);
+
 	destservers = g_string_new(NULL);
 	for (tmp = rec->servers; tmp != NULL; tmp = tmp->next) {
 		NETSPLIT_SERVER_REC *rec = tmp->data;
@@ -168,6 +170,10 @@ static void print_server_splits(IRC_SERVER_REC *server, TEMP_SPLIT_REC *rec)
 	for (tmp = rec->channels; tmp != NULL; tmp = tmp->next) {
 		TEMP_SPLIT_CHAN_REC *chan = tmp->data;
 
+		if (filter_channel != NULL &&
+		    strcasecmp(chan->name, filter_channel) != 0)
+			continue;
+
 		g_string_truncate(chan->nicks, chan->nicks->len-2);
 
 		if (netsplit_max_nicks > 0 &&
@@ -193,7 +199,7 @@ static void temp_split_chan_free(TEMP_SPLIT_CHAN_REC *rec)
 	g_free(rec);
 }
 
-static void print_splits(IRC_SERVER_REC *server)
+static void print_splits(IRC_SERVER_REC *server, const char *filter_channel)
 {
 	TEMP_SPLIT_REC temp;
 	GSList *servers;
@@ -212,7 +218,7 @@ static void print_splits(IRC_SERVER_REC *server)
 
 		g_hash_table_foreach(server->splits,
 				     (GHFunc) get_server_splits, &temp);
-		print_server_splits(server, &temp);
+		print_server_splits(server, &temp, filter_channel);
 
 		g_slist_foreach(temp.channels,
 				(GFunc) temp_split_chan_free, NULL);
@@ -233,13 +239,13 @@ static int check_server_splits(IRC_SERVER_REC *server)
 	if (time(NULL)-last < SPLIT_WAIT_TIME)
 		return FALSE;
 
-	print_splits(server);
+	print_splits(server, NULL);
         return TRUE;
 }
 
 /* something is going to be printed to screen, print our current netsplit
    message before it. */
-static void sig_print_starting(void)
+static void sig_print_starting(TEXT_DEST_REC *dest)
 {
 	GSList *tmp;
 
@@ -250,7 +256,7 @@ static void sig_print_starting(void)
 		IRC_SERVER_REC *rec = tmp->data;
 
 		if (IS_IRC_SERVER(rec) && rec->split_servers != NULL)
-			print_splits(rec);
+			print_splits(rec, NULL);
 	}
 }
 

git diff lemon-netsplit-base HEAD src/fe-common/irc/fe-netjoin.c

diff --git a/src/fe-common/irc/fe-netjoin.c b/src/fe-common/irc/fe-netjoin.c
index f5cb081e4..a7a2e4fe4 100644
--- a/src/fe-common/irc/fe-netjoin.c
+++ b/src/fe-common/irc/fe-netjoin.c
@@ -164,11 +164,11 @@ static void print_channel_netjoins(char *channel, TEMP_PRINT_REC *rec,
 	g_free(channel);
 }
 
-static void print_netjoins(NETJOIN_SERVER_REC *server)
+static void print_netjoins(NETJOIN_SERVER_REC *server, const char *filter_channel)
 {
 	TEMP_PRINT_REC *temp;
 	GHashTable *channels;
-	GSList *tmp, *next, *old;
+	GSList *tmp, *tmp2, *next, *next2, *old;
 
 	g_return_if_fail(server != NULL);
 
@@ -181,11 +181,19 @@ static void print_netjoins(NETJOIN_SERVER_REC *server)
 	for (tmp = server->netjoins; tmp != NULL; tmp = next) {
 		NETJOIN_REC *rec = tmp->data;
 
-		next = tmp->next;
-		while (rec->now_channels != NULL) {
-			char *channel = rec->now_channels->data;
+		next = g_slist_next(tmp);
+
+		for (tmp2 = rec->now_channels; tmp2 != NULL; tmp2 = next2) {
+			char *channel = tmp2->data;
 			char *realchannel = channel + 1;
 
+			next2 = g_slist_next(tmp2);
+
+			/* Filter the results by channel if asked to do so */
+			if (filter_channel != NULL &&
+			    strcasecmp(realchannel, filter_channel) != 0)
+				continue;
+
 			temp = g_hash_table_lookup(channels, realchannel);
 			if (temp == NULL) {
 				temp = g_new0(TEMP_PRINT_REC, 1);
@@ -214,8 +222,8 @@ static void print_netjoins(NETJOIN_SERVER_REC *server)
 				g_free(data);
 			}
 
-			rec->now_channels =
-				g_slist_remove(rec->now_channels, channel);
+			/* drop tmp2 from the list */
+			rec->now_channels = g_slist_delete_link(rec->now_channels, tmp2);
 			g_free(channel);
 		}
 
@@ -235,7 +243,7 @@ static void print_netjoins(NETJOIN_SERVER_REC *server)
 
 /* something is going to be printed to screen, print our current netsplit
    message before it. */
-static void sig_print_starting(void)
+static void sig_print_starting(TEXT_DEST_REC *dest)
 {
 	GSList *tmp, *next;
 
@@ -247,7 +255,7 @@ static void sig_print_starting(void)
 
 		next = tmp->next;
 		if (server->netjoins != NULL)
-			print_netjoins(server);
+			print_netjoins(server, NULL);
 	}
 }
 
@@ -272,7 +280,7 @@ static int sig_check_netjoins(void)
 		}
 
                 if (server->netjoins != NULL)
-			print_netjoins(server);
+			print_netjoins(server, NULL);
 	}
 
 	/* now remove all netjoins which haven't had any new joins
@@ -457,6 +465,20 @@ static void read_settings(void)
 	}
 }
 
+static void sig_server_disconnected(IRC_SERVER_REC *server)
+{
+	NETJOIN_SERVER_REC *netjoin_server;
+
+	g_return_if_fail(server != NULL);
+
+	if (!IS_IRC_SERVER(server))
+		return;
+
+	if ((netjoin_server = netjoin_find_server(server))) {
+		netjoin_server_remove(netjoin_server);
+	}
+}
+
 void fe_netjoin_init(void)
 {
 	settings_add_bool("misc", "hide_netsplit_quits", TRUE);
@@ -467,6 +489,7 @@ void fe_netjoin_init(void)
 
 	read_settings();
 	signal_add("setup changed", (SIGNAL_FUNC) read_settings);
+	signal_add("server disconnected", (SIGNAL_FUNC) sig_server_disconnected);
 }
 
 void fe_netjoin_deinit(void)
@@ -479,6 +502,7 @@ void fe_netjoin_deinit(void)
 	}
 
 	signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
+	signal_remove("server disconnected", (SIGNAL_FUNC) sig_server_disconnected);
 
 	signal_remove("message quit", (SIGNAL_FUNC) msg_quit);
 	signal_remove("message join", (SIGNAL_FUNC) msg_join);
@ailin-nemui

This comment has been minimized.

Contributor

ailin-nemui commented Feb 5, 2018

@irssi/developers merge this for 1.1.1?

@ailin-nemui ailin-nemui merged commit cfcc021 into irssi:master Feb 5, 2018

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details

lkundrak pushed a commit to lkundrak/irssi that referenced this pull request Feb 16, 2018

Merge pull request irssi#824 from dequis/more-netsplit-revert
Revert more of the netsplit print optimisation to fix crashes

(cherry picked from commit cfcc021)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment