Changeset 726
- Timestamp:
- 02/27/08 03:37:18 (6 months ago)
- Files:
-
- trunk/server/memcached.c (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/server/memcached.c
r724 r726 65 65 static void drive_machine(conn *c); 66 66 static int new_socket(struct addrinfo *ai); 67 static int *server_socket(const int port, const bool is_udp, int *count);67 static int server_socket(const int port, const bool is_udp); 68 68 static int try_read_command(conn *c); 69 69 static int try_read_network(conn *c); … … 2392 2392 2393 2393 2394 static int *server_socket(const int port, const bool is_udp, int *count) {2394 static int server_socket(const int port, const bool is_udp) { 2395 2395 int sfd; 2396 int *sfd_list;2397 int *sfd_ptr;2398 2396 struct linger ling = {0, 0}; 2399 2397 struct addrinfo *ai; … … 2431 2429 perror("getaddrinfo()"); 2432 2430 2433 return NULL; 2434 } 2435 2436 for (*count= 1, next= ai; next->ai_next; next= next->ai_next, (*count)++); 2437 2438 sfd_list= (int *)calloc(*count, sizeof(int)); 2439 if (sfd_list == NULL) { 2440 fprintf(stderr, "calloc()\n"); 2441 return NULL; 2442 } 2443 memset(sfd_list, -1, sizeof(int) * (*count)); 2444 2445 for (sfd_ptr= sfd_list, next= ai; next; next= next->ai_next, sfd_ptr++) { 2431 return 1; 2432 } 2433 2434 conn *conn_ptr = NULL; 2435 for (next= ai; next; next= next->ai_next) { 2436 conn *listen_conn_add; 2446 2437 if ((sfd = new_socket(next)) == -1) { 2447 free(sfd_list);2448 2438 freeaddrinfo(ai); 2449 return NULL;2439 return 1; 2450 2440 } 2451 2441 … … 2462 2452 if (errno != EADDRINUSE) { 2463 2453 perror("bind()"); 2464 /* If we are not at the first element, loop back and close all sockets */2465 if (sfd_ptr != sfd_list) {2466 do {2467 --sfd_ptr;2468 close(*sfd_ptr);2469 } while (sfd_ptr != sfd_list);2470 }2471 2454 close(sfd); 2472 2455 freeaddrinfo(ai); 2473 free(sfd_list); 2474 return NULL; 2456 return 1; 2475 2457 } 2476 2458 close(sfd); 2477 *sfd_ptr= -1;2478 2459 } else { 2479 2460 success++; 2480 *sfd_ptr= sfd;2481 2461 if (!is_udp && listen(sfd, 1024) == -1) { 2482 2462 perror("listen()"); 2483 if (sfd_ptr != sfd_list) {2484 do {2485 --sfd_ptr;2486 close(*sfd_ptr);2487 } while (sfd_ptr != sfd_list);2488 }2489 2463 close(sfd); 2490 2464 freeaddrinfo(ai); 2491 free(sfd_list); 2492 return NULL; 2465 return 1; 2493 2466 } 2494 2467 } 2468 2469 if (is_udp) 2470 { 2471 int c; 2472 2473 for (c = 0; c < settings.num_threads; c++) { 2474 /* this is guaranteed to hit all threads because we round-robin */ 2475 dispatch_conn_new(sfd, conn_read, EV_READ | EV_PERSIST, 2476 UDP_READ_BUFFER_SIZE, 1); 2477 } 2478 } else { 2479 if (!(listen_conn_add = conn_new(sfd, conn_listening, 2480 EV_READ | EV_PERSIST, 1, false, main_base))) { 2481 fprintf(stderr, "failed to create listening connection\n"); 2482 exit(EXIT_FAILURE); 2483 } 2484 2485 if (listen_conn == NULL) { 2486 conn_ptr = listen_conn = listen_conn_add; 2487 } else { 2488 conn_ptr->next= listen_conn_add; 2489 } 2490 } 2495 2491 } 2496 2492 2497 2493 freeaddrinfo(ai); 2498 2494 2499 if (success == 0) { 2500 free(sfd_list); 2501 return NULL; 2502 } 2503 2504 return sfd_list; 2495 return 0; 2505 2496 } 2506 2497 … … 2523 2514 } 2524 2515 2525 static int *server_socket_unix(const char *path, int access_mask) {2516 static int server_socket_unix(const char *path, int access_mask) { 2526 2517 int sfd; 2527 int *sfd_list;2528 2518 struct linger ling = {0, 0}; 2529 2519 struct sockaddr_un addr; … … 2533 2523 2534 2524 if (!path) { 2535 return NULL;2525 return 1; 2536 2526 } 2537 2527 2538 2528 if ((sfd = new_socket_unix()) == -1) { 2539 return NULL; 2540 } 2541 2542 /* 2543 When UNIX domain sockets get refactored, this will go away. 2544 For now we know there is just one socket. 2545 */ 2546 sfd_list= (int *)calloc(1, sizeof(int)); 2547 if (sfd_list == NULL) { 2548 fprintf(stderr, "calloc()\n"); 2549 return NULL; 2550 } 2551 memset(sfd_list, -1, sizeof(int) * 1); 2529 return 1; 2530 } 2552 2531 2553 2532 /* … … 2575 2554 perror("bind()"); 2576 2555 close(sfd); 2577 free(sfd_list);2578 2556 umask(old_umask); 2579 return NULL;2557 return 1; 2580 2558 } 2581 2559 umask(old_umask); … … 2583 2561 perror("listen()"); 2584 2562 close(sfd); 2585 free(sfd_list); 2586 return NULL; 2587 } 2588 2589 *sfd_list= sfd; 2590 2591 return sfd_list; 2563 return 1; 2564 } 2565 if (!(listen_conn = conn_new(sfd, conn_listening, 2566 EV_READ | EV_PERSIST, 1, false, main_base))) { 2567 fprintf(stderr, "failed to create listening connection\n"); 2568 exit(EXIT_FAILURE); 2569 } 2570 2571 return 0; 2592 2572 } 2593 2573 … … 2870 2850 /* listening socket */ 2871 2851 static int *l_socket = NULL; 2872 static int l_socket_count = 0;2873 2852 2874 2853 /* udp socket */ … … 3029 3008 } 3030 3009 3031 /*3032 * initialization order: first create the listening sockets3033 * (may need root on low ports), then drop root if needed,3034 * then daemonise if needed, then init libevent (in some cases3035 * descriptors created by libevent wouldn't survive forking).3036 */3037 3038 /* create the listening socket and bind it */3039 if (settings.socketpath == NULL) {3040 l_socket = server_socket(settings.port, 0, &l_socket_count);3041 if (l_socket == NULL) {3042 fprintf(stderr, "failed to listen\n");3043 exit(EXIT_FAILURE);3044 }3045 }3046 3047 if (settings.udpport > 0 && settings.socketpath == NULL) {3048 /* create the UDP listening socket and bind it */3049 u_socket = server_socket(settings.udpport, 1, &u_socket_count);3050 if (u_socket == NULL) {3051 fprintf(stderr, "failed to listen on UDP port %d\n", settings.udpport);3052 exit(EXIT_FAILURE);3053 }3054 }3055 3056 3010 /* lock paged memory if needed */ 3057 3011 if (lock_memory) { … … 3081 3035 return 1; 3082 3036 } 3083 }3084 3085 /* create unix mode sockets after dropping privileges */3086 if (settings.socketpath != NULL) {3087 l_socket = server_socket_unix(settings.socketpath,settings.access);3088 if (l_socket == NULL) {3089 fprintf(stderr, "failed to listen\n");3090 exit(EXIT_FAILURE);3091 }3092 /* We only support one of these, so whe know the count */3093 l_socket_count = 1;3094 3037 } 3095 3038 … … 3138 3081 perror("failed to ignore SIGPIPE; sigaction"); 3139 3082 exit(EXIT_FAILURE); 3140 }3141 /* create the initial listening connection */3142 int *l_socket_ptr;3143 conn *next = NULL;3144 for (l_socket_ptr= l_socket, x = 0; x < l_socket_count; l_socket_ptr++, x++) {3145 conn *listen_conn_add;3146 if (*l_socket_ptr > -1 ) {3147 if (!(listen_conn_add = conn_new(*l_socket_ptr, conn_listening,3148 EV_READ | EV_PERSIST, 1, false, main_base))) {3149 fprintf(stderr, "failed to create listening connection\n");3150 exit(EXIT_FAILURE);3151 }3152 3153 if (listen_conn == NULL) {3154 next = listen_conn = listen_conn_add;3155 } else {3156 next->next= listen_conn_add;3157 }3158 }3159 3083 } 3160 3084 /* start up worker threads if MT mode */ … … 3174 3098 } 3175 3099 delete_handler(0, 0, 0); /* sets up the event */ 3176 /* create the initial listening udp connection, monitored on all threads */ 3177 if (u_socket) { 3178 for (c = 0; c < settings.num_threads; c++) { 3179 /* this is guaranteed to hit all threads because we round-robin */ 3180 dispatch_conn_new(*u_socket, conn_read, EV_READ | EV_PERSIST, 3181 UDP_READ_BUFFER_SIZE, 1); 3182 } 3183 } 3100 3101 /* create unix mode sockets after dropping privileges */ 3102 if (settings.socketpath != NULL) { 3103 if (server_socket_unix(settings.socketpath,settings.access)) { 3104 fprintf(stderr, "failed to listen\n"); 3105 exit(EXIT_FAILURE); 3106 } 3107 } 3108 3109 /* create the listening socket, bind it, and init */ 3110 if (settings.socketpath == NULL) { 3111 int udp_port; 3112 3113 if (server_socket(settings.port, 0)) { 3114 fprintf(stderr, "failed to listen\n"); 3115 exit(EXIT_FAILURE); 3116 } 3117 /* 3118 * initialization order: first create the listening sockets 3119 * (may need root on low ports), then drop root if needed, 3120 * then daemonise if needed, then init libevent (in some cases 3121 * descriptors created by libevent wouldn't survive forking). 3122 */ 3123 udp_port = settings.udpport ? settings.udpport : settings.port; 3124 3125 /* create the UDP listening socket and bind it */ 3126 if (server_socket(udp_port, 1)) { 3127 fprintf(stderr, "failed to listen on UDP port %d\n", settings.udpport); 3128 exit(EXIT_FAILURE); 3129 } 3130 } 3131 3184 3132 /* enter the event loop */ 3185 3133 event_base_loop(main_base, 0);
