Mercurial > dovecot > original-hg > dovecot-1.2
comparison src/pop3-login/client.c @ 7101:09556a64b4e5 HEAD
Use a linked list to keep track of all clients instead of a hash table.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 04 Jan 2008 00:01:02 +0200 |
parents | 4c6364f99ff0 |
children | 75f4e7ce8151 |
comparison
equal
deleted
inserted
replaced
7100:4c6364f99ff0 | 7101:09556a64b4e5 |
---|---|
41 # error client idle timeout must be smaller than authentication timeout | 41 # error client idle timeout must be smaller than authentication timeout |
42 #endif | 42 #endif |
43 | 43 |
44 const char *login_protocol = "POP3"; | 44 const char *login_protocol = "POP3"; |
45 | 45 |
46 static struct hash_table *clients; | |
47 | |
48 static void client_set_title(struct pop3_client *client) | 46 static void client_set_title(struct pop3_client *client) |
49 { | 47 { |
50 const char *addr; | 48 const char *addr; |
51 | 49 |
52 if (!verbose_proctitle || !process_per_connection) | 50 if (!verbose_proctitle || !process_per_connection) |
233 o_stream_uncork(client->output); | 231 o_stream_uncork(client->output); |
234 } | 232 } |
235 | 233 |
236 void client_destroy_oldest(void) | 234 void client_destroy_oldest(void) |
237 { | 235 { |
238 struct hash_iterate_context *iter; | 236 struct client *client; |
239 void *key, *value; | |
240 struct pop3_client *destroy_buf[CLIENT_DESTROY_OLDEST_COUNT]; | 237 struct pop3_client *destroy_buf[CLIENT_DESTROY_OLDEST_COUNT]; |
241 unsigned int i, destroy_count; | 238 unsigned int i, destroy_count; |
242 | 239 |
243 /* find the oldest clients and put them to destroy-buffer */ | 240 /* find the oldest clients and put them to destroy-buffer */ |
244 memset(destroy_buf, 0, sizeof(destroy_buf)); | 241 memset(destroy_buf, 0, sizeof(destroy_buf)); |
245 | 242 |
246 destroy_count = max_connections > CLIENT_DESTROY_OLDEST_COUNT*2 ? | 243 destroy_count = max_connections > CLIENT_DESTROY_OLDEST_COUNT*2 ? |
247 CLIENT_DESTROY_OLDEST_COUNT : I_MIN(max_connections/2, 1); | 244 CLIENT_DESTROY_OLDEST_COUNT : I_MIN(max_connections/2, 1); |
248 iter = hash_iterate_init(clients); | 245 for (client = clients; client != NULL; client = client->next) { |
249 while (hash_iterate(iter, &key, &value)) { | 246 struct pop3_client *pop3_client = (struct pop3_client *)client; |
250 struct pop3_client *client = key; | |
251 | 247 |
252 for (i = 0; i < destroy_count; i++) { | 248 for (i = 0; i < destroy_count; i++) { |
253 if (destroy_buf[i] == NULL || | 249 if (destroy_buf[i] == NULL || |
254 destroy_buf[i]->created > client->created) { | 250 destroy_buf[i]->created > pop3_client->created) { |
255 /* @UNSAFE */ | 251 /* @UNSAFE */ |
256 memmove(destroy_buf+i+1, destroy_buf+i, | 252 memmove(destroy_buf+i+1, destroy_buf+i, |
257 sizeof(destroy_buf) - | 253 sizeof(destroy_buf) - |
258 (i+1) * sizeof(struct pop3_client *)); | 254 (i+1) * sizeof(struct pop3_client *)); |
259 destroy_buf[i] = client; | 255 destroy_buf[i] = pop3_client; |
260 break; | 256 break; |
261 } | 257 } |
262 } | 258 } |
263 } | 259 } |
264 hash_iterate_deinit(&iter); | |
265 | 260 |
266 /* then kill them */ | 261 /* then kill them */ |
267 for (i = 0; i < destroy_count; i++) { | 262 for (i = 0; i < destroy_count; i++) { |
268 if (destroy_buf[i] == NULL) | 263 if (destroy_buf[i] == NULL) |
269 break; | 264 break; |
330 | 325 |
331 client->common.local_ip = *local_ip; | 326 client->common.local_ip = *local_ip; |
332 client->common.ip = *ip; | 327 client->common.ip = *ip; |
333 client->common.fd = fd; | 328 client->common.fd = fd; |
334 client_open_streams(client, fd); | 329 client_open_streams(client, fd); |
335 | 330 client_link(&client->common); |
336 hash_insert(clients, client, client); | |
337 | 331 |
338 main_ref(); | 332 main_ref(); |
339 | 333 |
340 client->auth_connected = auth_client_is_connected(auth_client); | 334 client->auth_connected = auth_client_is_connected(auth_client); |
341 if (client->auth_connected) | 335 if (client->auth_connected) |
355 client->destroyed = TRUE; | 349 client->destroyed = TRUE; |
356 | 350 |
357 if (reason != NULL) | 351 if (reason != NULL) |
358 client_syslog(&client->common, reason); | 352 client_syslog(&client->common, reason); |
359 | 353 |
360 hash_remove(clients, client); | 354 client_unlink(&client->common); |
361 | 355 |
362 if (client->input != NULL) | 356 if (client->input != NULL) |
363 i_stream_close(client->input); | 357 i_stream_close(client->input); |
364 if (client->output != NULL) | 358 if (client->output != NULL) |
365 o_stream_close(client->output); | 359 o_stream_close(client->output); |
461 without being referenced.. */ | 455 without being referenced.. */ |
462 i_stream_close(client->input); | 456 i_stream_close(client->input); |
463 } | 457 } |
464 } | 458 } |
465 | 459 |
466 unsigned int clients_get_count(void) | |
467 { | |
468 return hash_count(clients); | |
469 } | |
470 | |
471 void clients_notify_auth_connected(void) | 460 void clients_notify_auth_connected(void) |
472 { | 461 { |
473 struct hash_iterate_context *iter; | 462 struct client *client; |
474 void *key, *value; | 463 |
475 | 464 for (client = clients; client != NULL; client = client->next) { |
476 iter = hash_iterate_init(clients); | 465 struct pop3_client *pop3_client = (struct pop3_client *)client; |
477 while (hash_iterate(iter, &key, &value)) { | 466 |
478 struct pop3_client *client = key; | 467 if (!pop3_client->auth_connected) { |
479 | 468 pop3_client->auth_connected = TRUE; |
480 if (!client->auth_connected) { | 469 client_auth_ready(pop3_client); |
481 client->auth_connected = TRUE; | |
482 client_auth_ready(client); | |
483 } | 470 } |
484 } | 471 } |
485 hash_iterate_deinit(&iter); | |
486 } | 472 } |
487 | 473 |
488 void clients_destroy_all(void) | 474 void clients_destroy_all(void) |
489 { | 475 { |
490 struct hash_iterate_context *iter; | 476 struct client *client; |
491 void *key, *value; | 477 |
492 | 478 for (client = clients; client != NULL; client = client->next) { |
493 iter = hash_iterate_init(clients); | 479 struct pop3_client *pop3_client = (struct pop3_client *)client; |
494 while (hash_iterate(iter, &key, &value)) { | 480 |
495 struct pop3_client *client = key; | 481 client_destroy(pop3_client, "Disconnected: Shutting down"); |
496 | 482 } |
497 client_destroy(client, "Disconnected: Shutting down"); | 483 } |
498 } | |
499 hash_iterate_deinit(&iter); | |
500 } | |
501 | |
502 void clients_init(void) | |
503 { | |
504 clients = hash_create(system_pool, system_pool, 128, NULL, NULL); | |
505 } | |
506 | |
507 void clients_deinit(void) | |
508 { | |
509 clients_destroy_all(); | |
510 hash_destroy(&clients); | |
511 } |