aboutsummaryrefslogtreecommitdiff
path: root/src/lockmanager
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2012-04-27 22:41:10 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2012-04-27 22:41:10 +0000
commitfe92967f50a918352370fb95c6bc0f6d2a5eb6c2 (patch)
tree643896abb72ca1fbb933c8db7946909547289f26 /src/lockmanager
parent487c280270c1e8f6d22cb77b651da000d2a53724 (diff)
downloadgnunet-fe92967f50a918352370fb95c6bc0f6d2a5eb6c2.tar.gz
gnunet-fe92967f50a918352370fb95c6bc0f6d2a5eb6c2.zip
-hashmap for storing lockingrequests in lockmanager
Diffstat (limited to 'src/lockmanager')
-rw-r--r--src/lockmanager/lockmanager_api.c138
-rw-r--r--src/lockmanager/test_lockmanager_api.c101
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 */
108static void 115static void
109handle_success (void *cls, 116handle_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 */
128static void
129handle_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 */
168static int
169free_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 */
191static void
192hash_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
296GNUNET_LOCKMANAGER_cancel_request (struct GNUNET_LOCKMANAGER_LockingRequest 362GNUNET_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 */
54struct GNUNET_CONFIGURATION_Handle *config; 54static struct GNUNET_CONFIGURATION_Handle *config;
55 55
56/** 56/**
57 * Testing function 57 * The handle to the lockmanager service
58 */
59static struct GNUNET_LOCKMANAGER_Handle *handle;
60
61/**
62 * The locking request
63 */
64static 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 */
62static void 72static void
63test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 73do_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 */
99static void
100do_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 */
118static void
119status_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 */
136static void
137test (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}