Changeset 717
- Timestamp:
- 02/25/08 07:55:14 (9 months ago)
- Files:
-
- branches/binary/TODO.txt (modified) (1 diff)
- branches/binary/server/ChangeLog (modified) (1 diff)
- branches/binary/server/configure.ac (modified) (2 diffs)
- branches/binary/server/doc/protocol.txt (modified) (1 diff)
- branches/binary/server/memcached.c (modified) (35 diffs)
- branches/binary/server/memcached.h (modified) (5 diffs)
- branches/binary/server/slabs.c (modified) (1 diff)
- branches/binary/server/t/lib/MemcachedTest.pm (modified) (1 diff)
- branches/binary/website/apis.bml (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/binary/TODO.txt
r460 r717 1 * virtual bucket support2 http://rt.livejournal.org/Ticket/Display.html?id=503 4 1 * Cache-Memcached and Devel::Profile 5 2 http://rt.livejournal.org/Ticket/Display.html?id=319 6 3 7 * Atomic replace and append operations (fwd)8 http://rt.livejournal.org/Ticket/Display.html?id=3299 10 4 * Re: Cache::Memcached fix for problems with sockets used as string (fwd) 11 5 http://rt.livejournal.org/Ticket/Display.html?id=339 12 13 * perl hot spots of Cache::MemCached in C14 http://rt.livejournal.org/Ticket/Display.html?id=56215 16 * Using constant makes campers happy17 http://rt.livejournal.org/Ticket/Display.html?id=72018 19 * Make the control flow way more readable20 http://rt.livejournal.org/Ticket/Display.html?id=72121 22 * micro optimisation for most common case23 http://rt.livejournal.org/Ticket/Display.html?id=72224 25 * use gotos for 10% speed up of _oneline26 http://rt.livejournal.org/Ticket/Display.html?id=72327 28 * Subject: some fixes and improvements29 http://rt.livejournal.org/Ticket/Display.html?id=122830 6 31 7 * sendfile from memcached? branches/binary/server/ChangeLog
r660 r717 1 2008-12-17 2 3 * IPv6 support, and IPv6 multi-interface support (brian@tangent.org) 4 5 * Add compiler options for Sun Studio compilers with --enable-threads 6 (Trond.Norbye@Sun.COM) 7 8 * Add --enable-64bit for mulitarget platforms (Trond.Norbye@Sun.COM) 9 10 * Use gettimeofday(2) instead of time(2). 11 12 2008-02-10 13 14 * Make -k option work (Tomash Brechko) 15 16 * Fix chunk slab alignment (Trond.Norbye@Sun.COM) 17 1 18 2007-12-06 [Version 1.2.4 released] 2 19 branches/binary/server/configure.ac
r668 r717 9 9 AM_PROG_CC_C_O 10 10 AC_PROG_INSTALL 11 12 AC_ARG_ENABLE(64bit, 13 [AS_HELP_STRING([--enable-64bit],[build 64bit verison])]) 14 if test "x$enable_64bit" == "xyes" 15 then 16 org_cflags=$CFLAGS 17 CFLAGS=-m64 18 AC_RUN_IFELSE( 19 [AC_LANG_PROGRAM([], [dnl 20 return sizeof(void*) == 8 ? 0 : 1; 21 ]) 22 ],[ 23 CFLAGS="-m64 $org_cflags" 24 ],[ 25 AC_MSG_ERROR([Don't know how to build a 64-bit object.]) 26 ]) 27 fi 11 28 12 29 trylibeventdir="" … … 165 182 if test "x$ac_cv_search_pthread_create" != "xno"; then 166 183 AC_DEFINE([USE_THREADS],,[Define this if you want to use pthreads]) 184 dnl Sun compilers need the -mt flag! 185 AC_RUN_IFELSE( 186 [AC_LANG_PROGRAM([], [dnl 187 #ifdef __SUNPRO_C 188 return 0; 189 #else 190 return 1; 191 #endif 192 ]) 193 ],[ 194 CFLAGS="-mt $CFLAGS" 195 ]) 167 196 else 168 197 AC_MSG_ERROR([Can't enable threads without the POSIX thread library.]) branches/binary/server/doc/protocol.txt
r644 r717 194 194 - "EXISTS\r\n" to indicate that the item you are trying to store with 195 195 a "cas" command has been modified since you last fetched it. 196 197 - "NOT_FOUND\r\n" to indicate that the item you are trying to store 198 with a "cas" command did not exist or has been deleted. 196 199 197 200 branches/binary/server/memcached.c
r692 r717 20 20 #include <sys/socket.h> 21 21 #include <sys/un.h> 22 #include <s ys/signal.h>22 #include <signal.h> 23 23 #include <sys/resource.h> 24 24 #include <sys/uio.h> … … 65 65 */ 66 66 static void drive_machine(conn *c); 67 static int new_socket( const int prot);68 static int server_socket(const int port, const int prot);67 static int new_socket(struct addrinfo *ai); 68 static int *server_socket(const int port, const int prot, int *count); 69 69 static int try_read_command(conn *c); 70 70 static int try_read_network(conn *c); … … 97 97 (to avoid 64 bit time_t) */ 98 98 99 void pre_gdb(void);100 99 static void conn_free(conn *c); 101 100 … … 108 107 static int delcurr; 109 108 static int deltotal; 110 static conn *listen_conn; 111 static conn *bin_listen_conn; 109 static conn *listen_conn = NULL; 112 110 static struct event_base *main_base; 113 111 … … 171 169 settings.port = 11211; 172 170 settings.udpport = 0; 173 settings.interf.s_addr = htonl(INADDR_ANY); 171 /* By default this string should be NULL for getaddrinfo() */ 172 settings.inter = NULL; 174 173 settings.maxbytes = 64 * 1024 * 1024; /* default is 64MB */ 175 174 settings.maxconns = 1024; /* to limit connections-related memory to about 5MB */ … … 254 253 freecurr = 0; 255 254 if ((freeconns = (conn **)malloc(sizeof(conn *) * freetotal)) == NULL) { 256 perror("malloc()");255 fprintf(stderr, "malloc()\n"); 257 256 } 258 257 return; … … 303 302 if (NULL == c) { 304 303 if (!(c = (conn *)malloc(sizeof(conn)))) { 305 perror("malloc()");304 fprintf(stderr, "malloc()\n"); 306 305 return NULL; 307 306 } … … 337 336 if (c->msglist != 0) free(c->msglist); 338 337 free(c); 339 perror("malloc()");338 fprintf(stderr, "malloc()\n"); 340 339 return NULL; 341 340 } … … 402 401 conn_free(c); 403 402 } 403 perror("event_add"); 404 404 return NULL; 405 405 } … … 600 600 freesuffix = (char **)malloc( sizeof(char *) * freesuffixtotal ); 601 601 if (freesuffix == NULL) { 602 perror("malloc()");602 fprintf(stderr, "malloc()\n"); 603 603 } 604 604 return; … … 2478 2478 } 2479 2479 2480 res = read(c->sfd, c->rbuf + c->rbytes, c->rsize - c->rbytes); 2480 int avail = c->rsize - c->rbytes; 2481 res = read(c->sfd, c->rbuf + c->rbytes, avail); 2481 2482 if (res > 0) { 2482 2483 STATS_LOCK(); … … 2485 2486 gotdata = 1; 2486 2487 c->rbytes += res; 2487 continue; 2488 if (res == avail) { 2489 continue; 2490 } else { 2491 break; 2492 } 2488 2493 } 2489 2494 if (res == 0) { … … 2518 2523 */ 2519 2524 void accept_new_conns(const bool do_accept) { 2525 conn *next; 2526 2520 2527 if (! is_listen_thread()) 2521 2528 return; 2522 if (do_accept) { 2523 update_event(listen_conn, EV_READ | EV_PERSIST); 2524 if (listen(listen_conn->sfd, 1024) != 0) { 2525 perror("listen"); 2526 } 2527 } 2528 else { 2529 update_event(listen_conn, 0); 2530 if (listen(listen_conn->sfd, 0) != 0) { 2531 perror("listen"); 2532 } 2533 } 2529 2530 for (next = listen_conn; next; next = next->next) { 2531 if (do_accept) { 2532 update_event(next, EV_READ | EV_PERSIST); 2533 if (listen(next->sfd, 1024) != 0) { 2534 perror("listen"); 2535 } 2536 } 2537 else { 2538 update_event(next, 0); 2539 if (listen(next->sfd, 0) != 0) { 2540 perror("listen"); 2541 } 2542 } 2543 } 2534 2544 } 2535 2545 … … 2606 2616 int init_state; /* initial state for a new connection */ 2607 2617 socklen_t addrlen; 2608 struct sockaddr addr;2618 struct sockaddr_storage addr; 2609 2619 int res; 2610 2620 … … 2616 2626 case conn_listening: 2617 2627 addrlen = sizeof(addr); 2618 if ((sfd = accept(c->sfd, &addr, &addrlen)) == -1) {2628 if ((sfd = accept(c->sfd, (struct sockaddr *)&addr, &addrlen)) == -1) { 2619 2629 if (errno == EAGAIN || errno == EWOULDBLOCK) { 2620 2630 /* these are transient, so don't log anything */ … … 2867 2877 } 2868 2878 2869 static int new_socket( const int prot) {2879 static int new_socket(struct addrinfo *ai) { 2870 2880 int sfd; 2871 2881 int flags; 2872 2882 2873 if ((sfd = socket( AF_INET, IS_UDP(prot) ? SOCK_DGRAM : SOCK_STREAM, 0)) == -1) {2883 if ((sfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) == -1) { 2874 2884 perror("socket()"); 2875 2885 return -1; … … 2921 2931 2922 2932 2923 static int server_socket(const int port, const int prot) {2933 static int *server_socket(const int port, const int prot, int *count) { 2924 2934 int sfd; 2935 int *sfd_list; 2936 int *sfd_ptr; 2925 2937 struct linger ling = {0, 0}; 2926 struct sockaddr_in addr; 2938 struct addrinfo *ai; 2939 struct addrinfo *next; 2940 struct addrinfo hints; 2941 char port_buf[NI_MAXSERV]; 2942 int error; 2943 int success = 0; 2944 2927 2945 int flags =1; 2928 2929 if ((sfd = new_socket(prot)) == -1) {2930 return -1;2931 }2932 2933 setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void *)&flags, sizeof(flags));2934 if (IS_UDP(prot)) {2935 maximize_sndbuf(sfd);2936 } else {2937 setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&flags, sizeof(flags));2938 setsockopt(sfd, SOL_SOCKET, SO_LINGER, (void *)&ling, sizeof(ling));2939 setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags));2940 }2941 2946 2942 2947 /* … … 2944 2949 * that otherwise mess things up. 2945 2950 */ 2946 memset(&addr, 0, sizeof(addr)); 2947 2948 addr.sin_family = AF_INET; 2949 addr.sin_port = htons(port); 2950 addr.sin_addr = settings.interf; 2951 if (bind(sfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { 2952 perror("bind()"); 2953 close(sfd); 2954 return -1; 2955 } 2956 if (!IS_UDP(prot) && listen(sfd, 1024) == -1) { 2957 perror("listen()"); 2958 close(sfd); 2959 return -1; 2960 } 2961 return sfd; 2951 memset(&hints, 0, sizeof (hints)); 2952 hints.ai_flags = AI_PASSIVE|AI_ADDRCONFIG; 2953 if (IS_UDP(prot)) 2954 { 2955 hints.ai_protocol = IPPROTO_UDP; 2956 hints.ai_socktype = SOCK_DGRAM; 2957 hints.ai_family = AF_INET; /* This left here because of issues with OSX 10.5 */ 2958 } else { 2959 hints.ai_family = AF_UNSPEC; 2960 hints.ai_protocol = IPPROTO_TCP; 2961 hints.ai_socktype = SOCK_STREAM; 2962 } 2963 2964 snprintf(port_buf, NI_MAXSERV, "%d", port); 2965 error= getaddrinfo(settings.inter, port_buf, &hints, &ai); 2966 if (error != 0) { 2967 if (error != EAI_SYSTEM) 2968 fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(error)); 2969 else 2970 perror("getaddrinfo()"); 2971 2972 return NULL; 2973 } 2974 2975 for (*count= 1, next= ai; next->ai_next; next= next->ai_next, (*count)++); 2976 2977 sfd_list= (int *)calloc(*count, sizeof(int)); 2978 if (sfd_list == NULL) { 2979 fprintf(stderr, "calloc()\n"); 2980 return NULL; 2981 } 2982 memset(sfd_list, -1, sizeof(int) * (*count)); 2983 2984 for (sfd_ptr= sfd_list, next= ai; next; next= next->ai_next, sfd_ptr++) { 2985 if ((sfd = new_socket(next)) == -1) { 2986 free(sfd_list); 2987 freeaddrinfo(ai); 2988 return NULL; 2989 } 2990 2991 setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void *)&flags, sizeof(flags)); 2992 if (IS_UDP(prot)) { 2993 maximize_sndbuf(sfd); 2994 } else { 2995 setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&flags, sizeof(flags)); 2996 setsockopt(sfd, SOL_SOCKET, SO_LINGER, (void *)&ling, sizeof(ling)); 2997 setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags)); 2998 } 2999 3000 if (bind(sfd, next->ai_addr, next->ai_addrlen) == -1) { 3001 if (errno != EADDRINUSE) { 3002 perror("bind()"); 3003 /* If we are not at the first element, loop back and close all sockets */ 3004 if (sfd_ptr != sfd_list) { 3005 do { 3006 --sfd_ptr; 3007 close(*sfd_ptr); 3008 } while (sfd_ptr != sfd_list); 3009 } 3010 close(sfd); 3011 freeaddrinfo(ai); 3012 free(sfd_list); 3013 return NULL; 3014 } 3015 close(sfd); 3016 *sfd_ptr= -1; 3017 } else { 3018 success++; 3019 *sfd_ptr= sfd; 3020 if (!IS_UDP(prot) && listen(sfd, 1024) == -1) { 3021 perror("listen()"); 3022 if (sfd_ptr != sfd_list) { 3023 do { 3024 --sfd_ptr; 3025 close(*sfd_ptr); 3026 } while (sfd_ptr != sfd_list); 3027 } 3028 close(sfd); 3029 freeaddrinfo(ai); 3030 free(sfd_list); 3031 return NULL; 3032 } 3033 } 3034 } 3035 3036 freeaddrinfo(ai); 3037 3038 if (success == 0) { 3039 free(sfd_list); 3040 return NULL; 3041 } 3042 3043 return sfd_list; 2962 3044 } 2963 3045 … … 2980 3062 } 2981 3063 2982 static int server_socket_unix(const char *path, int access_mask) {3064 static int *server_socket_unix(const char *path, int access_mask) { 2983 3065 int sfd; 3066 int *sfd_list; 2984 3067 struct linger ling = {0, 0}; 2985 3068 struct sockaddr_un addr; … … 2989 3072 2990 3073 if (!path) { 2991 return -1;3074 return NULL; 2992 3075 } 2993 3076 2994 3077 if ((sfd = new_socket_unix()) == -1) { 2995 return -1; 2996 } 3078 return NULL; 3079 } 3080 3081 /* 3082 When UNIX domain sockets get refactored, this will go away. 3083 For now we know there is just one socket. 3084 */ 3085 sfd_list= (int *)calloc(1, sizeof(int)); 3086 if (sfd_list == NULL) { 3087 fprintf(stderr, "calloc()\n"); 3088 return NULL; 3089 } 3090 memset(sfd_list, -1, sizeof(int) * 1); 2997 3091 2998 3092 /* … … 3020 3114 perror("bind()"); 3021 3115 close(sfd); 3116 free(sfd_list); 3022 3117 umask(old_umask); 3023 return -1;3118 return NULL; 3024 3119 } 3025 3120 umask(old_umask); … … 3027 3122 perror("listen()"); 3028 3123 close(sfd); 3029 return -1; 3030 } 3031 return sfd; 3032 } 3033 3034 /* listening socket */ 3035 static int l_socket = 0; 3036 /* Listening socket for the binary protocol */ 3037 static int bl_socket = -1; 3038 3039 /* udp socket */ 3040 static int u_socket = -1; 3041 3042 /* invoke right before gdb is called, on assert */ 3043 void pre_gdb(void) { 3044 int i; 3045 if (l_socket > -1) close(l_socket); 3046 if (bl_socket > -1) close(bl_socket); 3047 if (u_socket > -1) close(u_socket); 3048 for (i = 3; i <= 500; i++) close(i); /* so lame */ 3049 kill(getpid(), SIGABRT); 3124 free(sfd_list); 3125 return NULL; 3126 } 3127 3128 *sfd_list= sfd; 3129 3130 return sfd_list; 3050 3131 } 3051 3132 … … 3063 3144 /* time-sensitive callers can call it by hand with this, outside the normal ever-1-second timer */ 3064 3145 static void set_current_time(void) { 3065 current_time = (rel_time_t) (time(0) - stats.started); 3146 struct timeval timer; 3147 3148 gettimeofday(&timer, NULL); 3149 current_time = (rel_time_t) (timer.tv_sec - stats.started); 3066 3150 } 3067 3151 … … 3137 3221 "-M return error on memory exhausted (rather than removing items)\n" 3138 3222 "-c <num> max simultaneous connections, default is 1024\n" 3139 "-k lock down all paged memory\n" 3223 "-k lock down all paged memory. Note that there is a\n" 3224 " limit on how much memory you may lock. Trying to\n" 3225 " allocate more than that would fail, so be sure you\n" 3226 " set the limit correctly for the user you started\n" 3227 " the daemon with (not for -u <username> user;\n" 3228 " under sh this is done with 'ulimit -S -l NUM_KB').\n" 3140 3229 "-v verbose (print errors/warnings while in event loop)\n" 3141 3230 "-vv very verbose (also print client commands/reponses)\n" … … 3258 3347 int main (int argc, char **argv) { 3259 3348 int c; 3260 struct in_addr addr;3349 int x; 3261 3350 bool lock_memory = false; 3262 3351 bool daemonize = false; … … 3267 3356 struct sigaction sa; 3268 3357 struct rlimit rlim; 3358 /* listening sockets */ 3359 static int *l_socket = NULL; 3360 static int *bl_socket = NULL; 3361 static int l_socket_count = 0; 3362 static int bl_socket_count = 0; 3363 3364 /* udp socket */ 3365 static int *u_socket = NULL; 3366 static int u_socket_count = 0; 3269 3367 3270 3368 /* handle SIGINT */ … … 3322 3420 break; 3323 3421 case 'l': 3324 if (inet_pton(AF_INET, optarg, &addr) <= 0) { 3325 fprintf(stderr, "Illegal address: %s\n", optarg); 3326 return 1; 3327 } else { 3328 settings.interf = addr; 3329 } 3422 settings.inter= strdup(optarg); 3330 3423 break; 3331 3424 case 'd': … … 3431 3524 /* create the listening socket and bind it */ 3432 3525 if (settings.socketpath == NULL) { 3433 l_socket = server_socket(settings.port, 0 );3434 if (l_socket == -1) {3526 l_socket = server_socket(settings.port, 0, &l_socket_count); 3527 if (l_socket == NULL) { 3435 3528 fprintf(stderr, "failed to listen\n"); 3436 3529 exit(EXIT_FAILURE); … … 3438 3531 /* Try the binary port. */ 3439 3532 if(settings.binport > 0) { 3440 bl_socket = server_socket(settings.binport, 0 );3441 if (bl_socket == -1) {3533 bl_socket = server_socket(settings.binport, 0, &bl_socket_count); 3534 if (bl_socket == NULL) { 3442 3535 fprintf(stderr, "failed to listen to binary protocol\n"); 3443 3536 exit(EXIT_FAILURE); … … 3448 3541 if (settings.udpport > 0 && settings.socketpath == NULL) { 3449 3542 /* create the UDP listening socket and bind it */ 3450 u_socket = server_socket(settings.udpport, 1 );3451 if (u_socket == -1) {3543 u_socket = server_socket(settings.udpport, 1, &u_socket_count); 3544 if (u_socket == NULL) { 3452 3545 fprintf(stderr, "failed to listen on UDP port %d\n", settings.udpport); 3453 3546 exit(EXIT_FAILURE); 3454 3547 } 3548 } 3549 3550 /* lock paged memory if needed */ 3551 if (lock_memory) { 3552 #ifdef HAVE_MLOCKALL 3553 int res = mlockall(MCL_CURRENT | MCL_FUTURE); 3554 if (res != 0) { 3555 fprintf(stderr, "warning: -k invalid, mlockall() failed: %s\n", 3556 strerror(errno)); 3557 } 3558 #else 3559 fprintf(stderr, "warning: -k invalid, mlockall() not supported on this platform. proceeding without.\n"); 3560 #endif 3455 3561 } 3456 3562 … … 3474 3580 if (settings.socketpath != NULL) { 3475 3581 l_socket = server_socket_unix(settings.socketpath,settings.access); 3476 if (l_socket == -1) { 3477 fprintf(stderr, "failed to listen\n"); 3478 exit(EXIT_FAILURE); 3479 } 3582 if (l_socket == NULL) { 3583 fprintf(stderr, "failed to listen\n"); 3584 exit(EXIT_FAILURE); 3585 } 3586 /* We only support one of these, so whe know the count */ 3587 l_socket_count = 1; 3480 3588 } 3481 3589 … … 3512 3620 } 3513 3621 memset(buckets, 0, sizeof(int) * MAX_BUCKETS); 3514 }3515 3516 /* lock paged memory if needed */3517 if (lock_memory) {3518 #ifdef HAVE_MLOCKALL3519 mlockall(MCL_CURRENT | MCL_FUTURE);3520 #else3521 fprintf(stderr, "warning: mlockall() not supported on this platform. proceeding without.\n");3522 #endif3523 3622 } 3524 3623 … … 3535 3634 } 3536 3635 /* create the initial listening connection */ 3537 if (!(listen_conn = conn_new(l_socket, conn_listening, 3538 EV_READ | EV_PERSIST, 1, ascii_prot, 3539 main_base))) { 3540 fprintf(stderr, "failed to create listening connection"); 3541 exit(EXIT_FAILURE); 3542 } 3543 3544 /* Same for binary protocol */ 3545 if (bl_socket > 0) { 3546 if (!(bin_listen_conn = conn_new(bl_socket, conn_listening, 3547 EV_READ | EV_PERSIST, 1, binary_prot, 3548 main_base))) { 3549 fprintf(stderr, "failed to create listening connection"); 3550 exit(EXIT_FAILURE); 3636 int *l_socket_ptr; 3637 conn *next = NULL; 3638 for (l_socket_ptr= l_socket, x = 0; x < l_socket_count; l_socket_ptr++, x++) { 3639 conn *listen_conn_add; 3640 if (*l_socket_ptr > -1 ) { 3641 if (!(listen_conn_add = conn_new(*l_socket_ptr, conn_listening, 3642 EV_READ | EV_PERSIST, 1, ascii_prot, main_base))) { 3643 fprintf(stderr, "failed to create listening connection\n"); 3644 exit(EXIT_FAILURE); 3645 } 3646 3647 if (listen_conn == NULL) { 3648 next = listen_conn = listen_conn_add; 3649 } else { 3650 next->next= listen_conn_add; 3651 } 3652 } 3653 } 3654 3655 for (l_socket_ptr= bl_socket, x = 0; x < bl_socket_count; l_socket_ptr++, x++) { 3656 conn *listen_conn_add; 3657 if (*l_socket_ptr > -1 ) { 3658 if (!(listen_conn_add = conn_new(*l_socket_ptr, conn_listening, 3659 EV_READ | EV_PERSIST, 1, binary_prot, main_base))) { 3660 fprintf(stderr, "failed to create listening connection\n"); 3661 exit(EXIT_FAILURE); 3662 } 3663 3664 if (listen_conn == NULL) { 3665 next = listen_conn = listen_conn_add; 3666 } else { 3667 next->next= listen_conn_add; 3668 } 3551 3669 } 3552 3670 } … … 3569 3687 delete_handler(0, 0, 0); /* sets up the event */ 3570 3688 /* create the initial listening udp connection, monitored on all threads */ 3571 if (u_socket > -1) {3689 if (u_socket) { 3572 3690 for (c = 0; c < settings.num_threads; c++) { 3573 3691 /* this is guaranteed to hit all threads because we round-robin */ 3574 dispatch_conn_new( u_socket, conn_read, EV_READ | EV_PERSIST,3692 dispatch_conn_new(*u_socket, conn_read, EV_READ | EV_PERSIST, 3575 3693 UDP_READ_BUFFER_SIZE, ascii_udp_prot); 3576 3694 } … … 3581 3699 if (daemonize) 3582 3700 remove_pidfile(pid_file); 3701 /* Clean up strdup() call for bind() address */ 3702 if (settings.inter) 3703 free(settings.inter); 3704 if (l_socket) 3705 free(l_socket); 3706 if (u_socket) 3707 free(u_socket); 3708 3583 3709 return 0; 3584 3710 } branches/binary/server/memcached.h
r692 r717 11 11 #include <netinet/in.h> 12 12 #include <event.h> 13 #include <netdb.h> 13 14 14 15 #define DATA_BUFFER_SIZE 2048 … … 127 128 int udpport; 128 129 int binport; /* Port for binary protocol. */ 129 struct in_addr interf;130 char *inter; 130 131 int verbose; 131 132 rel_time_t oldest_live; /* ignore existing items older than this */ … … 212 213 #define NREAD_CAS 6 213 214 214 typedef struct { 215 typedef struct conn conn; 216 struct conn { 215 217 int sfd; 216 218 int state; … … 290 292 int opaque; 291 293 int keylen; 292 293 } conn; 294 conn *next; /* Used for generating a list of conn structures */ 295 }; 296 294 297 295 298 /* number of virtual buckets for a managed instance */ … … 298 301 /* current time of day (updated periodically) */ 299 302 extern volatile rel_time_t current_time; 300 301 /* temporary hack */302 /* #define assert(x) if(!(x)) { printf("assert failure: %s\n", #x); pre_gdb(); }303 void pre_gdb (); */304 303 305 304 /* branches/binary/server/slabs.c
r591 r717 26 26 #define POWER_LARGEST 200 27 27 #define POWER_BLOCK 1048576 28 #define CHUNK_ALIGN_BYTES (sizeof(void *))28 #define CHUNK_ALIGN_BYTES 8 29 29 #define DONT_PREALLOC_SLABS 30 30 branches/binary/server/t/lib/MemcachedTest.pm
r641 r717 143 143 144 144 sub new_memcached { 145 my $args = shift || "";146 my $port = free_port();145 my ($args, $passed_port) = @_; 146 my $port = $passed_port || free_port(); 147 147 my $udpport = free_port("udp"); 148 148 $args .= " -p $port"; branches/binary/website/apis.bml
r657 r717 16 16 the memcached.</p> 17 17 18 <p>There is also Cache::Memcached::Fast---another Perl client written in C, 19 largely compatible with the original Cache::Memcached. Available on CPAN at <a 20 href="http://search.cpan.org/dist/Cache-Memcached-Fast/">http://search.cpan.org/dist/Cache-Memcached-Fast/</a>.</p> 21 18 22 <?h1 PHP API h1?> 19 23 … … 32 36 <li><a href="http://www.deveiate.org/code/Ruby-MemCache.html">http://www.deveiate.org/code/Ruby-MemCache.html</a></li> 33 37 <li>gem install memcache-client</li> 38 <li><a href="http://blog.evanweaver.com/files/doc/fauna/memcached/">http://blog.evanweaver.com/files/doc/fauna/memcached/</a>. C backed client wrapping libmemcached. 34 39 </ul> 35 40 … … 60 65 <ul> 61 66 <li><a href="http://www.outoforder.cc/projects/libs/apr_memcache/">apr_memcache</a> by Paul Querna; Apache Software License version 2.0</li> 62 <li><a href="http://tangent.org/552/libmemcached.html">libmemcached</a> by 63 Brian Aker; BSD license.</li> 64 <li><a href="http://people.freebsd.org/~seanc/libmemcache/">libmemcache</a> by Sean Chittenden; BSD license.</li> 67 <li><a href="http://tangent.org/552/libmemcached.html">libmemcached</a> by Brian Aker; BSD license. This is a new library, under heavy development.</li> 68 <li><a href="http://people.freebsd.org/~seanc/libmemcache/">libmemcache</a> by Sean Chittenden; BSD license. This is the original C library. It is no longer under active development. You should try libmemcached instead.</li> 65 69 </ul> 66 70
