[dovecot-cvs] dovecot/src/login-common master.c,1.20,1.21
tss at dovecot.org
tss at dovecot.org
Sun Nov 12 12:41:37 UTC 2006
Update of /var/lib/cvs/dovecot/src/login-common
In directory talvi:/tmp/cvs-serv14605/login-common
Modified Files:
master.c
Log Message:
Fixed potential problems with client disconnecting while master was handling
the login.
Index: master.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/login-common/master.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- master.c 11 Oct 2006 12:17:27 -0000 1.20
+++ master.c 12 Nov 2006 12:41:34 -0000 1.21
@@ -20,11 +20,22 @@
static unsigned int master_pos;
static char master_buf[sizeof(struct master_login_reply)];
+static struct client destroyed_client;
+
+static void client_call_master_callback(struct client *client, bool success)
+{
+ master_callback_t *master_callback;
+
+ master_callback = client->master_callback;
+ client->master_tag = 0;
+ client->master_callback = NULL;
+
+ master_callback(client, success);
+}
static void request_handle(struct master_login_reply *reply)
{
struct client *client;
- master_callback_t *master_callback;
if (reply->tag == 0 && !process_per_connection) {
/* this means we have to start listening again.
@@ -37,13 +48,11 @@
if (client == NULL)
i_fatal("Master sent reply with unknown tag %u", reply->tag);
- master_callback = client->master_callback;
- client->master_tag = 0;
- client->master_callback = NULL;
-
- master_callback(client, reply->success);
hash_remove(master_requests, POINTER_CAST(reply->tag));
- /* NOTE: client may be destroyed now */
+ if (client != &destroyed_client) {
+ client_call_master_callback(client, reply->success);
+ /* NOTE: client may be destroyed now */
+ }
}
void master_request_login(struct client *client, master_callback_t *callback,
@@ -79,10 +88,12 @@
void master_request_abort(struct client *client)
{
- hash_remove(master_requests, POINTER_CAST(client->master_tag));
+ /* we're still going to get the reply from the master, so just
+ remember that we want to ignore it */
+ hash_update(master_requests, POINTER_CAST(client->master_tag),
+ &destroyed_client);
- client->master_tag = 0;
- client->master_callback = NULL;
+ client_call_master_callback(client, FALSE);
}
void master_notify_state_change(enum master_login_state state)
More information about the dovecot-cvs
mailing list