| 1 | /* |
|---|
| 2 | Memcached library |
|---|
| 3 | */ |
|---|
| 4 | #include "common.h" |
|---|
| 5 | |
|---|
| 6 | memcached_st *memcached_create(memcached_st *ptr) |
|---|
| 7 | { |
|---|
| 8 | memcached_result_st *result_ptr; |
|---|
| 9 | #ifdef _WIN32 |
|---|
| 10 | WSADATA wsaData; |
|---|
| 11 | WSAStartup(MAKEWORD(2, 0), &wsaData); |
|---|
| 12 | #endif |
|---|
| 13 | |
|---|
| 14 | if (ptr == NULL) |
|---|
| 15 | { |
|---|
| 16 | ptr= (memcached_st *)malloc(sizeof(memcached_st)); |
|---|
| 17 | |
|---|
| 18 | if (!ptr) |
|---|
| 19 | return NULL; /* MEMCACHED_MEMORY_ALLOCATION_FAILURE */ |
|---|
| 20 | |
|---|
| 21 | memset(ptr, 0, sizeof(memcached_st)); |
|---|
| 22 | ptr->is_allocated= MEMCACHED_ALLOCATED; |
|---|
| 23 | } |
|---|
| 24 | else |
|---|
| 25 | { |
|---|
| 26 | memset(ptr, 0, sizeof(memcached_st)); |
|---|
| 27 | } |
|---|
| 28 | result_ptr= memcached_result_create(ptr, &ptr->result); |
|---|
| 29 | WATCHPOINT_ASSERT(result_ptr); |
|---|
| 30 | ptr->poll_timeout= MEMCACHED_DEFAULT_TIMEOUT; |
|---|
| 31 | ptr->connect_timeout= MEMCACHED_DEFAULT_TIMEOUT; |
|---|
| 32 | ptr->retry_timeout= 0; |
|---|
| 33 | ptr->distribution= MEMCACHED_DISTRIBUTION_MODULA; |
|---|
| 34 | |
|---|
| 35 | ptr->io_msg_watermark = 500; |
|---|
| 36 | ptr->io_bytes_watermark = 65 * 1024; |
|---|
| 37 | |
|---|
| 38 | return ptr; |
|---|
| 39 | } |
|---|
| 40 | |
|---|
| 41 | void memcached_free(memcached_st *ptr) |
|---|
| 42 | { |
|---|
| 43 | if (!ptr) return; |
|---|
| 44 | |
|---|
| 45 | /* If we have anything open, lets close it now */ |
|---|
| 46 | memcached_quit(ptr); |
|---|
| 47 | server_list_free(ptr, ptr->hosts); |
|---|
| 48 | memcached_result_free(&ptr->result); |
|---|
| 49 | |
|---|
| 50 | if (ptr->on_cleanup) |
|---|
| 51 | ptr->on_cleanup(ptr); |
|---|
| 52 | |
|---|
| 53 | if (ptr->continuum) |
|---|
| 54 | { |
|---|
| 55 | if (ptr->call_free) |
|---|
| 56 | ptr->call_free(ptr, ptr->continuum); |
|---|
| 57 | else |
|---|
| 58 | free(ptr->continuum); |
|---|
| 59 | } |
|---|
| 60 | |
|---|
| 61 | if (ptr->is_allocated == MEMCACHED_ALLOCATED) |
|---|
| 62 | { |
|---|
| 63 | if (ptr->call_free) |
|---|
| 64 | ptr->call_free(ptr, ptr); |
|---|
| 65 | else |
|---|
| 66 | free(ptr); |
|---|
| 67 | } |
|---|
| 68 | else |
|---|
| 69 | ptr->is_allocated= MEMCACHED_USED; |
|---|
| 70 | } |
|---|
| 71 | |
|---|
| 72 | /* |
|---|
| 73 | clone is the destination, while source is the structure to clone. |
|---|
| 74 | If source is NULL the call is the same as if a memcached_create() was |
|---|
| 75 | called. |
|---|
| 76 | */ |
|---|
| 77 | memcached_st *memcached_clone(memcached_st *clone, memcached_st *source) |
|---|
| 78 | { |
|---|
| 79 | memcached_return rc= MEMCACHED_SUCCESS; |
|---|
| 80 | memcached_st *new_clone; |
|---|
| 81 | |
|---|
| 82 | if (source == NULL) |
|---|
| 83 | return memcached_create(clone); |
|---|
| 84 | |
|---|
| 85 | if (clone && clone->is_allocated == MEMCACHED_USED) |
|---|
| 86 | { |
|---|
| 87 | return NULL; |
|---|
| 88 | } |
|---|
| 89 | |
|---|
| 90 | new_clone= memcached_create(clone); |
|---|
| 91 | |
|---|
| 92 | if (new_clone == NULL) |
|---|
| 93 | return NULL; |
|---|
| 94 | |
|---|
| 95 | if (source->hosts) |
|---|
| 96 | rc= memcached_server_push(new_clone, source->hosts); |
|---|
| 97 | |
|---|
| 98 | if (rc != MEMCACHED_SUCCESS) |
|---|
| 99 | { |
|---|
| 100 | memcached_free(new_clone); |
|---|
| 101 | |
|---|
| 102 | return NULL; |
|---|
| 103 | } |
|---|
| 104 | |
|---|
| 105 | |
|---|
| 106 | new_clone->flags= source->flags; |
|---|
| 107 | new_clone->send_size= source->send_size; |
|---|
| 108 | new_clone->recv_size= source->recv_size; |
|---|
| 109 | new_clone->poll_timeout= source->poll_timeout; |
|---|
| 110 | new_clone->connect_timeout= source->connect_timeout; |
|---|
| 111 | new_clone->retry_timeout= source->retry_timeout; |
|---|
| 112 | new_clone->distribution= source->distribution; |
|---|
| 113 | new_clone->hash= source->hash; |
|---|
| 114 | new_clone->hash_continuum= source->hash_continuum; |
|---|
| 115 | new_clone->user_data= source->user_data; |
|---|
| 116 | |
|---|
| 117 | new_clone->snd_timeout= source->snd_timeout; |
|---|
| 118 | new_clone->rcv_timeout= source->rcv_timeout; |
|---|
| 119 | |
|---|
| 120 | new_clone->on_clone= source->on_clone; |
|---|
| 121 | new_clone->on_cleanup= source->on_cleanup; |
|---|
| 122 | new_clone->call_free= source->call_free; |
|---|
| 123 | new_clone->call_malloc= source->call_malloc; |
|---|
| 124 | new_clone->call_realloc= source->call_realloc; |
|---|
| 125 | new_clone->get_key_failure= source->get_key_failure; |
|---|
| 126 | new_clone->delete_trigger= source->delete_trigger; |
|---|
| 127 | |
|---|
| 128 | if (source->prefix_key[0] != 0) |
|---|
| 129 | { |
|---|
| 130 | strcpy(new_clone->prefix_key, source->prefix_key); |
|---|
| 131 | new_clone->prefix_key_length= source->prefix_key_length; |
|---|
| 132 | } |
|---|
| 133 | |
|---|
| 134 | rc= run_distribution(new_clone); |
|---|
| 135 | if (rc != MEMCACHED_SUCCESS) |
|---|
| 136 | { |
|---|
| 137 | memcached_free(new_clone); |
|---|
| 138 | |
|---|
| 139 | return NULL; |
|---|
| 140 | } |
|---|
| 141 | |
|---|
| 142 | if (source->on_clone) |
|---|
| 143 | source->on_clone(source, new_clone); |
|---|
| 144 | |
|---|
| 145 | return new_clone; |
|---|
| 146 | } |
|---|