03e76ac48fea5820b8b4fc5131fd807cd92da6f5
[m6w6/libmemcached] / libmemcached / memcached_server.c
1 /*
2 This is a partial implementation for fetching/creating memcached_server_st objects.
3 */
4 #include "common.h"
5
6 memcached_server_st *memcached_server_create(memcached_st *memc, memcached_server_st *ptr)
7 {
8 if (ptr == NULL)
9 {
10 ptr= (memcached_server_st *)calloc(1, sizeof(memcached_server_st));
11
12 if (!ptr)
13 return NULL; /* MEMCACHED_MEMORY_ALLOCATION_FAILURE */
14
15 ptr->options.is_allocated= true;
16 }
17 else
18 {
19 memset(ptr, 0, sizeof(memcached_server_st));
20 }
21
22 ptr->root= memc;
23
24 return ptr;
25 }
26
27 memcached_server_st *memcached_server_create_with(memcached_st *memc, memcached_server_st *host,
28 const char *hostname, unsigned int port,
29 uint32_t weight, memcached_connection type)
30 {
31 host= memcached_server_create(memc, host);
32
33 if (host == NULL)
34 return NULL;
35
36 strncpy(host->hostname, hostname, MEMCACHED_MAX_HOST_LENGTH - 1);
37 host->root= memc ? memc : NULL;
38 host->port= port;
39 host->weight= weight;
40 host->fd= -1;
41 host->type= type;
42 host->read_ptr= host->read_buffer;
43 if (memc)
44 host->next_retry= memc->retry_timeout;
45 if (type == MEMCACHED_CONNECTION_UDP)
46 {
47 host->write_buffer_offset= UDP_DATAGRAM_HEADER_LENGTH;
48 memcached_io_init_udp_header(host, 0);
49 }
50
51 return host;
52 }
53
54 void memcached_server_free(memcached_server_st *ptr)
55 {
56 memcached_quit_server(ptr, 0);
57
58 if (ptr->cached_server_error)
59 free(ptr->cached_server_error);
60
61 if (ptr->address_info)
62 freeaddrinfo(ptr->address_info);
63
64
65 if (memcached_is_allocated(ptr))
66 {
67 ptr->root->call_free(ptr->root, ptr);
68 }
69 else
70 {
71 memset(ptr, 0, sizeof(memcached_server_st));
72 }
73 }
74
75 /*
76 If we do not have a valid object to clone from, we toss an error.
77 */
78 memcached_server_st *memcached_server_clone(memcached_server_st *clone, memcached_server_st *ptr)
79 {
80 memcached_server_st *rv= NULL;
81
82 /* We just do a normal create if ptr is missing */
83 if (ptr == NULL)
84 return NULL;
85
86 rv = memcached_server_create_with(ptr->root, clone,
87 ptr->hostname, ptr->port, ptr->weight,
88 ptr->type);
89 if (rv != NULL)
90 {
91 rv->cached_errno= ptr->cached_errno;
92 if (ptr->cached_server_error)
93 rv->cached_server_error= strdup(ptr->cached_server_error);
94 }
95
96 return rv;
97
98 }
99
100 memcached_return memcached_server_cursor(memcached_st *ptr,
101 memcached_server_function *callback,
102 void *context,
103 unsigned int number_of_callbacks)
104 {
105 unsigned int y;
106
107 for (y= 0; y < ptr->number_of_hosts; y++)
108 {
109 unsigned int x;
110
111 for (x= 0; x < number_of_callbacks; x++)
112 {
113 unsigned int iferror;
114
115 iferror= (*callback[x])(ptr, &ptr->hosts[y], context);
116
117 if (iferror)
118 continue;
119 }
120 }
121
122 return MEMCACHED_SUCCESS;
123 }
124
125 memcached_server_st *memcached_server_by_key(memcached_st *ptr, const char *key, size_t key_length, memcached_return *error)
126 {
127 uint32_t server_key;
128
129 *error= memcached_validate_key_length(key_length,
130 ptr->flags.binary_protocol);
131 unlikely (*error != MEMCACHED_SUCCESS)
132 return NULL;
133
134 unlikely (ptr->number_of_hosts == 0)
135 {
136 *error= MEMCACHED_NO_SERVERS;
137 return NULL;
138 }
139
140 if (ptr->flags.verify_key && (memcached_key_test((const char **)&key, &key_length, 1) == MEMCACHED_BAD_KEY_PROVIDED))
141 {
142 *error= MEMCACHED_BAD_KEY_PROVIDED;
143 return NULL;
144 }
145
146 server_key= memcached_generate_hash(ptr, key, key_length);
147
148 return memcached_server_clone(NULL, &ptr->hosts[server_key]);
149
150 }
151
152 const char *memcached_server_error(memcached_server_st *ptr)
153 {
154 if (ptr)
155 return ptr->cached_server_error;
156 else
157 return NULL;
158 }
159
160 void memcached_server_error_reset(memcached_server_st *ptr)
161 {
162 ptr->cached_server_error[0]= 0;
163 }
164
165 memcached_server_st *memcached_server_get_last_disconnect(memcached_st *ptr)
166 {
167 return ptr->last_disconnected_server;
168 }