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 }