Changeset 727
- Timestamp:
- 02/27/08 05:54:16 (6 months ago)
- Files:
-
- branches/binary/server/memcached.c (modified) (15 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/binary/server/memcached.c
r725 r727 66 66 static void drive_machine(conn *c); 67 67 static int new_socket(struct addrinfo *ai); 68 static int *server_socket(const int port, const int prot, int *count);68 static int server_socket(const int port, const int prot); 69 69 static int try_read_command(conn *c); 70 70 static int try_read_network(conn *c); … … 2987 2987 2988 2988 2989 static int *server_socket(const int port, const int prot, int *count) {2989 static int server_socket(const int port, const int prot) { 2990 2990 int sfd; 2991 int *sfd_list;2992 int *sfd_ptr;2993 2991 struct linger ling = {0, 0}; 2994 2992 struct addrinfo *ai; … … 3026 3024 perror("getaddrinfo()"); 3027 3025 3028 return NULL; 3029 } 3030 3031 for (*count= 1, next= ai; next->ai_next; next= next->ai_next, (*count)++); 3032 3033 sfd_list= (int *)calloc(*count, sizeof(int)); 3034 if (sfd_list == NULL) { 3035 fprintf(stderr, "calloc()\n"); 3036 return NULL; 3037 } 3038 memset(sfd_list, -1, sizeof(int) * (*count)); 3039 3040 for (sfd_ptr= sfd_list, next= ai; next; next= next->ai_next, sfd_ptr++) { 3026 return 1; 3027 } 3028 3029 for (next= ai; next; next= next->ai_next) { 3030 conn *listen_conn_add; 3041 3031 if ((sfd = new_socket(next)) == -1) { 3042 free(sfd_list);3043 3032 freeaddrinfo(ai); 3044 return NULL;3033 return 1; 3045 3034 } 3046 3035 … … 3057 3046 if (errno != EADDRINUSE) { 3058 3047 perror("bind()"); 3059 /* If we are not at the first element, loop back and close all sockets */3060 if (sfd_ptr != sfd_list) {3061 do {3062 --sfd_ptr;3063 close(*sfd_ptr);3064 } while (sfd_ptr != sfd_list);3065 }3066 3048 close(sfd); 3067 3049 freeaddrinfo(ai); 3068 free(sfd_list); 3069 return NULL; 3050 return 1; 3070 3051 } 3071 3052 close(sfd); 3072 *sfd_ptr= -1;3073 3053 } else { 3074 3054 success++; 3075 *sfd_ptr= sfd;3076 3055 if (!IS_UDP(prot) && listen(sfd, 1024) == -1) { 3077 3056 perror("listen()"); 3078 if (sfd_ptr != sfd_list) {3079 do {3080 --sfd_ptr;3081 close(*sfd_ptr);3082 } while (sfd_ptr != sfd_list);3083 }3084 3057 close(sfd); 3085 3058 freeaddrinfo(ai); 3086 free(sfd_list); 3087 return NULL; 3059 return 1; 3088 3060 } 3089 3061 } 3062 3063 if (IS_UDP(prot)) { 3064 int c; 3065 3066 for (c = 0; c < settings.num_threads; c++) { 3067 /* this is guaranteed to hit all threads because we round-robin */ 3068 dispatch_conn_new(sfd, conn_read, EV_READ | EV_PERSIST, 3069 UDP_READ_BUFFER_SIZE, ascii_udp_prot); 3070 } 3071 } else { 3072 if (!(listen_conn_add = conn_new(sfd, conn_listening, 3073 EV_READ | EV_PERSIST, 1, 3074 prot, main_base))) { 3075 fprintf(stderr, "failed to create listening connection\n"); 3076 exit(EXIT_FAILURE); 3077 } 3078 3079 if (listen_conn == NULL) { 3080 listen_conn = listen_conn_add; 3081 } else { 3082 listen_conn_add->next = listen_conn->next; 3083 listen_conn->next = listen_conn_add; 3084 } 3085 } 3090 3086 } 3091 3087 3092 3088 freeaddrinfo(ai); 3093 3089 3094 if (success == 0) { 3095 free(sfd_list); 3096 return NULL; 3097 } 3098 3099 return sfd_list; 3090 return 0; 3100 3091 } 3101 3092 … … 3118 3109 } 3119 3110 3120 static int *server_socket_unix(const char *path, int access_mask) {3111 static int server_socket_unix(const char *path, int access_mask) { 3121 3112 int sfd; 3122 int *sfd_list;3123 3113 struct linger ling = {0, 0}; 3124 3114 struct sockaddr_un addr; … … 3128 3118 3129 3119 if (!path) { 3130 return NULL;3120 return 1; 3131 3121 } 3132 3122 3133 3123 if ((sfd = new_socket_unix()) == -1) { 3134 return NULL; 3135 } 3136 3137 /* 3138 When UNIX domain sockets get refactored, this will go away. 3139 For now we know there is just one socket. 3140 */ 3141 sfd_list= (int *)calloc(1, sizeof(int)); 3142 if (sfd_list == NULL) { 3143 fprintf(stderr, "calloc()\n"); 3144 return NULL; 3145 } 3146 memset(sfd_list, -1, sizeof(int) * 1); 3124 return 1; 3125 } 3147 3126 3148 3127 /* … … 3170 3149 perror("bind()"); 3171 3150 close(sfd); 3172 free(sfd_list);3173 3151 umask(old_umask); 3174 return NULL;3152 return 1; 3175 3153 } 3176 3154 umask(old_umask); … … 3178 3156 perror("listen()"); 3179 3157 close(sfd); 3180 free(sfd_list); 3181 return NULL; 3182 } 3183 3184 *sfd_list= sfd; 3185 3186 return sfd_list; 3158 return 1; 3159 } 3160 if (!(listen_conn = conn_new(sfd, conn_listening, 3161 EV_READ | EV_PERSIST, 1, false, main_base))) { 3162 fprintf(stderr, "failed to create listening connection\n"); 3163 exit(EXIT_FAILURE); 3164 } 3165 3166 return 0; 3187 3167 } 3188 3168 … … 3422 3402 listen_conn = listen_conn_add; 3423 3403 } else { 3424 listen_conn_add->next = listen_conn->next;3425 listen_conn->next = listen_conn_add;3404 listen_conn_add->next = listen_conn->next; 3405 listen_conn->next = listen_conn_add; 3426 3406 } 3427 3407 } … … 3489 3469 static int *l_socket = NULL; 3490 3470 static int *bl_socket = NULL; 3491 static int l_socket_count = 0;3492 static int bl_socket_count = 0;3493 3471 3494 3472 /* udp socket */ … … 3652 3630 } 3653 3631 3654 /*3655 * initialization order: first create the listening sockets3656 * (may need root on low ports), then drop root if needed,3657 * then daemonise if needed, then init libevent (in some cases3658 * descriptors created by libevent wouldn't survive forking).3659 */3660 3661 /* create the listening socket and bind it */3662 if (settings.socketpath == NULL) {3663 l_socket = server_socket(settings.port, 0, &l_socket_count);3664 if (l_socket == NULL) {3665 fprintf(stderr, "failed to listen\n");3666 exit(EXIT_FAILURE);3667 }3668 /* Try the binary port. */3669 if(settings.binport > 0) {3670 bl_socket = server_socket(settings.binport, 0, &bl_socket_count);3671 if (bl_socket == NULL) {3672 fprintf(stderr, "failed to listen to binary protocol\n");3673 exit(EXIT_FAILURE);3674 }3675 }3676 }3677 3678 if (settings.udpport > 0 && settings.socketpath == NULL) {3679 /* create the UDP listening socket and bind it */3680 u_socket = server_socket(settings.udpport, ascii_udp_prot,3681 &u_socket_count);3682 if (u_socket == NULL) {3683 fprintf(stderr, "failed to listen on UDP port %d\n", settings.udpport);3684 exit(EXIT_FAILURE);3685 }3686 }3687 3688 3632 /* lock paged memory if needed */ 3689 3633 if (lock_memory) { … … 3713 3657 return 1; 3714 3658 } 3715 }3716 3717 /* create unix mode sockets after dropping privileges */3718 if (settings.socketpath != NULL) {3719 l_socket = server_socket_unix(settings.socketpath,settings.access);3720 if (l_socket == NULL) {3721 fprintf(stderr, "failed to listen\n");3722 exit(EXIT_FAILURE);3723 }3724 /* We only support one of these, so whe know the count */3725 l_socket_count = 1;3726 3659 } 3727 3660 … … 3736 3669 } 3737 3670 } 3738 3739 3671 3740 3672 /* initialize main thread libevent instance */ … … 3771 3703 exit(EXIT_FAILURE); 3772 3704 } 3773 /* Set up all of the listening connections */3774 setup_listening_conns(l_socket, l_socket_count, ascii_prot);3775 setup_listening_conns(bl_socket, bl_socket_count, binary_prot);3776 3777 3705 /* start up worker threads if MT mode */ 3778 3706 thread_init(settings.num_threads, main_base); … … 3791 3719 } 3792 3720 delete_handler(0, 0, 0); /* sets up the event */ 3793 /* create the initial listening udp connection, monitored on all threads */ 3794 if (u_socket) { 3795 for (c = 0; c < settings.num_threads; c++) { 3796 /* this is guaranteed to hit all threads because we round-robin */ 3797 dispatch_conn_new(*u_socket, conn_read, EV_READ | EV_PERSIST, 3798 UDP_READ_BUFFER_SIZE, ascii_udp_prot); 3799 } 3800 } 3721 3722 /* create unix mode sockets after dropping privileges */ 3723 if (settings.socketpath != NULL) { 3724 if (server_socket_unix(settings.socketpath,settings.access)) { 3725 fprintf(stderr, "failed to listen\n"); 3726 exit(EXIT_FAILURE); 3727 } 3728 } 3729 3730 /* create the listening socket, bind it, and init */ 3731 if (settings.socketpath == NULL) { 3732 int udp_port; 3733 3734 if (server_socket(settings.port, ascii_prot)) { 3735 fprintf(stderr, "failed to listen\n"); 3736 exit(EXIT_FAILURE); 3737 } 3738 3739 /* Try the binary port. */ 3740 if(settings.binport > 0) { 3741 if(server_socket(settings.binport, binary_prot)) { 3742 fprintf(stderr, "failed to listen to binary protocol\n"); 3743 exit(EXIT_FAILURE); 3744 } 3745 } 3746 /* 3747 * initialization order: first create the listening sockets 3748 * (may need root on low ports), then drop root if needed, 3749 * then daemonise if needed, then init libevent (in some cases 3750 * descriptors created by libevent wouldn't survive forking). 3751 */ 3752 udp_port = settings.udpport ? settings.udpport : settings.port; 3753 3754 /* create the UDP listening socket and bind it */ 3755 if (server_socket(udp_port, ascii_udp_prot)) { 3756 fprintf(stderr, "failed to listen on UDP port %d\n", settings.udpport); 3757 exit(EXIT_FAILURE); 3758 } 3759 } 3760 3801 3761 /* enter the event loop */ 3802 3762 event_base_loop(main_base, 0);
