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