Updating server_st to keep client buffers per server.
[awesomized/libmemcached] / lib / memcached_hosts.c
1 #include <memcached.h>
2 #include "common.h"
3
4 /* Protoypes (static) */
5 static memcached_return server_add(memcached_st *ptr, char *hostname,
6 unsigned int port,
7 memcached_connection type);
8
9 static void host_reset(memcached_server_st *host, char *new_hostname, unsigned int port,
10 memcached_connection type)
11 {
12 host->stack_responses= 0;
13 host->cursor_active= 0;
14 host->hostname= new_hostname;
15 host->port= port;
16 host->fd= -1;
17 host->type= type;
18 host->write_buffer_offset= 0;
19 host->read_buffer_length= 0;
20 host->read_ptr= host->read_buffer;
21 }
22
23 memcached_return memcached_server_push(memcached_st *ptr, memcached_server_st *list)
24 {
25 unsigned int x;
26 unsigned int count;
27 memcached_server_st *new_host_list;
28
29 if (!list)
30 return MEMCACHED_SUCCESS;
31
32 for (count= 0; list[count].hostname; count++);
33
34 new_host_list=
35 (memcached_server_st *)realloc(ptr->hosts,
36 sizeof(memcached_server_st) * (count + ptr->number_of_hosts + 1));
37
38 if (!new_host_list)
39 return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
40
41 ptr->hosts= new_host_list;
42
43 for (x= 0; list[x].hostname; x++)
44 {
45 ptr->hosts[ptr->number_of_hosts].hostname= strdup(list[x].hostname);
46 ptr->hosts[ptr->number_of_hosts].port= list[x].port;
47 ptr->hosts[ptr->number_of_hosts].fd= list[x].fd;
48 ptr->hosts[ptr->number_of_hosts].stack_responses= list[x].stack_responses;
49 ptr->hosts[ptr->number_of_hosts].cursor_active= list[x].cursor_active;
50 ptr->hosts[ptr->number_of_hosts].type= list[x].type;
51 ptr->number_of_hosts++;
52 }
53 host_reset(&ptr->hosts[ptr->number_of_hosts], NULL, 0,
54 MEMCACHED_CONNECTION_UNKNOWN);
55
56 return MEMCACHED_SUCCESS;
57 }
58
59 memcached_return memcached_server_add_unix_socket(memcached_st *ptr, char *filename)
60 {
61 if (!filename)
62 return MEMCACHED_FAILURE;
63
64 return server_add(ptr, filename, 0, MEMCACHED_CONNECTION_UNIX_SOCKET);
65 }
66
67 memcached_return memcached_server_add(memcached_st *ptr, char *hostname, unsigned int port)
68 {
69 if (!port)
70 port= MEMCACHED_DEFAULT_PORT;
71
72 if (!hostname)
73 hostname= "localhost";
74
75 return server_add(ptr, hostname, port, MEMCACHED_CONNECTION_TCP);
76 }
77
78 static memcached_return server_add(memcached_st *ptr, char *hostname,
79 unsigned int port,
80 memcached_connection type)
81 {
82 memcached_server_st *new_host_list;
83 char *new_hostname;
84 LIBMEMCACHED_MEMCACHED_SERVER_ADD_START();
85
86
87 if (ptr->number_of_hosts)
88 {
89 new_host_list= (memcached_server_st *)realloc(ptr->hosts,
90 sizeof(memcached_server_st) * (ptr->number_of_hosts+1));
91 if (!new_host_list)
92 return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
93 host_reset(&new_host_list[ptr->number_of_hosts], NULL, 0,
94 MEMCACHED_CONNECTION_UNKNOWN);
95 }
96 else
97 {
98 new_host_list=
99 (memcached_server_st *)malloc(sizeof(memcached_server_st) * 2);
100 if (!new_host_list)
101 return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
102 host_reset(&new_host_list[0], NULL, 0, MEMCACHED_CONNECTION_UNKNOWN);
103 host_reset(&new_host_list[1], NULL, 0, MEMCACHED_CONNECTION_UNKNOWN);
104 }
105
106 ptr->hosts= new_host_list;
107
108 new_hostname=
109 (char *)malloc(sizeof(char) * (strlen(hostname)+1));
110
111 if (!new_hostname)
112 return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
113
114 memset(new_hostname, 0, strlen(hostname)+1);
115 memcpy(new_hostname, hostname, strlen(hostname));
116 host_reset(&ptr->hosts[ptr->number_of_hosts], new_hostname, port, type);
117 ptr->number_of_hosts++;
118
119 LIBMEMCACHED_MEMCACHED_SERVER_ADD_END();
120
121 return MEMCACHED_SUCCESS;
122 }
123
124 memcached_server_st *memcached_server_list_append(memcached_server_st *ptr,
125 char *hostname, unsigned int port,
126 memcached_return *error)
127 {
128 unsigned int count;
129 memcached_server_st *new_host_list;
130 char *new_hostname;
131
132 if (!hostname)
133 return ptr;
134
135 if (!port)
136 port= MEMCACHED_DEFAULT_PORT;
137
138 /* Always count so that we keep a free host at the end */
139 if (ptr)
140 {
141 for (count= 0; ptr[count].hostname; count++);
142 count+= 2;
143 new_host_list= (memcached_server_st *)realloc(ptr, sizeof(memcached_server_st) * count);
144 if (!new_host_list)
145 goto error;
146 host_reset(&new_host_list[count-1], NULL, 0, MEMCACHED_CONNECTION_UNKNOWN);
147 }
148 else
149 {
150 count= 2;
151 new_host_list= (memcached_server_st *)malloc(sizeof(memcached_server_st) * count);
152 if (!new_host_list)
153 goto error;
154 host_reset(&new_host_list[0], NULL, 0, MEMCACHED_CONNECTION_UNKNOWN);
155 host_reset(&new_host_list[1], NULL, 0, MEMCACHED_CONNECTION_UNKNOWN);
156 }
157
158 new_hostname= strdup(hostname);
159
160 if (!new_hostname)
161 goto error;
162
163 host_reset(&new_host_list[count-2], new_hostname, port, MEMCACHED_CONNECTION_TCP);
164
165 *error= MEMCACHED_SUCCESS;
166 return new_host_list;
167 error:
168 *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
169
170 return NULL;
171 }
172
173 unsigned int memcached_server_list_count(memcached_server_st *ptr)
174 {
175 unsigned int x;
176
177 for (x= 0; ptr[x].hostname; x++);
178
179 return x;
180 }
181
182 void memcached_server_list_free(memcached_server_st *ptr)
183 {
184 unsigned int x;
185
186 for (x= 0; ptr[x].hostname; x++)
187 free(ptr[x].hostname);
188
189 free(ptr);
190 }