gaim_proxy_connect() returns a pointer to a GaimProxyConnectData.  The
alternative is to keep a reference to that struct (probably in gc), and cancel
the connection using gaim_proxy_connect_cancel() if the account is destroyed
before the connection attempt finishes.

Hmm, my solution would be to add a pointer to gc to the GaimProxyConnectData struct, initializing it appropriately in gaim_proxy_connect(). Then we could check in gaim_proxy_connect_data_connected() to ensure it hasn't been freed before calling the callback. Something like:

static void
gaim_proxy_connect_data_connected(GaimProxyConnectData *connect_data)
{
-        connect_data->connect_cb(connect_data->data, connect_data->fd, NULL);
+       if (g_list_find(gaim_connections_get_all(), connect_data->gc))
+              connect_data->connect_cb(connect_data->data, connect_data->fd, NULL);
+       else
+            g_free(connect_data->data)

        connect_data->fd = -1;

        gaim_proxy_connect_data_disconnect(connect_data, NULL);
        gaim_proxy_connect_data_destroy(connect_data);
}

We could do the same check in the callback for each asynchronous call to prevent some unnecessary function calls if the account was disabled early in the connection process, but that seems a bit excessive.

It seems that this would also solve Evan's upload_buddy_icon() issue.