Changeset 717

Show
Ignore:
Timestamp:
02/25/08 07:55:14 (9 months ago)
Author:
dsallings
Message:

Merge branch 'master' into binary-merged

This was a big hack of a merge, but I wanted to hold my spot before doing
deeper verification.

Conflicts:

server/memcached.c
server/memcached.h

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/binary/TODO.txt

    r460 r717  
    1 * virtual bucket support 
    2   http://rt.livejournal.org/Ticket/Display.html?id=50 
    3  
    41* Cache-Memcached and Devel::Profile 
    52  http://rt.livejournal.org/Ticket/Display.html?id=319 
    63 
    7 * Atomic replace and append operations (fwd) 
    8   http://rt.livejournal.org/Ticket/Display.html?id=329 
    9  
    104* Re: Cache::Memcached fix for problems with sockets used as string (fwd) 
    115  http://rt.livejournal.org/Ticket/Display.html?id=339 
    12  
    13 * perl hot spots of Cache::MemCached in C 
    14   http://rt.livejournal.org/Ticket/Display.html?id=562 
    15  
    16 * Using constant makes campers happy 
    17   http://rt.livejournal.org/Ticket/Display.html?id=720 
    18  
    19 * Make the control flow way more readable 
    20   http://rt.livejournal.org/Ticket/Display.html?id=721 
    21  
    22 * micro optimisation for most common case 
    23   http://rt.livejournal.org/Ticket/Display.html?id=722 
    24  
    25 * use gotos for 10% speed up of _oneline 
    26   http://rt.livejournal.org/Ticket/Display.html?id=723 
    27  
    28 * Subject: some fixes and improvements 
    29   http://rt.livejournal.org/Ticket/Display.html?id=1228 
    306 
    317* sendfile from memcached? 
  • branches/binary/server/ChangeLog

    r660 r717  
     12008-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 
     122008-02-10 
     13 
     14       * Make -k option work (Tomash Brechko) 
     15 
     16           * Fix chunk slab alignment (Trond.Norbye@Sun.COM) 
     17 
    1182007-12-06 [Version 1.2.4 released] 
    219 
  • branches/binary/server/configure.ac

    r668 r717  
    99AM_PROG_CC_C_O 
    1010AC_PROG_INSTALL 
     11 
     12AC_ARG_ENABLE(64bit, 
     13  [AS_HELP_STRING([--enable-64bit],[build 64bit verison])]) 
     14if test "x$enable_64bit" == "xyes" 
     15then 
     16    org_cflags=$CFLAGS 
     17    CFLAGS=-m64 
     18    AC_RUN_IFELSE( 
     19      [AC_LANG_PROGRAM([], [dnl 
     20return 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    ]) 
     27fi 
    1128 
    1229trylibeventdir="" 
     
    165182  if test "x$ac_cv_search_pthread_create" != "xno"; then 
    166183    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    ]) 
    167196  else 
    168197    AC_MSG_ERROR([Can't enable threads without the POSIX thread library.]) 
  • branches/binary/server/doc/protocol.txt

    r644 r717  
    194194- "EXISTS\r\n" to indicate that the item you are trying to store with 
    195195a "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 
     198with a "cas" command did not exist or has been deleted. 
    196199 
    197200 
  • branches/binary/server/memcached.c

    r692 r717  
    2020#include <sys/socket.h> 
    2121#include <sys/un.h> 
    22 #include <sys/signal.h> 
     22#include <signal.h> 
    2323#include <sys/resource.h> 
    2424#include <sys/uio.h> 
     
    6565 */ 
    6666static void drive_machine(conn *c); 
    67 static int new_socket(const int prot); 
    68 static int server_socket(const int port, const int prot); 
     67static int new_socket(struct addrinfo *ai); 
     68static int *server_socket(const int port, const int prot, int *count); 
    6969static int try_read_command(conn *c); 
    7070static int try_read_network(conn *c); 
     
    9797                              (to avoid 64 bit time_t) */ 
    9898 
    99 void pre_gdb(void); 
    10099static void conn_free(conn *c); 
    101100 
     
    108107static int delcurr; 
    109108static int deltotal; 
    110 static conn *listen_conn; 
    111 static conn *bin_listen_conn; 
     109static conn *listen_conn = NULL; 
    112110static struct event_base *main_base; 
    113111 
     
    171169    settings.port = 11211; 
    172170    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; 
    174173    settings.maxbytes = 64 * 1024 * 1024; /* default is 64MB */ 
    175174    settings.maxconns = 1024;         /* to limit connections-related memory to about 5MB */ 
     
    254253    freecurr = 0; 
    255254    if ((freeconns = (conn **)malloc(sizeof(conn *) * freetotal)) == NULL) { 
    256         perror("malloc()"); 
     255        fprintf(stderr, "malloc()\n"); 
    257256    } 
    258257    return; 
     
    303302    if (NULL == c) { 
    304303        if (!(c = (conn *)malloc(sizeof(conn)))) { 
    305             perror("malloc()"); 
     304            fprintf(stderr, "malloc()\n"); 
    306305            return NULL; 
    307306        } 
     
    337336            if (c->msglist != 0) free(c->msglist); 
    338337            free(c); 
    339             perror("malloc()"); 
     338            fprintf(stderr, "malloc()\n"); 
    340339            return NULL; 
    341340        } 
     
    402401            conn_free(c); 
    403402        } 
     403        perror("event_add"); 
    404404        return NULL; 
    405405    } 
     
    600600    freesuffix = (char **)malloc( sizeof(char *) * freesuffixtotal ); 
    601601    if (freesuffix == NULL) { 
    602         perror("malloc()"); 
     602        fprintf(stderr, "malloc()\n"); 
    603603    } 
    604604    return; 
     
    24782478        } 
    24792479 
    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); 
    24812482        if (res > 0) { 
    24822483            STATS_LOCK(); 
     
    24852486            gotdata = 1; 
    24862487            c->rbytes += res; 
    2487             continue; 
     2488            if (res == avail) { 
     2489                continue; 
     2490            } else { 
     2491                break; 
     2492            } 
    24882493        } 
    24892494        if (res == 0) { 
     
    25182523 */ 
    25192524void accept_new_conns(const bool do_accept) { 
     2525    conn *next; 
     2526 
    25202527    if (! is_listen_thread()) 
    25212528        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  } 
    25342544} 
    25352545 
     
    26062616    int init_state; /* initial state for a new connection */ 
    26072617    socklen_t addrlen; 
    2608     struct sockaddr addr; 
     2618    struct sockaddr_storage addr; 
    26092619    int res; 
    26102620 
     
    26162626        case conn_listening: 
    26172627            addrlen = sizeof(addr); 
    2618             if ((sfd = accept(c->sfd, &addr, &addrlen)) == -1) { 
     2628            if ((sfd = accept(c->sfd, (struct sockaddr *)&addr, &addrlen)) == -1) { 
    26192629                if (errno == EAGAIN || errno == EWOULDBLOCK) { 
    26202630                    /* these are transient, so don't log anything */ 
     
    28672877} 
    28682878 
    2869 static int new_socket(const int prot) { 
     2879static int new_socket(struct addrinfo *ai) { 
    28702880    int sfd; 
    28712881    int flags; 
    28722882 
    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) { 
    28742884        perror("socket()"); 
    28752885        return -1; 
     
    29212931 
    29222932 
    2923 static int server_socket(const int port, const int prot) { 
     2933static int *server_socket(const int port, const int prot, int *count) { 
    29242934    int sfd; 
     2935    int *sfd_list; 
     2936    int *sfd_ptr; 
    29252937    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 
    29272945    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     } 
    29412946 
    29422947    /* 
     
    29442949     * that otherwise mess things up. 
    29452950     */ 
    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; 
    29623044} 
    29633045 
     
    29803062} 
    29813063 
    2982 static int server_socket_unix(const char *path, int access_mask) { 
     3064static int *server_socket_unix(const char *path, int access_mask) { 
    29833065    int sfd; 
     3066    int *sfd_list; 
    29843067    struct linger ling = {0, 0}; 
    29853068    struct sockaddr_un addr; 
     
    29893072 
    29903073    if (!path) { 
    2991         return -1
     3074        return NULL
    29923075    } 
    29933076 
    29943077    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); 
    29973091 
    29983092    /* 
     
    30203114        perror("bind()"); 
    30213115        close(sfd); 
     3116        free(sfd_list); 
    30223117        umask(old_umask); 
    3023         return -1
     3118        return NULL
    30243119    } 
    30253120    umask(old_umask); 
     
    30273122        perror("listen()"); 
    30283123        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; 
    30503131} 
    30513132 
     
    30633144/* time-sensitive callers can call it by hand with this, outside the normal ever-1-second timer */ 
    30643145static 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); 
    30663150} 
    30673151 
     
    31373221           "-M            return error on memory exhausted (rather than removing items)\n" 
    31383222           "-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" 
    31403229           "-v            verbose (print errors/warnings while in event loop)\n" 
    31413230           "-vv           very verbose (also print client commands/reponses)\n" 
     
    32583347int main (int argc, char **argv) { 
    32593348    int c; 
    3260     struct in_addr addr
     3349    int x
    32613350    bool lock_memory = false; 
    32623351    bool daemonize = false; 
     
    32673356    struct sigaction sa; 
    32683357    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; 
    32693367 
    32703368    /* handle SIGINT */ 
     
    33223420            break; 
    33233421        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); 
    33303423            break; 
    33313424        case 'd': 
     
    34313524    /* create the listening socket and bind it */ 
    34323525    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) { 
    34353528            fprintf(stderr, "failed to listen\n"); 
    34363529            exit(EXIT_FAILURE); 
     
    34383531        /* Try the binary port. */ 
    34393532        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) { 
    34423535                 fprintf(stderr, "failed to listen to binary protocol\n"); 
    34433536                    exit(EXIT_FAILURE); 
     
    34483541    if (settings.udpport > 0 && settings.socketpath == NULL) { 
    34493542        /* 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) { 
    34523545            fprintf(stderr, "failed to listen on UDP port %d\n", settings.udpport); 
    34533546            exit(EXIT_FAILURE); 
    34543547        } 
     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 
    34553561    } 
    34563562 
     
    34743580    if (settings.socketpath != NULL) { 
    34753581        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; 
    34803588    } 
    34813589 
     
    35123620        } 
    35133621        memset(buckets, 0, sizeof(int) * MAX_BUCKETS); 
    3514     } 
    3515  
    3516     /* lock paged memory if needed */ 
    3517     if (lock_memory) { 
    3518 #ifdef HAVE_MLOCKALL 
    3519         mlockall(MCL_CURRENT | MCL_FUTURE); 
    3520 #else 
    3521         fprintf(stderr, "warning: mlockall() not supported on this platform.  proceeding without.\n"); 
    3522 #endif 
    35233622    } 
    35243623 
     
    35353634    } 
    35363635    /* 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            } 
    35513669        } 
    35523670    } 
     
    35693687    delete_handler(0, 0, 0); /* sets up the event */ 
    35703688    /* create the initial listening udp connection, monitored on all threads */ 
    3571     if (u_socket > -1) { 
     3689    if (u_socket) { 
    35723690        for (c = 0; c < settings.num_threads; c++) { 
    35733691            /* 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, 
    35753693                              UDP_READ_BUFFER_SIZE, ascii_udp_prot); 
    35763694        } 
     
    35813699    if (daemonize) 
    35823700        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 
    35833709    return 0; 
    35843710} 
  • branches/binary/server/memcached.h

    r692 r717  
    1111#include <netinet/in.h> 
    1212#include <event.h> 
     13#include <netdb.h> 
    1314 
    1415#define DATA_BUFFER_SIZE 2048 
     
    127128    int udpport; 
    128129    int binport;           /* Port for binary protocol. */ 
    129     struct in_addr interf
     130    char *inter
    130131    int verbose; 
    131132    rel_time_t oldest_live; /* ignore existing items older than this */ 
     
    212213#define NREAD_CAS 6 
    213214 
    214 typedef struct { 
     215typedef struct conn conn; 
     216struct conn { 
    215217    int    sfd; 
    216218    int    state; 
     
    290292    int opaque; 
    291293    int keylen; 
    292  
    293 } conn; 
     294    conn   *next;     /* Used for generating a list of conn structures */ 
     295}; 
     296 
    294297 
    295298/* number of virtual buckets for a managed instance */ 
     
    298301/* current time of day (updated periodically) */ 
    299302extern 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 (); */ 
    304303 
    305304/* 
  • branches/binary/server/slabs.c

    r591 r717  
    2626#define POWER_LARGEST  200 
    2727#define POWER_BLOCK 1048576 
    28 #define CHUNK_ALIGN_BYTES (sizeof(void *)) 
     28#define CHUNK_ALIGN_BYTES 8 
    2929#define DONT_PREALLOC_SLABS 
    3030 
  • branches/binary/server/t/lib/MemcachedTest.pm

    r641 r717  
    143143 
    144144sub new_memcached { 
    145     my $args = shift || ""
    146     my $port = free_port(); 
     145    my ($args, $passed_port) = @_
     146    my $port = $passed_port || free_port(); 
    147147    my $udpport = free_port("udp"); 
    148148    $args .= " -p $port"; 
  • branches/binary/website/apis.bml

    r657 r717  
    1616the memcached.</p> 
    1717 
     18<p>There is also Cache::Memcached::Fast---another Perl client written in C, 
     19largely compatible with the original Cache::Memcached. Available on CPAN at <a 
     20href="http://search.cpan.org/dist/Cache-Memcached-Fast/">http://search.cpan.org/dist/Cache-Memcached-Fast/</a>.</p> 
     21 
    1822<?h1 PHP API h1?> 
    1923 
     
    3236<li><a href="http://www.deveiate.org/code/Ruby-MemCache.html">http://www.deveiate.org/code/Ruby-MemCache.html</a></li> 
    3337<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. 
    3439</ul> 
    3540 
     
    6065<ul> 
    6166<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> 
    6569</ul> 
    6670