1
0
mirror of https://github.com/irssi/irssi.git synced 2024-12-04 14:46:39 -05:00

Added reference counter to SERVER_CONNECT_REC. Since it's being moved around

a lot in reconnects etc. this should make it easier to track when it's
supposed to be destroyed. Hopefully fixes a crash I assume is related to
this but couldn't find..


git-svn-id: http://svn.irssi.org/repos/irssi/trunk@1880 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
Timo Sirainen 2001-10-21 13:59:07 +00:00 committed by cras
parent ae1b5b0d50
commit 1256621041
10 changed files with 79 additions and 38 deletions

View File

@ -73,7 +73,7 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr)
if (proto->not_initialized) { if (proto->not_initialized) {
/* trying to use protocol that isn't yet initialized */ /* trying to use protocol that isn't yet initialized */
signal_emit("chat protocol unknown", 1, proto->name); signal_emit("chat protocol unknown", 1, proto->name);
server_connect_free(conn); server_connect_unref(conn);
cmd_params_free(free_arg); cmd_params_free(free_arg);
return NULL; return NULL;
} }
@ -102,8 +102,10 @@ static void cmd_connect(const char *data)
SERVER_CONNECT_REC *conn; SERVER_CONNECT_REC *conn;
conn = get_server_connect(data, NULL); conn = get_server_connect(data, NULL);
if (conn != NULL) if (conn != NULL) {
CHAT_PROTOCOL(conn)->server_connect(conn); CHAT_PROTOCOL(conn)->server_connect(conn);
server_connect_unref(conn);
}
} }
static RECONNECT_REC *find_reconnect_server(int chat_type, static RECONNECT_REC *find_reconnect_server(int chat_type,
@ -147,6 +149,7 @@ static void update_reconnection(SERVER_CONNECT_REC *conn, SERVER_REC *server)
if (server != NULL) { if (server != NULL) {
oldconn = server->connrec; oldconn = server->connrec;
server_connect_ref(oldconn);
reconnect_save_status(conn, server); reconnect_save_status(conn, server);
} else { } else {
/* maybe we can reconnect some server from /* maybe we can reconnect some server from
@ -156,7 +159,8 @@ static void update_reconnection(SERVER_CONNECT_REC *conn, SERVER_REC *server)
if (recon == NULL) return; if (recon == NULL) return;
oldconn = recon->conn; oldconn = recon->conn;
server_reconnect_destroy(recon, FALSE); server_connect_ref(oldconn);
server_reconnect_destroy(recon);
conn->away_reason = g_strdup(oldconn->away_reason); conn->away_reason = g_strdup(oldconn->away_reason);
conn->channels = g_strdup(oldconn->channels); conn->channels = g_strdup(oldconn->channels);
@ -167,11 +171,10 @@ static void update_reconnection(SERVER_CONNECT_REC *conn, SERVER_REC *server)
if (conn->chatnet == NULL && oldconn->chatnet != NULL) if (conn->chatnet == NULL && oldconn->chatnet != NULL)
conn->chatnet = g_strdup(oldconn->chatnet); conn->chatnet = g_strdup(oldconn->chatnet);
server_connect_unref(oldconn);
if (server != NULL) { if (server != NULL) {
signal_emit("command disconnect", 2, signal_emit("command disconnect", 2,
"* Changing server", server); "* Changing server", server);
} else {
server_connect_free(oldconn);
} }
} }
@ -201,6 +204,7 @@ static void cmd_server_connect(const char *data, SERVER_REC *server)
if (!plus_addr) if (!plus_addr)
update_reconnection(conn, server); update_reconnection(conn, server);
CHAT_PROTOCOL(conn)->server_connect(conn); CHAT_PROTOCOL(conn)->server_connect(conn);
server_connect_unref(conn);
} }
} }

View File

@ -15,6 +15,7 @@ typedef struct {
SERVER_SETUP_REC *(*create_server_setup) (void); SERVER_SETUP_REC *(*create_server_setup) (void);
CHANNEL_SETUP_REC *(*create_channel_setup) (void); CHANNEL_SETUP_REC *(*create_channel_setup) (void);
SERVER_CONNECT_REC *(*create_server_connect) (void); SERVER_CONNECT_REC *(*create_server_connect) (void);
void (*destroy_server_connect) (SERVER_CONNECT_REC *);
SERVER_REC *(*server_connect) (SERVER_CONNECT_REC *); SERVER_REC *(*server_connect) (SERVER_CONNECT_REC *);
CHANNEL_REC *(*channel_create) (SERVER_REC *, const char *, int); CHANNEL_REC *(*channel_create) (SERVER_REC *, const char *, int);

View File

@ -3,6 +3,8 @@
int type; /* module_get_uniq_id("SERVER CONNECT", 0) */ int type; /* module_get_uniq_id("SERVER CONNECT", 0) */
int chat_type; /* chat_protocol_lookup(xx) */ int chat_type; /* chat_protocol_lookup(xx) */
int refcount;
/* if we're connecting via proxy, or just NULLs */ /* if we're connecting via proxy, or just NULLs */
char *proxy; char *proxy;
int proxy_port; int proxy_port;

View File

@ -56,20 +56,22 @@ static void server_reconnect_add(SERVER_CONNECT_REC *conn,
rec = g_new(RECONNECT_REC, 1); rec = g_new(RECONNECT_REC, 1);
rec->tag = ++last_reconnect_tag; rec->tag = ++last_reconnect_tag;
rec->conn = conn;
rec->next_connect = next_connect; rec->next_connect = next_connect;
rec->conn = conn;
server_connect_ref(conn);
reconnects = g_slist_append(reconnects, rec); reconnects = g_slist_append(reconnects, rec);
} }
void server_reconnect_destroy(RECONNECT_REC *rec, int free_conn) void server_reconnect_destroy(RECONNECT_REC *rec)
{ {
g_return_if_fail(rec != NULL); g_return_if_fail(rec != NULL);
reconnects = g_slist_remove(reconnects, rec); reconnects = g_slist_remove(reconnects, rec);
signal_emit("server reconnect remove", 1, rec); signal_emit("server reconnect remove", 1, rec);
if (free_conn) server_connect_free(rec->conn); server_connect_unref(rec->conn);
g_free(rec); g_free(rec);
if (reconnects == NULL) if (reconnects == NULL)
@ -95,8 +97,10 @@ static int server_reconnect_timeout(void)
if (rec->next_connect <= now) { if (rec->next_connect <= now) {
conn = rec->conn; conn = rec->conn;
server_reconnect_destroy(rec, FALSE); server_connect_ref(conn);
server_reconnect_destroy(rec);
CHAT_PROTOCOL(conn)->server_connect(conn); CHAT_PROTOCOL(conn)->server_connect(conn);
server_connect_unref(conn);
} }
} }
@ -118,6 +122,7 @@ static void sserver_connect(SERVER_SETUP_REC *rec, SERVER_CONNECT_REC *conn)
/* connect to server.. */ /* connect to server.. */
CHAT_PROTOCOL(conn)->server_connect(conn); CHAT_PROTOCOL(conn)->server_connect(conn);
} }
server_connect_unref(conn);
} }
static SERVER_CONNECT_REC * static SERVER_CONNECT_REC *
@ -129,6 +134,7 @@ server_connect_copy_skeleton(SERVER_CONNECT_REC *src, int connect_info)
signal_emit("server connect copy", 2, &dest, src); signal_emit("server connect copy", 2, &dest, src);
g_return_val_if_fail(dest != NULL, NULL); g_return_val_if_fail(dest != NULL, NULL);
server_connect_ref(dest);
dest->type = module_get_uniq_id("SERVER CONNECT", 0); dest->type = module_get_uniq_id("SERVER CONNECT", 0);
dest->reconnection = src->reconnection; dest->reconnection = src->reconnection;
dest->proxy = g_strdup(src->proxy); dest->proxy = g_strdup(src->proxy);
@ -226,6 +232,7 @@ static void sig_reconnect(SERVER_REC *server)
server_reconnect_add(conn, (server->connect_time == 0 ? time(NULL) : server_reconnect_add(conn, (server->connect_time == 0 ? time(NULL) :
server->connect_time) + reconnect_time); server->connect_time) + reconnect_time);
} }
server_connect_unref(conn);
return; return;
} }
@ -270,7 +277,7 @@ static void sig_reconnect(SERVER_REC *server)
if (through) { if (through) {
/* shouldn't happen unless there's no servers in /* shouldn't happen unless there's no servers in
this chatnet in setup.. */ this chatnet in setup.. */
server_connect_free(conn); server_connect_unref(conn);
break; break;
} }
@ -294,7 +301,7 @@ static void sig_connected(SERVER_REC *server)
static void cmd_rmreconns(void) static void cmd_rmreconns(void)
{ {
while (reconnects != NULL) while (reconnects != NULL)
server_reconnect_destroy(reconnects->data, TRUE); server_reconnect_destroy(reconnects->data);
} }
static RECONNECT_REC *reconnect_find_tag(int tag) static RECONNECT_REC *reconnect_find_tag(int tag)
@ -325,7 +332,8 @@ static void reconnect_all(void)
rec = reconnects->data; rec = reconnects->data;
list = g_slist_append(list, rec->conn); list = g_slist_append(list, rec->conn);
server_reconnect_destroy(rec, FALSE); server_connect_unref(rec->conn);
server_reconnect_destroy(rec);
} }
@ -333,6 +341,7 @@ static void reconnect_all(void)
conn = list->data; conn = list->data;
CHAT_PROTOCOL(conn)->server_connect(conn); CHAT_PROTOCOL(conn)->server_connect(conn);
server_connect_unref(conn);
list = g_slist_remove(list, conn); list = g_slist_remove(list, conn);
} }
} }
@ -356,6 +365,7 @@ static void cmd_reconnect(const char *data, SERVER_REC *server)
conn->reconnection = TRUE; conn->reconnection = TRUE;
CHAT_PROTOCOL(conn)->server_connect(conn); CHAT_PROTOCOL(conn)->server_connect(conn);
server_connect_unref(conn);
return; return;
} }
@ -384,8 +394,10 @@ static void cmd_reconnect(const char *data, SERVER_REC *server)
} }
conn = rec->conn; conn = rec->conn;
server_reconnect_destroy(rec, FALSE); server_connect_ref(conn);
server_reconnect_destroy(rec);
CHAT_PROTOCOL(conn)->server_connect(conn); CHAT_PROTOCOL(conn)->server_connect(conn);
server_connect_unref(conn);
} }
static void cmd_disconnect(const char *data, SERVER_REC *server) static void cmd_disconnect(const char *data, SERVER_REC *server)
@ -400,7 +412,7 @@ static void cmd_disconnect(const char *data, SERVER_REC *server)
if (rec == NULL) if (rec == NULL)
signal_emit("server reconnect not found", 1, data); signal_emit("server reconnect not found", 1, data);
else else
server_reconnect_destroy(rec, TRUE); server_reconnect_destroy(rec);
signal_stop(); signal_stop();
} }
@ -413,7 +425,7 @@ static void sig_chat_protocol_deinit(CHAT_PROTOCOL_REC *proto)
next = tmp->next; next = tmp->next;
if (rec->conn->chat_type == proto->id) if (rec->conn->chat_type == proto->id)
server_reconnect_destroy(rec, TRUE); server_reconnect_destroy(rec);
} }
} }

View File

@ -15,7 +15,7 @@ typedef struct {
extern GSList *reconnects; extern GSList *reconnects;
void reconnect_save_status(SERVER_CONNECT_REC *conn, SERVER_REC *server); void reconnect_save_status(SERVER_CONNECT_REC *conn, SERVER_REC *server);
void server_reconnect_destroy(RECONNECT_REC *rec, int free_conn); void server_reconnect_destroy(RECONNECT_REC *rec);
void servers_reconnect_init(void); void servers_reconnect_init(void);
void servers_reconnect_deinit(void); void servers_reconnect_deinit(void);

View File

@ -168,15 +168,15 @@ static void server_setup_fill_chatnet(SERVER_CONNECT_REC *conn,
g_return_if_fail(IS_SERVER_CONNECT(conn)); g_return_if_fail(IS_SERVER_CONNECT(conn));
g_return_if_fail(IS_CHATNET(chatnet)); g_return_if_fail(IS_CHATNET(chatnet));
if (chatnet->nick) { if (chatnet->nick != NULL) {
g_free(conn->nick); g_free(conn->nick);
conn->nick = g_strdup(chatnet->nick);; conn->nick = g_strdup(chatnet->nick);;
} }
if (chatnet->username) { if (chatnet->username != NULL) {
g_free(conn->username); g_free(conn->username);
conn->username = g_strdup(chatnet->username);; conn->username = g_strdup(chatnet->username);;
} }
if (chatnet->realname) { if (chatnet->realname != NULL) {
g_free(conn->realname); g_free(conn->realname);
conn->realname = g_strdup(chatnet->realname);; conn->realname = g_strdup(chatnet->realname);;
} }
@ -212,6 +212,8 @@ create_addr_conn(int chat_type, const char *address, int port,
chat_protocol_get_default(); chat_protocol_get_default();
conn = proto->create_server_connect(); conn = proto->create_server_connect();
server_connect_ref(conn);
conn->chat_type = proto->id; conn->chat_type = proto->id;
if (chatnet != NULL && *chatnet != '\0') if (chatnet != NULL && *chatnet != '\0')
conn->chatnet = g_strdup(chatnet); conn->chatnet = g_strdup(chatnet);

View File

@ -59,7 +59,7 @@ void server_connect_failed(SERVER_REC *server, const char *msg)
} }
MODULE_DATA_DEINIT(server); MODULE_DATA_DEINIT(server);
server_connect_free(server->connrec); server_connect_unref(server->connrec);
g_free_not_null(server->nick); g_free_not_null(server->nick);
g_free(server->tag); g_free(server->tag);
g_free(server); g_free(server);
@ -361,7 +361,7 @@ void server_disconnect(SERVER_REC *server)
g_source_remove(server->readtag); g_source_remove(server->readtag);
MODULE_DATA_DEINIT(server); MODULE_DATA_DEINIT(server);
server_connect_free(server->connrec); server_connect_unref(server->connrec);
rawlog_destroy(server->rawlog); rawlog_destroy(server->rawlog);
line_split_free(server->buffer); line_split_free(server->buffer);
g_free_not_null(server->version); g_free_not_null(server->version);
@ -413,11 +413,24 @@ SERVER_REC *server_find_chatnet(const char *chatnet)
return NULL; return NULL;
} }
void server_connect_free(SERVER_CONNECT_REC *conn) void server_connect_ref(SERVER_CONNECT_REC *conn)
{
conn->refcount++;
}
void server_connect_unref(SERVER_CONNECT_REC *conn)
{ {
g_return_if_fail(IS_SERVER_CONNECT(conn)); g_return_if_fail(IS_SERVER_CONNECT(conn));
signal_emit("server connect free", 1, conn); if (--conn->refcount > 0)
return;
if (conn->refcount < 0) {
g_warning("Connection '%s' refcount = %d",
conn->tag, conn->refcount);
}
CHAT_PROTOCOL(conn)->destroy_server_connect(conn);
g_free_not_null(conn->proxy); g_free_not_null(conn->proxy);
g_free_not_null(conn->proxy_string); g_free_not_null(conn->proxy_string);
g_free_not_null(conn->proxy_password); g_free_not_null(conn->proxy_password);

View File

@ -41,7 +41,8 @@ SERVER_REC *server_find_chatnet(const char *chatnet);
/* starts connecting to server */ /* starts connecting to server */
int server_start_connect(SERVER_REC *server); int server_start_connect(SERVER_REC *server);
void server_connect_free(SERVER_CONNECT_REC *conn); void server_connect_ref(SERVER_CONNECT_REC *conn);
void server_connect_unref(SERVER_CONNECT_REC *conn);
/* initializes server record but doesn't start connecting */ /* initializes server record but doesn't start connecting */
void server_connect_init(SERVER_REC *server); void server_connect_init(SERVER_REC *server);

View File

@ -65,6 +65,18 @@ static SERVER_CONNECT_REC *create_server_connect(void)
return g_malloc0(sizeof(IRC_SERVER_CONNECT_REC)); return g_malloc0(sizeof(IRC_SERVER_CONNECT_REC));
} }
static void destroy_server_connect(SERVER_CONNECT_REC *conn)
{
IRC_SERVER_CONNECT_REC *ircconn;
ircconn = IRC_SERVER_CONNECT(conn);
if (ircconn == NULL)
return;
g_free_not_null(ircconn->usermode);
g_free_not_null(ircconn->alternate_nick);
}
void irc_core_init(void) void irc_core_init(void)
{ {
CHAT_PROTOCOL_REC *rec; CHAT_PROTOCOL_REC *rec;
@ -80,6 +92,7 @@ void irc_core_init(void)
rec->create_server_setup = create_server_setup; rec->create_server_setup = create_server_setup;
rec->create_channel_setup = create_channel_setup; rec->create_channel_setup = create_channel_setup;
rec->create_server_connect = create_server_connect; rec->create_server_connect = create_server_connect;
rec->destroy_server_connect = destroy_server_connect;
rec->server_connect = (SERVER_REC *(*) (SERVER_CONNECT_REC *)) rec->server_connect = (SERVER_REC *(*) (SERVER_CONNECT_REC *))
irc_server_connect; irc_server_connect;

View File

@ -55,15 +55,6 @@ void irc_servers_reconnect_deinit(void);
static int cmd_tag; static int cmd_tag;
static void sig_server_connect_free(IRC_SERVER_CONNECT_REC *conn)
{
if (!IS_IRC_SERVER_CONNECT(conn))
return;
g_free_not_null(conn->usermode);
g_free_not_null(conn->alternate_nick);
}
static int isnickflag_func(char flag) static int isnickflag_func(char flag)
{ {
return isnickflag(flag); return isnickflag(flag);
@ -171,8 +162,12 @@ IRC_SERVER_REC *irc_server_connect(IRC_SERVER_CONNECT_REC *conn)
server = g_new0(IRC_SERVER_REC, 1); server = g_new0(IRC_SERVER_REC, 1);
server->chat_type = IRC_PROTOCOL; server->chat_type = IRC_PROTOCOL;
server->connrec = conn; server->connrec = conn;
if (server->connrec->port <= 0) server->connrec->port = 6667; server_connect_ref(SERVER_CONNECT(conn));
if (server->connrec->port <= 0)
server->connrec->port = 6667;
server->cmd_queue_speed = conn->cmd_queue_speed > 0 ? server->cmd_queue_speed = conn->cmd_queue_speed > 0 ?
conn->cmd_queue_speed : settings_get_int("cmd_queue_speed"); conn->cmd_queue_speed : settings_get_int("cmd_queue_speed");
@ -191,7 +186,7 @@ IRC_SERVER_REC *irc_server_connect(IRC_SERVER_CONNECT_REC *conn)
conn->max_msgs : DEFAULT_MAX_MSGS; conn->max_msgs : DEFAULT_MAX_MSGS;
if (!server_start_connect((SERVER_REC *) server)) { if (!server_start_connect((SERVER_REC *) server)) {
server_connect_free(SERVER_CONNECT(conn)); server_connect_unref(SERVER_CONNECT(conn));
g_free(server); g_free(server);
return NULL; return NULL;
} }
@ -498,7 +493,6 @@ void irc_servers_init(void)
cmd_tag = g_timeout_add(500, (GSourceFunc) servers_cmd_timeout, NULL); cmd_tag = g_timeout_add(500, (GSourceFunc) servers_cmd_timeout, NULL);
signal_add("server connect free", (SIGNAL_FUNC) sig_server_connect_free);
signal_add_first("server looking", (SIGNAL_FUNC) sig_server_looking); signal_add_first("server looking", (SIGNAL_FUNC) sig_server_looking);
signal_add_first("server connected", (SIGNAL_FUNC) sig_connected); signal_add_first("server connected", (SIGNAL_FUNC) sig_connected);
signal_add_last("server disconnected", (SIGNAL_FUNC) sig_disconnected); signal_add_last("server disconnected", (SIGNAL_FUNC) sig_disconnected);
@ -520,7 +514,6 @@ void irc_servers_deinit(void)
{ {
g_source_remove(cmd_tag); g_source_remove(cmd_tag);
signal_remove("server connect free", (SIGNAL_FUNC) sig_server_connect_free);
signal_remove("server looking", (SIGNAL_FUNC) sig_server_looking); signal_remove("server looking", (SIGNAL_FUNC) sig_server_looking);
signal_remove("server connected", (SIGNAL_FUNC) sig_connected); signal_remove("server connected", (SIGNAL_FUNC) sig_connected);
signal_remove("server disconnected", (SIGNAL_FUNC) sig_disconnected); signal_remove("server disconnected", (SIGNAL_FUNC) sig_disconnected);