diff options
author | Sree Harsha Totakura <totakura@in.tum.de> | 2012-04-27 22:41:10 +0000 |
---|---|---|
committer | Sree Harsha Totakura <totakura@in.tum.de> | 2012-04-27 22:41:10 +0000 |
commit | fe92967f50a918352370fb95c6bc0f6d2a5eb6c2 (patch) | |
tree | 643896abb72ca1fbb933c8db7946909547289f26 /src/lockmanager | |
parent | 487c280270c1e8f6d22cb77b651da000d2a53724 (diff) | |
download | gnunet-fe92967f50a918352370fb95c6bc0f6d2a5eb6c2.tar.gz gnunet-fe92967f50a918352370fb95c6bc0f6d2a5eb6c2.zip |
-hashmap for storing lockingrequests in lockmanager
Diffstat (limited to 'src/lockmanager')
-rw-r--r-- | src/lockmanager/lockmanager_api.c | 138 | ||||
-rw-r--r-- | src/lockmanager/test_lockmanager_api.c | 101 |
2 files changed, 194 insertions, 45 deletions
diff --git a/src/lockmanager/lockmanager_api.c b/src/lockmanager/lockmanager_api.c index bfd06275c..7e20e27de 100644 --- a/src/lockmanager/lockmanager_api.c +++ b/src/lockmanager/lockmanager_api.c | |||
@@ -26,9 +26,11 @@ | |||
26 | 26 | ||
27 | #include "platform.h" | 27 | #include "platform.h" |
28 | #include "gnunet_common.h" | 28 | #include "gnunet_common.h" |
29 | #include "gnunet_protocols.h" | 29 | #include "gnunet_container_lib.h" |
30 | #include "gnunet_client_lib.h" | 30 | #include "gnunet_client_lib.h" |
31 | #include "gnunet_crypto_lib.h" | ||
31 | #include "gnunet_lockmanager_service.h" | 32 | #include "gnunet_lockmanager_service.h" |
33 | #include "gnunet_protocols.h" | ||
32 | 34 | ||
33 | #include "lockmanager.h" | 35 | #include "lockmanager.h" |
34 | 36 | ||
@@ -49,6 +51,11 @@ struct GNUNET_LOCKMANAGER_Handle | |||
49 | * The client connection to the service | 51 | * The client connection to the service |
50 | */ | 52 | */ |
51 | struct GNUNET_CLIENT_Connection *conn; | 53 | struct GNUNET_CLIENT_Connection *conn; |
54 | |||
55 | /** | ||
56 | * Hashmap handle | ||
57 | */ | ||
58 | struct GNUNET_CONTAINER_MultiHashMap *hashmap; | ||
52 | }; | 59 | }; |
53 | 60 | ||
54 | 61 | ||
@@ -100,16 +107,18 @@ struct GNUNET_LOCKMANAGER_LockingRequest | |||
100 | 107 | ||
101 | 108 | ||
102 | /** | 109 | /** |
103 | * Message handler for SUCCESS messages | 110 | * Handler for server replies |
104 | * | 111 | * |
105 | * @param cls the LOCKMANAGER_Handle | 112 | * @param cls the LOCKMANAGER_Handle |
106 | * @param msg message received, NULL on timeout or fatal error | 113 | * @param msg received message, NULL on timeout or fatal error |
107 | */ | 114 | */ |
108 | static void | 115 | static void |
109 | handle_success (void *cls, | 116 | handle_replies (void *cls, |
110 | const struct GNUNET_MessageHeader *msg) | 117 | const struct GNUNET_MessageHeader *msg) |
111 | { | 118 | { |
112 | if (NULL == msg) | 119 | if (NULL == msg) |
120 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
121 | "Lockmanager service not available or went down\n"); | ||
113 | return; | 122 | return; |
114 | 123 | ||
115 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 124 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
@@ -118,24 +127,6 @@ handle_success (void *cls, | |||
118 | 127 | ||
119 | 128 | ||
120 | /** | 129 | /** |
121 | * We wait for DUMMY message which will never be sent by the server. However, | ||
122 | * in case the server shuts-down/crashes/restarts we are notified by this call | ||
123 | * back with a NULL for msg. | ||
124 | * | ||
125 | * @param cls closure | ||
126 | * @param msg message received, NULL on timeout or fatal error | ||
127 | */ | ||
128 | static void | ||
129 | handle_server_crash (void *cls, | ||
130 | const struct GNUNET_MessageHeader *msg) | ||
131 | { | ||
132 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
133 | "Lockmanager service not available or went down\n"); | ||
134 | |||
135 | } | ||
136 | |||
137 | |||
138 | /** | ||
139 | * Transmit notify for sending message to server | 130 | * Transmit notify for sending message to server |
140 | * | 131 | * |
141 | * @param cls the message to send | 132 | * @param cls the message to send |
@@ -158,10 +149,65 @@ transmit_notify (void *cls, size_t size, void *buf) | |||
158 | GNUNET_assert (size >= msg_size); | 149 | GNUNET_assert (size >= msg_size); |
159 | memcpy (buf, msg, msg_size); | 150 | memcpy (buf, msg, msg_size); |
160 | GNUNET_free (msg); | 151 | GNUNET_free (msg); |
152 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
153 | "Message of size %u sent\n", msg_size); | ||
161 | return msg_size; | 154 | return msg_size; |
162 | } | 155 | } |
163 | 156 | ||
164 | 157 | ||
158 | /** | ||
159 | * Iterator to free hash map entries. | ||
160 | * | ||
161 | * @param cls NULL | ||
162 | * @param key current key code | ||
163 | * @param value value in the hash map | ||
164 | * @return GNUNET_YES if we should continue to | ||
165 | * iterate, | ||
166 | * GNUNET_NO if not. | ||
167 | */ | ||
168 | static int | ||
169 | free_iterator(void *cls, | ||
170 | const GNUNET_HashCode * key, | ||
171 | void *value) | ||
172 | { | ||
173 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
174 | "Clearing locking request\n"); | ||
175 | GNUNET_free (value); | ||
176 | return GNUNET_YES; | ||
177 | } | ||
178 | |||
179 | |||
180 | /** | ||
181 | * Generate hash with domain name and the lock | ||
182 | * | ||
183 | * @param domain NULL terminated domain name | ||
184 | * | ||
185 | * @param domain_length the length of the domain name including the terminating | ||
186 | * NULL if already known; 0 to calculate | ||
187 | * | ||
188 | * @param lock the lock number | ||
189 | * @param where to write the generated hash | ||
190 | */ | ||
191 | static void | ||
192 | hash_domain_and_lock (const char *domain, | ||
193 | uint16_t domain_length, | ||
194 | uint32_t lock, | ||
195 | GNUNET_HashCode *ret) | ||
196 | { | ||
197 | unsigned int str_len; | ||
198 | uint32_t *block; | ||
199 | size_t block_size; | ||
200 | |||
201 | str_len = (0 == domain_length) ? strlen (domain) : domain_length - 1; | ||
202 | block_size = sizeof (uint32_t) + str_len; | ||
203 | block = GNUNET_malloc (block_size); | ||
204 | /* Copy data */ | ||
205 | *block = lock; | ||
206 | memcpy (&block[1], domain, str_len); | ||
207 | |||
208 | GNUNET_CRYPTO_hash (block, block_size, ret); | ||
209 | GNUNET_free (block); | ||
210 | } | ||
165 | 211 | ||
166 | /*******************/ | 212 | /*******************/ |
167 | /* API Definitions */ | 213 | /* API Definitions */ |
@@ -189,17 +235,14 @@ GNUNET_LOCKMANAGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
189 | return NULL; | 235 | return NULL; |
190 | } | 236 | } |
191 | 237 | ||
238 | h->hashmap = GNUNET_CONTAINER_multihashmap_create (15); | ||
239 | GNUNET_assert (NULL != h->hashmap); | ||
240 | |||
192 | GNUNET_CLIENT_receive (h->conn, | 241 | GNUNET_CLIENT_receive (h->conn, |
193 | &handle_server_crash, | 242 | &handle_replies, |
194 | NULL, | 243 | NULL, |
195 | GNUNET_TIME_UNIT_FOREVER_REL); | 244 | GNUNET_TIME_UNIT_FOREVER_REL); |
196 | 245 | ||
197 | /* FIXME: Assertions fail in client.c if trying to receive multiple messages */ | ||
198 | /* GNUNET_CLIENT_receive (h->conn, */ | ||
199 | /* &handle_success, */ | ||
200 | /* h, */ | ||
201 | /* GNUNET_TIME_UNIT_FOREVER_REL); */ | ||
202 | |||
203 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); | 246 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); |
204 | return h; | 247 | return h; |
205 | } | 248 | } |
@@ -215,6 +258,18 @@ GNUNET_LOCKMANAGER_disconnect (struct GNUNET_LOCKMANAGER_Handle *handle) | |||
215 | { | 258 | { |
216 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); | 259 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); |
217 | GNUNET_CLIENT_disconnect (handle->conn); | 260 | GNUNET_CLIENT_disconnect (handle->conn); |
261 | |||
262 | if (0 != GNUNET_CONTAINER_multihashmap_size (handle->hashmap)) | ||
263 | { | ||
264 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
265 | "Some locking requests are still present. Cancel them before " | ||
266 | "calling %s\n", __func__); | ||
267 | GNUNET_CONTAINER_multihashmap_iterate (handle->hashmap, | ||
268 | &free_iterator, | ||
269 | NULL); | ||
270 | } | ||
271 | GNUNET_CONTAINER_multihashmap_destroy (handle->hashmap); | ||
272 | |||
218 | GNUNET_free (handle); | 273 | GNUNET_free (handle); |
219 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); | 274 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); |
220 | } | 275 | } |
@@ -254,6 +309,7 @@ GNUNET_LOCKMANAGER_acquire_lock (struct GNUNET_LOCKMANAGER_Handle *handle, | |||
254 | { | 309 | { |
255 | struct GNUNET_LOCKMANAGER_LockingRequest *r; | 310 | struct GNUNET_LOCKMANAGER_LockingRequest *r; |
256 | struct GNUNET_LOCKMANAGER_Message *msg; | 311 | struct GNUNET_LOCKMANAGER_Message *msg; |
312 | struct GNUNET_HashCode hash; | ||
257 | uint16_t msg_size; | 313 | uint16_t msg_size; |
258 | 314 | ||
259 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); | 315 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); |
@@ -271,6 +327,7 @@ GNUNET_LOCKMANAGER_acquire_lock (struct GNUNET_LOCKMANAGER_Handle *handle, | |||
271 | msg->lock = htonl (lock); | 327 | msg->lock = htonl (lock); |
272 | memcpy (&msg[1], r->domain, r->domain_name_length); | 328 | memcpy (&msg[1], r->domain, r->domain_name_length); |
273 | 329 | ||
330 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Queueing ACQUIRE message\n"); | ||
274 | r->transmit_handle = | 331 | r->transmit_handle = |
275 | GNUNET_CLIENT_notify_transmit_ready (r->handle->conn, | 332 | GNUNET_CLIENT_notify_transmit_ready (r->handle->conn, |
276 | msg_size, | 333 | msg_size, |
@@ -278,6 +335,15 @@ GNUNET_LOCKMANAGER_acquire_lock (struct GNUNET_LOCKMANAGER_Handle *handle, | |||
278 | GNUNET_NO, | 335 | GNUNET_NO, |
279 | *transmit_notify, | 336 | *transmit_notify, |
280 | msg); | 337 | msg); |
338 | hash_domain_and_lock (r->domain, | ||
339 | r->domain_name_length, | ||
340 | r->lock, | ||
341 | &hash); | ||
342 | GNUNET_CONTAINER_multihashmap_put (r->handle->hashmap, | ||
343 | &hash, | ||
344 | r, | ||
345 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
346 | |||
281 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); | 347 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); |
282 | return r; | 348 | return r; |
283 | } | 349 | } |
@@ -296,6 +362,8 @@ void | |||
296 | GNUNET_LOCKMANAGER_cancel_request (struct GNUNET_LOCKMANAGER_LockingRequest | 362 | GNUNET_LOCKMANAGER_cancel_request (struct GNUNET_LOCKMANAGER_LockingRequest |
297 | *request) | 363 | *request) |
298 | { | 364 | { |
365 | struct GNUNET_HashCode hash; | ||
366 | |||
299 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); | 367 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); |
300 | /* FIXME: Stop ACQUIRE retransmissions */ | 368 | /* FIXME: Stop ACQUIRE retransmissions */ |
301 | if (GNUNET_LOCKMANAGER_SUCCESS == request->status) | 369 | if (GNUNET_LOCKMANAGER_SUCCESS == request->status) |
@@ -318,6 +386,16 @@ GNUNET_LOCKMANAGER_cancel_request (struct GNUNET_LOCKMANAGER_LockingRequest | |||
318 | &transmit_notify, | 386 | &transmit_notify, |
319 | msg); | 387 | msg); |
320 | } | 388 | } |
321 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); | 389 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); |
390 | |||
391 | hash_domain_and_lock (request->domain, | ||
392 | request->domain_name_length, | ||
393 | request->lock, | ||
394 | &hash); | ||
395 | |||
396 | GNUNET_assert (GNUNET_YES == | ||
397 | GNUNET_CONTAINER_multihashmap_remove | ||
398 | (request->handle->hashmap, &hash, request)); | ||
399 | |||
322 | GNUNET_free (request); | 400 | GNUNET_free (request); |
323 | } | 401 | } |
diff --git a/src/lockmanager/test_lockmanager_api.c b/src/lockmanager/test_lockmanager_api.c index 144f7b43c..9137768e8 100644 --- a/src/lockmanager/test_lockmanager_api.c +++ b/src/lockmanager/test_lockmanager_api.c | |||
@@ -51,22 +51,32 @@ static struct GNUNET_OS_Process *arm_pid = NULL; | |||
51 | /** | 51 | /** |
52 | * Configuration Handle | 52 | * Configuration Handle |
53 | */ | 53 | */ |
54 | struct GNUNET_CONFIGURATION_Handle *config; | 54 | static struct GNUNET_CONFIGURATION_Handle *config; |
55 | 55 | ||
56 | /** | 56 | /** |
57 | * Testing function | 57 | * The handle to the lockmanager service |
58 | */ | ||
59 | static struct GNUNET_LOCKMANAGER_Handle *handle; | ||
60 | |||
61 | /** | ||
62 | * The locking request | ||
63 | */ | ||
64 | static struct GNUNET_LOCKMANAGER_LockingRequest *request; | ||
65 | |||
66 | /** | ||
67 | * Shutdown nicely | ||
58 | * | 68 | * |
59 | * @param cls NULL | 69 | * @param cls |
60 | * @param tc the task context | 70 | * @param tc the task context |
61 | */ | 71 | */ |
62 | static void | 72 | static void |
63 | test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 73 | do_shutdown (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc) |
64 | { | 74 | { |
65 | struct GNUNET_LOCKMANAGER_Handle *handle; | 75 | if (NULL != request) |
66 | 76 | { | |
67 | handle = GNUNET_LOCKMANAGER_connect (config); | 77 | GNUNET_LOCKMANAGER_cancel_request (request); |
68 | GNUNET_assert (NULL != handle); | 78 | request = NULL; |
69 | 79 | } | |
70 | GNUNET_LOCKMANAGER_disconnect (handle); | 80 | GNUNET_LOCKMANAGER_disconnect (handle); |
71 | if (0 != GNUNET_OS_process_kill (arm_pid, SIGTERM)) | 81 | if (0 != GNUNET_OS_process_kill (arm_pid, SIGTERM)) |
72 | { | 82 | { |
@@ -75,7 +85,68 @@ test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
75 | } | 85 | } |
76 | GNUNET_OS_process_wait (arm_pid); | 86 | GNUNET_OS_process_wait (arm_pid); |
77 | GNUNET_OS_process_close (arm_pid); | 87 | GNUNET_OS_process_close (arm_pid); |
78 | result = GNUNET_OK; | 88 | if (GNUNET_SYSERR != result) |
89 | result = GNUNET_OK; | ||
90 | } | ||
91 | |||
92 | |||
93 | /** | ||
94 | * Shutdown nicely | ||
95 | * | ||
96 | * @param cls | ||
97 | * @param tc the task context | ||
98 | */ | ||
99 | static void | ||
100 | do_abort (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
101 | { | ||
102 | result = GNUNET_SYSERR; | ||
103 | do_shutdown (cls, tc); | ||
104 | } | ||
105 | |||
106 | /** | ||
107 | * Callback for lock status changes | ||
108 | * | ||
109 | * @param cls the closure from GNUNET_LOCKMANAGER_lock call | ||
110 | * | ||
111 | * @param domain_name the locking domain of the lock | ||
112 | * | ||
113 | * @param lock the lock for which this status is relevant | ||
114 | * | ||
115 | * @param status GNUNET_LOCKMANAGER_SUCCESS if the lock has been successfully | ||
116 | * acquired; GNUNET_LOCKMANAGER_RELEASE when the acquired lock is lost | ||
117 | */ | ||
118 | static void | ||
119 | status_cb (void *cls, | ||
120 | const char *domain_name, | ||
121 | uint32_t lock, | ||
122 | enum GNUNET_LOCKMANAGER_Status status) | ||
123 | { | ||
124 | GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (1), | ||
125 | &do_shutdown, | ||
126 | NULL); | ||
127 | } | ||
128 | |||
129 | |||
130 | /** | ||
131 | * Testing function | ||
132 | * | ||
133 | * @param cls NULL | ||
134 | * @param tc the task context | ||
135 | */ | ||
136 | static void | ||
137 | test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
138 | { | ||
139 | handle = GNUNET_LOCKMANAGER_connect (config); | ||
140 | GNUNET_assert (NULL != handle); | ||
141 | |||
142 | request = GNUNET_LOCKMANAGER_acquire_lock (handle, | ||
143 | "GNUNET_LOCKMANAGER_TESTING", | ||
144 | 99, | ||
145 | &status_cb, | ||
146 | NULL); | ||
147 | GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (10), | ||
148 | &do_abort, | ||
149 | NULL); | ||
79 | } | 150 | } |
80 | 151 | ||
81 | 152 | ||
@@ -127,15 +198,15 @@ int main (int argc, char **argv) | |||
127 | 198 | ||
128 | if (GNUNET_OK != ret) | 199 | if (GNUNET_OK != ret) |
129 | { | 200 | { |
130 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "run failed with error code %d\n", | 201 | LOG (GNUNET_ERROR_TYPE_WARNING, "run failed with error code %d\n", |
131 | ret); | 202 | ret); |
132 | return 1; | 203 | return 1; |
133 | } | 204 | } |
134 | if (GNUNET_SYSERR == result) | 205 | if (GNUNET_SYSERR == result) |
135 | { | 206 | { |
136 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "test failed\n"); | 207 | LOG (GNUNET_ERROR_TYPE_WARNING, "test failed\n"); |
137 | return 1; | 208 | return 1; |
138 | } | 209 | } |
139 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "test ok\n"); | 210 | LOG (GNUNET_ERROR_TYPE_INFO, "test ok\n"); |
140 | return 0; | 211 | return 0; |
141 | } | 212 | } |