diff options
author | Sree Harsha Totakura <totakura@in.tum.de> | 2012-05-13 17:21:18 +0000 |
---|---|---|
committer | Sree Harsha Totakura <totakura@in.tum.de> | 2012-05-13 17:21:18 +0000 |
commit | fc73a3da5ded1ff8488d7e13ab4ae4a1d0680f96 (patch) | |
tree | 61d50f96a1f1f0c329d22727bfe80d77d8ab874d /src/lockmanager | |
parent | 761e32ca4ffae07d145081c8273eb68fb505194b (diff) | |
download | gnunet-fc73a3da5ded1ff8488d7e13ab4ae4a1d0680f96.tar.gz gnunet-fc73a3da5ded1ff8488d7e13ab4ae4a1d0680f96.zip |
clean shutdown in lockmanager, test case for lock release and message format checks for incoming msg in lockmanager API
Diffstat (limited to 'src/lockmanager')
-rw-r--r-- | src/lockmanager/Makefile.am | 9 | ||||
-rw-r--r-- | src/lockmanager/gnunet-service-lockmanager.c | 75 | ||||
-rw-r--r-- | src/lockmanager/lockmanager_api.c | 282 | ||||
-rw-r--r-- | src/lockmanager/test_lockmanager_api.conf | 2 | ||||
-rw-r--r-- | src/lockmanager/test_lockmanager_api_lockrelease.c | 301 |
5 files changed, 507 insertions, 162 deletions
diff --git a/src/lockmanager/Makefile.am b/src/lockmanager/Makefile.am index f86ac72a5..ee6f816f1 100644 --- a/src/lockmanager/Makefile.am +++ b/src/lockmanager/Makefile.am | |||
@@ -38,7 +38,8 @@ libgnunetlockmanager_la_LDFLAGS = \ | |||
38 | -version-info 0:0:0 | 38 | -version-info 0:0:0 |
39 | 39 | ||
40 | check_PROGRAMS = \ | 40 | check_PROGRAMS = \ |
41 | test-lockmanager-api | 41 | test-lockmanager-api \ |
42 | test-lockmanager-api-lockrelease | ||
42 | 43 | ||
43 | EXTRA_DIST = \ | 44 | EXTRA_DIST = \ |
44 | test_lockmanager_api.conf | 45 | test_lockmanager_api.conf |
@@ -52,3 +53,9 @@ test_lockmanager_api_SOURCES = \ | |||
52 | test_lockmanager_api_LDADD = \ | 53 | test_lockmanager_api_LDADD = \ |
53 | $(top_builddir)/src/util/libgnunetutil.la \ | 54 | $(top_builddir)/src/util/libgnunetutil.la \ |
54 | libgnunetlockmanager.la | 55 | libgnunetlockmanager.la |
56 | |||
57 | test_lockmanager_api_lockrelease_SOURCES = \ | ||
58 | test_lockmanager_api_lockrelease.c | ||
59 | test_lockmanager_api_lockrelease_LDADD = \ | ||
60 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
61 | libgnunetlockmanager.la \ No newline at end of file | ||
diff --git a/src/lockmanager/gnunet-service-lockmanager.c b/src/lockmanager/gnunet-service-lockmanager.c index 3642ca030..974c14be1 100644 --- a/src/lockmanager/gnunet-service-lockmanager.c +++ b/src/lockmanager/gnunet-service-lockmanager.c | |||
@@ -217,7 +217,6 @@ find_lock (const char *domain_name, | |||
217 | void *value) | 217 | void *value) |
218 | { | 218 | { |
219 | matched_lock = value; | 219 | matched_lock = value; |
220 | |||
221 | if ((lock_num == matched_lock->lock_num) | 220 | if ((lock_num == matched_lock->lock_num) |
222 | && (0 == strcmp (domain_name, matched_lock->domain_name))) | 221 | && (0 == strcmp (domain_name, matched_lock->domain_name))) |
223 | return GNUNET_NO; | 222 | return GNUNET_NO; |
@@ -266,7 +265,7 @@ add_lock (const char *domain_name, | |||
266 | 265 | ||
267 | 266 | ||
268 | /** | 267 | /** |
269 | * Removes a lock from the lock map | 268 | * Removes a lock from the lock map. The WaitList of the lock should be empty |
270 | * | 269 | * |
271 | * @param lock the lock to remove | 270 | * @param lock the lock to remove |
272 | */ | 271 | */ |
@@ -274,7 +273,8 @@ static void | |||
274 | remove_lock (struct Lock *lock) | 273 | remove_lock (struct Lock *lock) |
275 | { | 274 | { |
276 | struct GNUNET_HashCode key; | 275 | struct GNUNET_HashCode key; |
277 | 276 | ||
277 | GNUNET_assert (NULL == lock->wl_head); | ||
278 | get_key (lock->domain_name, | 278 | get_key (lock->domain_name, |
279 | lock->lock_num, | 279 | lock->lock_num, |
280 | &key); | 280 | &key); |
@@ -468,13 +468,14 @@ cl_add_client (struct GNUNET_SERVER_Client *client) | |||
468 | 468 | ||
469 | 469 | ||
470 | /** | 470 | /** |
471 | * Delete the given client from the client list | 471 | * Delete the given client from the client list. The LockList should be empty |
472 | * | 472 | * |
473 | * @param cl_entry the client list entry to delete | 473 | * @param cl_entry the client list entry to delete |
474 | */ | 474 | */ |
475 | static void | 475 | static void |
476 | cl_remove_client (struct ClientList *cl_entry) | 476 | cl_remove_client (struct ClientList *cl_entry) |
477 | { | 477 | { |
478 | GNUNET_assert (NULL == cl_entry->ll_head); | ||
478 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 479 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
479 | "Removing a client from the client list\n"); | 480 | "Removing a client from the client list\n"); |
480 | GNUNET_SERVER_client_drop (cl_entry->client); | 481 | GNUNET_SERVER_client_drop (cl_entry->client); |
@@ -635,7 +636,6 @@ process_lock_release (struct Lock *lock) | |||
635 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 636 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
636 | "Giving lock to a client from wait list\n"); | 637 | "Giving lock to a client from wait list\n"); |
637 | lock->cl_entry = wl_entry->cl_entry; | 638 | lock->cl_entry = wl_entry->cl_entry; |
638 | cl_ll_add_lock (wl_entry->cl_entry, lock); | ||
639 | lock_wl_remove(lock, wl_entry); | 639 | lock_wl_remove(lock, wl_entry); |
640 | send_success_msg (lock->cl_entry->client, | 640 | send_success_msg (lock->cl_entry->client, |
641 | lock->domain_name, | 641 | lock->domain_name, |
@@ -751,6 +751,68 @@ client_disconnect_cb (void *cls, struct GNUNET_SERVER_Client *client) | |||
751 | 751 | ||
752 | 752 | ||
753 | /** | 753 | /** |
754 | * Hashmap Iterator to delete lock entries in hash map | ||
755 | * | ||
756 | * @param cls NULL | ||
757 | * @param key current key code | ||
758 | * @param value value in the hash map | ||
759 | * @return GNUNET_YES if we should continue to | ||
760 | * iterate, | ||
761 | * GNUNET_NO if not. | ||
762 | */ | ||
763 | static int | ||
764 | lock_delete_iterator (void *cls, | ||
765 | const GNUNET_HashCode * key, | ||
766 | void *value) | ||
767 | { | ||
768 | struct Lock *lock = value; | ||
769 | |||
770 | GNUNET_assert (NULL != lock); | ||
771 | while (NULL != lock->wl_head) | ||
772 | { | ||
773 | lock_wl_remove (lock, lock->wl_head); | ||
774 | } | ||
775 | GNUNET_assert (GNUNET_YES == | ||
776 | GNUNET_CONTAINER_multihashmap_remove(lock_map, | ||
777 | key, | ||
778 | lock)); | ||
779 | GNUNET_free (lock->domain_name); | ||
780 | GNUNET_free (lock); | ||
781 | return GNUNET_YES; | ||
782 | } | ||
783 | |||
784 | |||
785 | /** | ||
786 | * Task to clean up and shutdown nicely | ||
787 | * | ||
788 | * @param | ||
789 | * @return | ||
790 | */ | ||
791 | static void | ||
792 | shutdown_task (void *cls, | ||
793 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
794 | { | ||
795 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
796 | "Shutting down lock manager\n"); | ||
797 | /* Clean the global ClientList */ | ||
798 | while (NULL != cl_head) | ||
799 | { | ||
800 | while (NULL != cl_head->ll_head) /* Clear the LockList */ | ||
801 | { | ||
802 | cl_ll_remove_lock (cl_head, cl_head->ll_head); | ||
803 | } | ||
804 | cl_remove_client (cl_head); | ||
805 | } | ||
806 | /* Clean the global hash table */ | ||
807 | GNUNET_CONTAINER_multihashmap_iterate (lock_map, | ||
808 | &lock_delete_iterator, | ||
809 | NULL); | ||
810 | GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (lock_map)); | ||
811 | GNUNET_CONTAINER_multihashmap_destroy (lock_map); | ||
812 | } | ||
813 | |||
814 | |||
815 | /** | ||
754 | * Lock manager setup | 816 | * Lock manager setup |
755 | * | 817 | * |
756 | * @param cls closure | 818 | * @param cls closure |
@@ -774,6 +836,9 @@ lockmanager_run (void *cls, | |||
774 | &client_disconnect_cb, | 836 | &client_disconnect_cb, |
775 | NULL); | 837 | NULL); |
776 | lock_map = GNUNET_CONTAINER_multihashmap_create (30); | 838 | lock_map = GNUNET_CONTAINER_multihashmap_create (30); |
839 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, | ||
840 | &shutdown_task, | ||
841 | NULL); | ||
777 | } | 842 | } |
778 | 843 | ||
779 | 844 | ||
diff --git a/src/lockmanager/lockmanager_api.c b/src/lockmanager/lockmanager_api.c index 18f5d0a71..1545717ee 100644 --- a/src/lockmanager/lockmanager_api.c +++ b/src/lockmanager/lockmanager_api.c | |||
@@ -98,44 +98,28 @@ struct GNUNET_LOCKMANAGER_LockingRequest | |||
98 | * The status of the lock | 98 | * The status of the lock |
99 | */ | 99 | */ |
100 | enum GNUNET_LOCKMANAGER_Status status; | 100 | enum GNUNET_LOCKMANAGER_Status status; |
101 | |||
102 | /** | ||
103 | * The length of the locking domain string including the trailing NULL | ||
104 | */ | ||
105 | uint16_t domain_name_length; | ||
106 | }; | 101 | }; |
107 | 102 | ||
108 | 103 | ||
109 | /** | 104 | /** |
110 | * Generate hash with domain name and the lock | 105 | * Get the key for the given lock in the 'lock_map'. |
111 | * | 106 | * |
112 | * @param domain NULL terminated domain name | 107 | * @param domain_name |
113 | * | 108 | * @param lock_number |
114 | * @param domain_length the length of the domain name including the terminating | 109 | * @param key set to the key |
115 | * NULL if already known; 0 to calculate | ||
116 | * | ||
117 | * @param lock the lock number | ||
118 | * @param ret where to write the generated hash | ||
119 | */ | 110 | */ |
120 | static void | 111 | static void |
121 | hash_domain_and_lock (const char *domain, | 112 | get_key (const char *domain_name, |
122 | uint16_t domain_length, | 113 | uint32_t lock_number, |
123 | uint32_t lock, | 114 | struct GNUNET_HashCode *key) |
124 | GNUNET_HashCode *ret) | ||
125 | { | 115 | { |
126 | unsigned int str_len; | 116 | uint32_t *last_32; |
127 | uint32_t *block; | 117 | |
128 | size_t block_size; | 118 | GNUNET_CRYPTO_hash (domain_name, |
129 | 119 | strlen (domain_name), | |
130 | str_len = (0 == domain_length) ? strlen (domain) : domain_length - 1; | 120 | key); |
131 | block_size = sizeof (uint32_t) + str_len; | 121 | last_32 = (uint32_t *) key; |
132 | block = GNUNET_malloc (block_size); | 122 | *last_32 ^= lock_number; |
133 | /* Copy data */ | ||
134 | *block = lock; | ||
135 | memcpy (&block[1], domain, str_len); | ||
136 | |||
137 | GNUNET_CRYPTO_hash (block, block_size, ret); | ||
138 | GNUNET_free (block); | ||
139 | } | 123 | } |
140 | 124 | ||
141 | 125 | ||
@@ -151,15 +135,15 @@ call_status_cb_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
151 | const struct GNUNET_LOCKMANAGER_LockingRequest *r = cls; | 135 | const struct GNUNET_LOCKMANAGER_LockingRequest *r = cls; |
152 | 136 | ||
153 | if (NULL != r->status_cb) | 137 | if (NULL != r->status_cb) |
154 | { | 138 | { |
155 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 139 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
156 | "Calling status change callback for lock: %d in domain: %s\n", | 140 | "Calling status change callback for lock: %d in domain: %s\n", |
157 | r->lock, r->domain); | 141 | r->lock, r->domain); |
158 | r->status_cb (r->status_cb_cls, | 142 | r->status_cb (r->status_cb_cls, |
159 | r->domain, | 143 | r->domain, |
160 | r->lock, | 144 | r->lock, |
161 | r->status); | 145 | r->status); |
162 | } | 146 | } |
163 | } | 147 | } |
164 | 148 | ||
165 | 149 | ||
@@ -174,67 +158,70 @@ handle_replies (void *cls, | |||
174 | const struct GNUNET_MessageHeader *msg) | 158 | const struct GNUNET_MessageHeader *msg) |
175 | { | 159 | { |
176 | struct GNUNET_LOCKMANAGER_Handle *handle = cls; | 160 | struct GNUNET_LOCKMANAGER_Handle *handle = cls; |
177 | 161 | const struct GNUNET_LOCKMANAGER_Message *m; | |
162 | const char *domain; | ||
163 | struct GNUNET_HashCode hash; | ||
164 | int match_found; | ||
165 | uint32_t lock; | ||
166 | uint16_t msize; | ||
167 | |||
178 | if (NULL == msg) | 168 | if (NULL == msg) |
169 | { | ||
170 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
171 | "Lockmanager service not available or went down\n"); | ||
172 | return; | ||
173 | } | ||
174 | if (GNUNET_MESSAGE_TYPE_LOCKMANAGER_SUCCESS != ntohs(msg->type)) | ||
175 | { | ||
176 | GNUNET_break (0); | ||
177 | return; | ||
178 | } | ||
179 | msize = ntohs (msg->size); | ||
180 | if (msize <= sizeof (struct GNUNET_LOCKMANAGER_Message)) | ||
181 | { | ||
182 | GNUNET_break (0); | ||
183 | return; | ||
184 | } | ||
185 | m = (const struct GNUNET_LOCKMANAGER_Message *) msg; | ||
186 | domain = (const char *) &m[1]; | ||
187 | msize -= sizeof (struct GNUNET_LOCKMANAGER_Message); | ||
188 | if ('\0' != domain[msize-1]) | ||
189 | { | ||
190 | GNUNET_break (0); | ||
191 | return; | ||
192 | } | ||
193 | |||
194 | lock = ntohl (m->lock); | ||
195 | get_key (domain, lock, &hash); | ||
196 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
197 | "Received SUCCESS message for lock: %d, domain %s\n", | ||
198 | lock, domain); | ||
199 | int match_iterator(void *cls, const GNUNET_HashCode *key, void *value) | ||
200 | { | ||
201 | struct GNUNET_LOCKMANAGER_LockingRequest *r = value; | ||
202 | |||
203 | if ( !((0 == strcmp (domain, r->domain)) | ||
204 | && (lock == r->lock))) | ||
205 | return GNUNET_YES; | ||
206 | match_found = GNUNET_YES; | ||
207 | if (GNUNET_LOCKMANAGER_SUCCESS != r->status) | ||
179 | { | 208 | { |
180 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 209 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
181 | "Lockmanager service not available or went down\n"); | 210 | "Changing status for lock: %d in domain: %s to SUCCESS\n", |
182 | return; | 211 | r->lock, r->domain); |
183 | } | 212 | r->status = GNUNET_LOCKMANAGER_SUCCESS; |
184 | 213 | GNUNET_SCHEDULER_add_continuation (&call_status_cb_task, | |
185 | switch (ntohs (msg->type)) | 214 | r, |
186 | { | 215 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); |
187 | case GNUNET_MESSAGE_TYPE_LOCKMANAGER_SUCCESS: | ||
188 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
189 | "Received SUCCESS message\n"); | ||
190 | |||
191 | const struct GNUNET_LOCKMANAGER_Message *m; | ||
192 | const char *domain; | ||
193 | struct GNUNET_HashCode hash; | ||
194 | uint32_t lock; | ||
195 | int match_found; | ||
196 | |||
197 | m = (struct GNUNET_LOCKMANAGER_Message *) msg; | ||
198 | domain = (char *) &m[1]; | ||
199 | lock = ntohl (m->lock); | ||
200 | hash_domain_and_lock (domain, 0, lock, &hash); | ||
201 | |||
202 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
203 | "\t on lock: %d in domain %s\n", | ||
204 | lock, domain); | ||
205 | |||
206 | int match_iterator(void *cls, const GNUNET_HashCode *key, void *value) | ||
207 | { | ||
208 | struct GNUNET_LOCKMANAGER_LockingRequest *r = value; | ||
209 | |||
210 | if ( !((0 == strcmp (domain, r->domain)) | ||
211 | && (lock == r->lock))) | ||
212 | return GNUNET_YES; | ||
213 | |||
214 | match_found = GNUNET_YES; | ||
215 | if (GNUNET_LOCKMANAGER_SUCCESS != r->status) | ||
216 | { | ||
217 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
218 | "Changing status for lock: %d in domain: %s to SUCCESS\n", | ||
219 | r->lock, r->domain); | ||
220 | r->status = GNUNET_LOCKMANAGER_SUCCESS; | ||
221 | GNUNET_SCHEDULER_add_continuation (&call_status_cb_task, | ||
222 | r, | ||
223 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | ||
224 | } | ||
225 | return GNUNET_NO; | ||
226 | } | ||
227 | |||
228 | match_found = GNUNET_NO; | ||
229 | GNUNET_CONTAINER_multihashmap_get_multiple (handle->hashmap, | ||
230 | &hash, | ||
231 | &match_iterator, | ||
232 | NULL); | ||
233 | GNUNET_assert (GNUNET_YES == match_found); | ||
234 | break; | ||
235 | default: | ||
236 | GNUNET_break(0); | ||
237 | } | 216 | } |
217 | return GNUNET_NO; | ||
218 | } | ||
219 | match_found = GNUNET_NO; | ||
220 | GNUNET_CONTAINER_multihashmap_get_multiple (handle->hashmap, | ||
221 | &hash, | ||
222 | &match_iterator, | ||
223 | NULL); | ||
224 | GNUNET_break (GNUNET_YES == match_found); | ||
238 | } | 225 | } |
239 | 226 | ||
240 | 227 | ||
@@ -253,10 +240,10 @@ transmit_notify (void *cls, size_t size, void *buf) | |||
253 | uint16_t msg_size; | 240 | uint16_t msg_size; |
254 | 241 | ||
255 | if ((0 == size) || (NULL == buf)) | 242 | if ((0 == size) || (NULL == buf)) |
256 | { | 243 | { |
257 | /* FIXME: Timed out -- requeue? */ | 244 | /* FIXME: Timed out -- requeue? */ |
258 | return 0; | 245 | return 0; |
259 | } | 246 | } |
260 | msg_size = ntohs (msg->header.size); | 247 | msg_size = ntohs (msg->header.size); |
261 | GNUNET_assert (size >= msg_size); | 248 | GNUNET_assert (size >= msg_size); |
262 | memcpy (buf, msg, msg_size); | 249 | memcpy (buf, msg, msg_size); |
@@ -313,15 +300,13 @@ GNUNET_LOCKMANAGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
313 | h = GNUNET_malloc (sizeof (struct GNUNET_LOCKMANAGER_Handle)); | 300 | h = GNUNET_malloc (sizeof (struct GNUNET_LOCKMANAGER_Handle)); |
314 | h->conn = GNUNET_CLIENT_connect ("lockmanager", cfg); | 301 | h->conn = GNUNET_CLIENT_connect ("lockmanager", cfg); |
315 | if (NULL == h->conn) | 302 | if (NULL == h->conn) |
316 | { | 303 | { |
317 | GNUNET_free (h); | 304 | GNUNET_free (h); |
318 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); | 305 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); |
319 | return NULL; | 306 | return NULL; |
320 | } | 307 | } |
321 | |||
322 | h->hashmap = GNUNET_CONTAINER_multihashmap_create (15); | 308 | h->hashmap = GNUNET_CONTAINER_multihashmap_create (15); |
323 | GNUNET_assert (NULL != h->hashmap); | 309 | GNUNET_assert (NULL != h->hashmap); |
324 | |||
325 | GNUNET_CLIENT_receive (h->conn, | 310 | GNUNET_CLIENT_receive (h->conn, |
326 | &handle_replies, | 311 | &handle_replies, |
327 | h, | 312 | h, |
@@ -342,18 +327,16 @@ GNUNET_LOCKMANAGER_disconnect (struct GNUNET_LOCKMANAGER_Handle *handle) | |||
342 | { | 327 | { |
343 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); | 328 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); |
344 | GNUNET_CLIENT_disconnect (handle->conn); | 329 | GNUNET_CLIENT_disconnect (handle->conn); |
345 | |||
346 | if (0 != GNUNET_CONTAINER_multihashmap_size (handle->hashmap)) | 330 | if (0 != GNUNET_CONTAINER_multihashmap_size (handle->hashmap)) |
347 | { | 331 | { |
348 | LOG (GNUNET_ERROR_TYPE_WARNING, | 332 | LOG (GNUNET_ERROR_TYPE_WARNING, |
349 | "Some locking requests are still present. Cancel them before " | 333 | "Some locking requests are still present. Cancel them before " |
350 | "calling %s\n", __func__); | 334 | "calling %s\n", __func__); |
351 | GNUNET_CONTAINER_multihashmap_iterate (handle->hashmap, | 335 | GNUNET_CONTAINER_multihashmap_iterate (handle->hashmap, |
352 | &free_iterator, | 336 | &free_iterator, |
353 | NULL); | 337 | NULL); |
354 | } | 338 | } |
355 | GNUNET_CONTAINER_multihashmap_destroy (handle->hashmap); | 339 | GNUNET_CONTAINER_multihashmap_destroy (handle->hashmap); |
356 | |||
357 | GNUNET_free (handle); | 340 | GNUNET_free (handle); |
358 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); | 341 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); |
359 | } | 342 | } |
@@ -395,25 +378,24 @@ GNUNET_LOCKMANAGER_acquire_lock (struct GNUNET_LOCKMANAGER_Handle *handle, | |||
395 | struct GNUNET_LOCKMANAGER_Message *msg; | 378 | struct GNUNET_LOCKMANAGER_Message *msg; |
396 | struct GNUNET_HashCode hash; | 379 | struct GNUNET_HashCode hash; |
397 | uint16_t msg_size; | 380 | uint16_t msg_size; |
381 | size_t domain_name_length; | ||
398 | 382 | ||
399 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); | 383 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); |
400 | r = GNUNET_malloc (sizeof (struct GNUNET_LOCKMANAGER_LockingRequest)); | 384 | r = GNUNET_malloc (sizeof (struct GNUNET_LOCKMANAGER_LockingRequest)); |
401 | r->domain_name_length = strlen (domain_name) + 1; | 385 | domain_name_length = strlen (domain_name) + 1; |
402 | r->handle = handle; | 386 | r->handle = handle; |
403 | r->lock = lock; | 387 | r->lock = lock; |
404 | r->domain = GNUNET_malloc (r->domain_name_length); | 388 | r->domain = GNUNET_malloc (domain_name_length); |
405 | r->status = GNUNET_LOCKMANAGER_RELEASE; | 389 | r->status = GNUNET_LOCKMANAGER_RELEASE; |
406 | r->status_cb = status_cb; | 390 | r->status_cb = status_cb; |
407 | r->status_cb_cls = status_cb_cls; | 391 | r->status_cb_cls = status_cb_cls; |
408 | memcpy (r->domain, domain_name, r->domain_name_length); | 392 | memcpy (r->domain, domain_name, domain_name_length); |
409 | 393 | msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message) + domain_name_length; | |
410 | msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message) + r->domain_name_length; | ||
411 | msg = GNUNET_malloc (msg_size); | 394 | msg = GNUNET_malloc (msg_size); |
412 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE); | 395 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE); |
413 | msg->header.size = htons (msg_size); | 396 | msg->header.size = htons (msg_size); |
414 | msg->lock = htonl (lock); | 397 | msg->lock = htonl (lock); |
415 | memcpy (&msg[1], r->domain, r->domain_name_length); | 398 | memcpy (&msg[1], r->domain, domain_name_length); |
416 | |||
417 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Queueing ACQUIRE message\n"); | 399 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Queueing ACQUIRE message\n"); |
418 | r->transmit_handle = | 400 | r->transmit_handle = |
419 | GNUNET_CLIENT_notify_transmit_ready (r->handle->conn, | 401 | GNUNET_CLIENT_notify_transmit_ready (r->handle->conn, |
@@ -422,15 +404,11 @@ GNUNET_LOCKMANAGER_acquire_lock (struct GNUNET_LOCKMANAGER_Handle *handle, | |||
422 | GNUNET_YES, | 404 | GNUNET_YES, |
423 | &transmit_notify, | 405 | &transmit_notify, |
424 | msg); | 406 | msg); |
425 | hash_domain_and_lock (r->domain, | 407 | get_key (r->domain, r->lock, &hash); |
426 | r->domain_name_length, | ||
427 | r->lock, | ||
428 | &hash); | ||
429 | GNUNET_CONTAINER_multihashmap_put (r->handle->hashmap, | 408 | GNUNET_CONTAINER_multihashmap_put (r->handle->hashmap, |
430 | &hash, | 409 | &hash, |
431 | r, | 410 | r, |
432 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | 411 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
433 | |||
434 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); | 412 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); |
435 | return r; | 413 | return r; |
436 | } | 414 | } |
@@ -449,40 +427,34 @@ void | |||
449 | GNUNET_LOCKMANAGER_cancel_request (struct GNUNET_LOCKMANAGER_LockingRequest | 427 | GNUNET_LOCKMANAGER_cancel_request (struct GNUNET_LOCKMANAGER_LockingRequest |
450 | *request) | 428 | *request) |
451 | { | 429 | { |
430 | struct GNUNET_LOCKMANAGER_Message *msg; | ||
452 | struct GNUNET_HashCode hash; | 431 | struct GNUNET_HashCode hash; |
432 | uint16_t msg_size; | ||
433 | size_t domain_name_length; | ||
453 | 434 | ||
454 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); | 435 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__); |
455 | /* FIXME: Stop ACQUIRE retransmissions */ | 436 | /* FIXME: Stop ACQUIRE retransmissions */ |
456 | if (GNUNET_LOCKMANAGER_SUCCESS == request->status) | 437 | if (GNUNET_LOCKMANAGER_SUCCESS == request->status) |
457 | { | 438 | { |
458 | struct GNUNET_LOCKMANAGER_Message *msg; | 439 | domain_name_length = strlen (request->domain) + 1; |
459 | uint16_t msg_size; | 440 | msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message) |
460 | 441 | + domain_name_length; | |
461 | msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message) | 442 | msg = GNUNET_malloc (msg_size); |
462 | + request->domain_name_length; | 443 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_RELEASE); |
463 | msg = GNUNET_malloc (msg_size); | 444 | msg->header.size = htons (msg_size); |
464 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_RELEASE); | 445 | msg->lock = htonl (request->lock); |
465 | msg->header.size = htons (msg_size); | 446 | memcpy (&msg[1], request->domain, domain_name_length); |
466 | msg->lock = htonl (request->lock); | 447 | GNUNET_CLIENT_notify_transmit_ready (request->handle->conn, |
467 | memcpy (&msg[1], request->domain, request->domain_name_length); | 448 | msg_size, |
468 | 449 | TIMEOUT, /* What if this fails */ | |
469 | GNUNET_CLIENT_notify_transmit_ready (request->handle->conn, | 450 | GNUNET_NO, |
470 | msg_size, | 451 | &transmit_notify, |
471 | TIMEOUT, /* What if this fails */ | 452 | msg); |
472 | GNUNET_NO, | 453 | } |
473 | &transmit_notify, | 454 | get_key (request->domain, request->lock, &hash); |
474 | msg); | ||
475 | } | ||
476 | |||
477 | hash_domain_and_lock (request->domain, | ||
478 | request->domain_name_length, | ||
479 | request->lock, | ||
480 | &hash); | ||
481 | |||
482 | GNUNET_assert (GNUNET_YES == | 455 | GNUNET_assert (GNUNET_YES == |
483 | GNUNET_CONTAINER_multihashmap_remove | 456 | GNUNET_CONTAINER_multihashmap_remove |
484 | (request->handle->hashmap, &hash, request)); | 457 | (request->handle->hashmap, &hash, request)); |
485 | |||
486 | GNUNET_free (request->domain); | 458 | GNUNET_free (request->domain); |
487 | GNUNET_free (request); | 459 | GNUNET_free (request); |
488 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); | 460 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); |
diff --git a/src/lockmanager/test_lockmanager_api.conf b/src/lockmanager/test_lockmanager_api.conf index b6a291730..aa13706cd 100644 --- a/src/lockmanager/test_lockmanager_api.conf +++ b/src/lockmanager/test_lockmanager_api.conf | |||
@@ -5,7 +5,7 @@ PORT = 12112 | |||
5 | ACCEPT_FROM = 127.0.0.1; | 5 | ACCEPT_FROM = 127.0.0.1; |
6 | HOSTNAME = localhost | 6 | HOSTNAME = localhost |
7 | # PREFIX = valgrind --leak-check=full | 7 | # PREFIX = valgrind --leak-check=full |
8 | # PREFIX = xterm -geometry 100x85 -T peer1 -e gdb --args | 8 | # PREFIX = xterm -geometry 100x85 -T peer1 -e libtool --mode=execute gdb --args |
9 | 9 | ||
10 | [fs] | 10 | [fs] |
11 | AUTOSTART = NO | 11 | AUTOSTART = NO |
diff --git a/src/lockmanager/test_lockmanager_api_lockrelease.c b/src/lockmanager/test_lockmanager_api_lockrelease.c new file mode 100644 index 000000000..8eea5cc22 --- /dev/null +++ b/src/lockmanager/test_lockmanager_api_lockrelease.c | |||
@@ -0,0 +1,301 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2012 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 2, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file lockmanager/test_lockmanager_api_lockrelease.c | ||
23 | * @brief Test cases for lockmanager_api where client disconnects abruptly | ||
24 | * @author Sree Harsha Totakura | ||
25 | */ | ||
26 | |||
27 | #include "platform.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | #include "gnunet_lockmanager_service.h" | ||
30 | |||
31 | #define VERBOSE GNUNET_YES | ||
32 | |||
33 | #define VERBOSE_ARM 1 | ||
34 | |||
35 | #define LOG(kind,...) \ | ||
36 | GNUNET_log (kind, __VA_ARGS__) | ||
37 | |||
38 | #define TIME_REL_SECONDS(min) \ | ||
39 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, min) | ||
40 | |||
41 | /** | ||
42 | * Various steps of the test | ||
43 | */ | ||
44 | enum Test | ||
45 | { | ||
46 | /** | ||
47 | * Signal test failure | ||
48 | */ | ||
49 | TEST_FAIL, | ||
50 | |||
51 | /** | ||
52 | * Testing just began | ||
53 | */ | ||
54 | TEST_INIT, | ||
55 | |||
56 | /** | ||
57 | * Client 1 has got the lock successfully; Client 2 should try to acquire | ||
58 | * the lock now; after some time client 1 has to release the lock | ||
59 | */ | ||
60 | TEST_CLIENT1_LOCK_SUCCESS, | ||
61 | |||
62 | /** | ||
63 | * Client 2 has got the lock; Should release it and call shutdown | ||
64 | */ | ||
65 | TEST_CLIENT2_LOCK_SUCCESS, | ||
66 | }; | ||
67 | |||
68 | /** | ||
69 | * The testing result | ||
70 | */ | ||
71 | static enum Test result; | ||
72 | |||
73 | /** | ||
74 | * The process id of the GNUNET ARM process | ||
75 | */ | ||
76 | static struct GNUNET_OS_Process *arm_pid = NULL; | ||
77 | |||
78 | /** | ||
79 | * Configuration Handle | ||
80 | */ | ||
81 | static struct GNUNET_CONFIGURATION_Handle *config; | ||
82 | |||
83 | /** | ||
84 | * The handle to the lockmanager service | ||
85 | */ | ||
86 | static struct GNUNET_LOCKMANAGER_Handle *handle; | ||
87 | |||
88 | /** | ||
89 | * A second client handle to the lockmanager service | ||
90 | */ | ||
91 | static struct GNUNET_LOCKMANAGER_Handle *handle2; | ||
92 | |||
93 | /** | ||
94 | * The locking request | ||
95 | */ | ||
96 | static struct GNUNET_LOCKMANAGER_LockingRequest *request; | ||
97 | |||
98 | /** | ||
99 | * The locking request of second client | ||
100 | */ | ||
101 | static struct GNUNET_LOCKMANAGER_LockingRequest *request2; | ||
102 | |||
103 | /** | ||
104 | * Abort task identifier | ||
105 | */ | ||
106 | static GNUNET_SCHEDULER_TaskIdentifier abort_task_id; | ||
107 | |||
108 | |||
109 | /** | ||
110 | * Shutdown nicely | ||
111 | * | ||
112 | * @param cls | ||
113 | * @param tc the task context | ||
114 | */ | ||
115 | static void | ||
116 | do_shutdown (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
117 | { | ||
118 | if (GNUNET_SCHEDULER_NO_TASK != abort_task_id) | ||
119 | { | ||
120 | GNUNET_SCHEDULER_cancel (abort_task_id); | ||
121 | abort_task_id = GNUNET_SCHEDULER_NO_TASK; | ||
122 | } | ||
123 | |||
124 | GNUNET_LOCKMANAGER_disconnect (handle); | ||
125 | GNUNET_LOCKMANAGER_disconnect (handle2); | ||
126 | if (0 != GNUNET_OS_process_kill (arm_pid, SIGTERM)) | ||
127 | { | ||
128 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
129 | "Kill gnunet-service-arm manually\n"); | ||
130 | } | ||
131 | GNUNET_OS_process_wait (arm_pid); | ||
132 | GNUNET_OS_process_destroy (arm_pid); | ||
133 | |||
134 | if (NULL != config) | ||
135 | GNUNET_CONFIGURATION_destroy (config); | ||
136 | } | ||
137 | |||
138 | |||
139 | /** | ||
140 | * Abort | ||
141 | * | ||
142 | * @param cls | ||
143 | * @param tc the task context | ||
144 | */ | ||
145 | static void | ||
146 | do_abort (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
147 | { | ||
148 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Aborting test...\n"); | ||
149 | abort_task_id = GNUNET_SCHEDULER_NO_TASK; | ||
150 | result = TEST_FAIL; | ||
151 | do_shutdown (cls, tc); | ||
152 | } | ||
153 | |||
154 | |||
155 | /** | ||
156 | * Callback for lock status changes | ||
157 | * | ||
158 | * @param cls the handle | ||
159 | * | ||
160 | * @param domain_name the locking domain of the lock | ||
161 | * | ||
162 | * @param lock the lock for which this status is relevant | ||
163 | * | ||
164 | * @param status GNUNET_LOCKMANAGER_SUCCESS if the lock has been successfully | ||
165 | * acquired; GNUNET_LOCKMANAGER_RELEASE when the acquired lock is lost | ||
166 | */ | ||
167 | static void | ||
168 | status_cb (void *cls, | ||
169 | const char *domain_name, | ||
170 | uint32_t lock, | ||
171 | enum GNUNET_LOCKMANAGER_Status status) | ||
172 | { | ||
173 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
174 | "Status change callback called on lock: %d of domain: %s\n", | ||
175 | lock, domain_name); | ||
176 | GNUNET_assert (GNUNET_LOCKMANAGER_SUCCESS == status); | ||
177 | switch (result) | ||
178 | { | ||
179 | case TEST_INIT: | ||
180 | GNUNET_assert (handle == cls); | ||
181 | result = TEST_CLIENT1_LOCK_SUCCESS; | ||
182 | request2 = GNUNET_LOCKMANAGER_acquire_lock (handle2, | ||
183 | "GNUNET_LOCKMANAGER_TESTING", | ||
184 | 99, | ||
185 | &status_cb, | ||
186 | handle2); | ||
187 | GNUNET_assert (NULL != request2); | ||
188 | GNUNET_LOCKMANAGER_cancel_request (request); | ||
189 | request = NULL; | ||
190 | break; | ||
191 | case TEST_CLIENT1_LOCK_SUCCESS: | ||
192 | GNUNET_assert (handle2 == cls); | ||
193 | result = TEST_CLIENT2_LOCK_SUCCESS; | ||
194 | GNUNET_LOCKMANAGER_cancel_request (request2); | ||
195 | GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (1), | ||
196 | &do_shutdown, | ||
197 | NULL); | ||
198 | break; | ||
199 | default: | ||
200 | GNUNET_assert (0); /* We should never reach here */ | ||
201 | } | ||
202 | |||
203 | } | ||
204 | |||
205 | |||
206 | /** | ||
207 | * Testing function | ||
208 | * | ||
209 | * @param cls NULL | ||
210 | * @param tc the task context | ||
211 | */ | ||
212 | static void | ||
213 | test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
214 | { | ||
215 | result = TEST_INIT; | ||
216 | handle = GNUNET_LOCKMANAGER_connect (config); | ||
217 | GNUNET_assert (NULL != handle); | ||
218 | handle2 = GNUNET_LOCKMANAGER_connect (config); | ||
219 | |||
220 | request = GNUNET_LOCKMANAGER_acquire_lock (handle, | ||
221 | "GNUNET_LOCKMANAGER_TESTING", | ||
222 | 99, | ||
223 | &status_cb, | ||
224 | handle); | ||
225 | GNUNET_assert (NULL != request); | ||
226 | abort_task_id = GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (60), | ||
227 | &do_abort, | ||
228 | NULL); | ||
229 | } | ||
230 | |||
231 | |||
232 | /** | ||
233 | * Main point of test execution | ||
234 | */ | ||
235 | static void | ||
236 | run (void *cls, char *const *args, const char *cfgfile, | ||
237 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
238 | { | ||
239 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting test...\n"); | ||
240 | config = GNUNET_CONFIGURATION_dup (cfg); | ||
241 | arm_pid = | ||
242 | GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", | ||
243 | "gnunet-service-arm", | ||
244 | #if VERBOSE_ARM | ||
245 | "-L", "DEBUG", | ||
246 | #endif | ||
247 | "-c", "test_lockmanager_api.conf", NULL); | ||
248 | |||
249 | GNUNET_assert (NULL != arm_pid); | ||
250 | GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (1), | ||
251 | &test, | ||
252 | NULL); | ||
253 | } | ||
254 | |||
255 | |||
256 | /** | ||
257 | * Main function | ||
258 | */ | ||
259 | int main (int argc, char **argv) | ||
260 | { | ||
261 | int ret; | ||
262 | |||
263 | char *const argv2[] = { "test-lockmanager-api-lockrelease", | ||
264 | "-c", "test_lockmanager_api.conf", | ||
265 | #if VERBOSE | ||
266 | "-L", "DEBUG", | ||
267 | #endif | ||
268 | NULL | ||
269 | }; | ||
270 | |||
271 | struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
272 | GNUNET_GETOPT_OPTION_END | ||
273 | }; | ||
274 | |||
275 | GNUNET_log_setup ("test-lockmanager-api-lockrelease", | ||
276 | #if VERBOSE | ||
277 | "DEBUG", | ||
278 | #else | ||
279 | "WARNING", | ||
280 | #endif | ||
281 | NULL); | ||
282 | |||
283 | ret = | ||
284 | GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2, | ||
285 | "test-lockmanager-api-lockrelease", | ||
286 | "nohelp", options, &run, NULL); | ||
287 | |||
288 | if (GNUNET_OK != ret) | ||
289 | { | ||
290 | LOG (GNUNET_ERROR_TYPE_WARNING, "run failed with error code %d\n", | ||
291 | ret); | ||
292 | return 1; | ||
293 | } | ||
294 | if (TEST_CLIENT2_LOCK_SUCCESS != result) | ||
295 | { | ||
296 | LOG (GNUNET_ERROR_TYPE_WARNING, "test failed\n"); | ||
297 | return 1; | ||
298 | } | ||
299 | LOG (GNUNET_ERROR_TYPE_INFO, "test OK\n"); | ||
300 | return 0; | ||
301 | } | ||