aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2012-04-28 13:09:31 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2012-04-28 13:09:31 +0000
commit4761d5671197ba3a125d66c672b5f5165ba83481 (patch)
tree0c3b8f9658b82f8b586530b49cdafb3b7e81c8ad
parentfe92967f50a918352370fb95c6bc0f6d2a5eb6c2 (diff)
downloadgnunet-4761d5671197ba3a125d66c672b5f5165ba83481.tar.gz
gnunet-4761d5671197ba3a125d66c672b5f5165ba83481.zip
-hashmap for storing lockingrequests in lockmanager
-rw-r--r--src/lockmanager/gnunet-service-lockmanager.c61
-rw-r--r--src/lockmanager/lockmanager_api.c176
2 files changed, 187 insertions, 50 deletions
diff --git a/src/lockmanager/gnunet-service-lockmanager.c b/src/lockmanager/gnunet-service-lockmanager.c
index 5735f65b1..65142fec2 100644
--- a/src/lockmanager/gnunet-service-lockmanager.c
+++ b/src/lockmanager/gnunet-service-lockmanager.c
@@ -35,21 +35,72 @@
35#define LOG(kind,...) \ 35#define LOG(kind,...) \
36 GNUNET_log_from (kind, "gnunet-service-lockmanager",__VA_ARGS__) 36 GNUNET_log_from (kind, "gnunet-service-lockmanager",__VA_ARGS__)
37 37
38#define TIME_REL_MINS(min) \
39 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, min)
40
41#define TIMEOUT TIME_REL_MINS(3)
42
43/**
44 * Transmit notify for sending message to client
45 *
46 * @param cls the message to send
47 * @param size number of bytes available in buf
48 * @param buf where the callee should write the message
49 * @return number of bytes written to buf
50 */
51static size_t
52transmit_notify (void *cls, size_t size, void *buf)
53{
54 struct GNUNET_LOCKMANAGER_Message *msg = cls;
55 uint16_t msg_size;
56
57 if ((0 == size) || (NULL == buf))
58 {
59 /* FIXME: Timed out -- requeue? */
60 return 0;
61 }
62 msg_size = ntohs (msg->header.size);
63 GNUNET_assert (size >= msg_size);
64 memcpy (buf, msg, msg_size);
65 GNUNET_free (msg);
66 LOG (GNUNET_ERROR_TYPE_DEBUG,
67 "Message of size %u sent\n", msg_size);
68 return msg_size;
69}
70
38 71
39/** 72/**
40 * Handler for GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE 73 * Handler for GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE
41 * 74 *
42 * @param 75 * @param cls NULL
43 * @return 76 * @param client the client sending this message
77 * @param message GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE message
44 */ 78 */
45static void 79static void
46handle_acquire (void *cls, 80handle_acquire (void *cls,
47 struct GNUNET_SERVER_Client *client, 81 struct GNUNET_SERVER_Client *client,
48 const struct GNUNET_MessageHeader *message) 82 const struct GNUNET_MessageHeader *message)
49{ 83{
50 // const struct GNUNET_LOCKMANAGER_Message *msg = message; 84 const struct GNUNET_LOCKMANAGER_Message *request;
85 struct GNUNET_LOCKMANAGER_Message *reply;
86 int16_t request_size;
87
88
51 LOG (GNUNET_ERROR_TYPE_DEBUG, 89 LOG (GNUNET_ERROR_TYPE_DEBUG,
52 "Received a ACQUIRE message\n"); 90 "Received an ACQUIRE message\n");
91
92 request = (struct GNUNET_LOCKMANAGER_Message *) message;
93
94 /* FIXME: Dummy implementation; just echos success for every lock */
95 request_size = ntohs (message->size);
96 reply = GNUNET_malloc (request_size);
97 memcpy (reply, request, request_size);
98 reply->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_SUCCESS);
99 GNUNET_SERVER_notify_transmit_ready (client,
100 request_size,
101 TIMEOUT,
102 &transmit_notify,
103 reply);
53 104
54 GNUNET_SERVER_receive_done (client, GNUNET_OK); 105 GNUNET_SERVER_receive_done (client, GNUNET_OK);
55} 106}
@@ -85,7 +136,7 @@ lockmanager_run (void *cls,
85 struct GNUNET_SERVER_Handle * server, 136 struct GNUNET_SERVER_Handle * server,
86 const struct GNUNET_CONFIGURATION_Handle *cfg) 137 const struct GNUNET_CONFIGURATION_Handle *cfg)
87{ 138{
88 struct GNUNET_SERVER_MessageHandler message_handlers[] = 139 static const struct GNUNET_SERVER_MessageHandler message_handlers[] =
89 { 140 {
90 {&handle_acquire, NULL, GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE, 0}, 141 {&handle_acquire, NULL, GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE, 0},
91 {&handle_release, NULL, GNUNET_MESSAGE_TYPE_LOCKMANAGER_RELEASE, 0}, 142 {&handle_release, NULL, GNUNET_MESSAGE_TYPE_LOCKMANAGER_RELEASE, 0},
diff --git a/src/lockmanager/lockmanager_api.c b/src/lockmanager/lockmanager_api.c
index 7e20e27de..6524c7134 100644
--- a/src/lockmanager/lockmanager_api.c
+++ b/src/lockmanager/lockmanager_api.c
@@ -107,6 +107,63 @@ struct GNUNET_LOCKMANAGER_LockingRequest
107 107
108 108
109/** 109/**
110 * Generate hash with domain name and the lock
111 *
112 * @param domain NULL terminated domain name
113 *
114 * @param domain_length the length of the domain name including the terminating
115 * NULL if already known; 0 to calculate
116 *
117 * @param lock the lock number
118 * @param where to write the generated hash
119 */
120static void
121hash_domain_and_lock (const char *domain,
122 uint16_t domain_length,
123 uint32_t lock,
124 GNUNET_HashCode *ret)
125{
126 unsigned int str_len;
127 uint32_t *block;
128 size_t block_size;
129
130 str_len = (0 == domain_length) ? strlen (domain) : domain_length - 1;
131 block_size = sizeof (uint32_t) + str_len;
132 block = GNUNET_malloc (block_size);
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}
140
141
142/**
143 * Task for calling status change callback for a lock
144 *
145 * @param cls the LockingRequest associated with this lock
146 * @param tc the TaskScheduler context
147 */
148static void
149call_status_cb_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
150{
151 const struct GNUNET_LOCKMANAGER_LockingRequest *r = cls;
152
153 if (NULL != r->status_cb)
154 {
155 LOG (GNUNET_ERROR_TYPE_DEBUG,
156 "Calling status change callback for lock: %d in domain: %s\n",
157 r->lock, r->domain);
158 r->status_cb (r->status_cb_cls,
159 r->domain,
160 r->lock,
161 r->status);
162 }
163}
164
165
166/**
110 * Handler for server replies 167 * Handler for server replies
111 * 168 *
112 * @param cls the LOCKMANAGER_Handle 169 * @param cls the LOCKMANAGER_Handle
@@ -116,13 +173,68 @@ static void
116handle_replies (void *cls, 173handle_replies (void *cls,
117 const struct GNUNET_MessageHeader *msg) 174 const struct GNUNET_MessageHeader *msg)
118{ 175{
176 struct GNUNET_LOCKMANAGER_Handle *handle = cls;
177
119 if (NULL == msg) 178 if (NULL == msg)
120 LOG (GNUNET_ERROR_TYPE_DEBUG, 179 {
121 "Lockmanager service not available or went down\n"); 180 LOG (GNUNET_ERROR_TYPE_DEBUG,
122 return; 181 "Lockmanager service not available or went down\n");
182 return;
183 }
123 184
124 LOG (GNUNET_ERROR_TYPE_DEBUG, 185 switch (ntohs (msg->type))
125 "Received SUCCESS message\n"); 186 {
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 }
126} 238}
127 239
128 240
@@ -160,7 +272,7 @@ transmit_notify (void *cls, size_t size, void *buf)
160 * 272 *
161 * @param cls NULL 273 * @param cls NULL
162 * @param key current key code 274 * @param key current key code
163 * @param value value in the hash map 275 * @param value the Locking request
164 * @return GNUNET_YES if we should continue to 276 * @return GNUNET_YES if we should continue to
165 * iterate, 277 * iterate,
166 * GNUNET_NO if not. 278 * GNUNET_NO if not.
@@ -170,49 +282,21 @@ free_iterator(void *cls,
170 const GNUNET_HashCode * key, 282 const GNUNET_HashCode * key,
171 void *value) 283 void *value)
172{ 284{
285 struct GNUNET_LOCKMANAGER_LockingRequest *r = value;
286
173 LOG (GNUNET_ERROR_TYPE_DEBUG, 287 LOG (GNUNET_ERROR_TYPE_DEBUG,
174 "Clearing locking request\n"); 288 "Clearing locking request\n");
175 GNUNET_free (value); 289 GNUNET_free (r->domain);
290 GNUNET_free (r);
176 return GNUNET_YES; 291 return GNUNET_YES;
177} 292}
178 293
179 294
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}
211
212/*******************/ 295/*******************/
213/* API Definitions */ 296/* API Definitions */
214/*******************/ 297/*******************/
215 298
299
216/** 300/**
217 * Connect to the lockmanager service 301 * Connect to the lockmanager service
218 * 302 *
@@ -240,7 +324,7 @@ GNUNET_LOCKMANAGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
240 324
241 GNUNET_CLIENT_receive (h->conn, 325 GNUNET_CLIENT_receive (h->conn,
242 &handle_replies, 326 &handle_replies,
243 NULL, 327 h,
244 GNUNET_TIME_UNIT_FOREVER_REL); 328 GNUNET_TIME_UNIT_FOREVER_REL);
245 329
246 LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); 330 LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__);
@@ -318,6 +402,7 @@ GNUNET_LOCKMANAGER_acquire_lock (struct GNUNET_LOCKMANAGER_Handle *handle,
318 r->handle = handle; 402 r->handle = handle;
319 r->lock = lock; 403 r->lock = lock;
320 r->domain = GNUNET_malloc (r->domain_name_length); 404 r->domain = GNUNET_malloc (r->domain_name_length);
405 r->status = GNUNET_LOCKMANAGER_RELEASE;
321 memcpy (r->domain, domain_name, r->domain_name_length); 406 memcpy (r->domain, domain_name, r->domain_name_length);
322 407
323 msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message) + r->domain_name_length; 408 msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message) + r->domain_name_length;
@@ -332,8 +417,8 @@ GNUNET_LOCKMANAGER_acquire_lock (struct GNUNET_LOCKMANAGER_Handle *handle,
332 GNUNET_CLIENT_notify_transmit_ready (r->handle->conn, 417 GNUNET_CLIENT_notify_transmit_ready (r->handle->conn,
333 msg_size, 418 msg_size,
334 TIMEOUT, 419 TIMEOUT,
335 GNUNET_NO, 420 GNUNET_YES,
336 *transmit_notify, 421 &transmit_notify,
337 msg); 422 msg);
338 hash_domain_and_lock (r->domain, 423 hash_domain_and_lock (r->domain,
339 r->domain_name_length, 424 r->domain_name_length,
@@ -386,8 +471,7 @@ GNUNET_LOCKMANAGER_cancel_request (struct GNUNET_LOCKMANAGER_LockingRequest
386 &transmit_notify, 471 &transmit_notify,
387 msg); 472 msg);
388 } 473 }
389 LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); 474
390
391 hash_domain_and_lock (request->domain, 475 hash_domain_and_lock (request->domain,
392 request->domain_name_length, 476 request->domain_name_length,
393 request->lock, 477 request->lock,
@@ -396,6 +480,8 @@ GNUNET_LOCKMANAGER_cancel_request (struct GNUNET_LOCKMANAGER_LockingRequest
396 GNUNET_assert (GNUNET_YES == 480 GNUNET_assert (GNUNET_YES ==
397 GNUNET_CONTAINER_multihashmap_remove 481 GNUNET_CONTAINER_multihashmap_remove
398 (request->handle->hashmap, &hash, request)); 482 (request->handle->hashmap, &hash, request));
399 483
484 GNUNET_free (request->domain);
400 GNUNET_free (request); 485 GNUNET_free (request);
486 LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__);
401} 487}