aboutsummaryrefslogtreecommitdiff
path: root/src/lockmanager
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2012-04-26 20:49:58 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2012-04-26 20:49:58 +0000
commitc1c0db0e9591de979b6572eb41bdd99f3cb6613d (patch)
tree08df1e643470afc6e8996224e0cf8522e1ac51a6 /src/lockmanager
parent01c524d5a9d16305e6d6a14000da2635548e96a0 (diff)
downloadgnunet-c1c0db0e9591de979b6572eb41bdd99f3cb6613d.tar.gz
gnunet-c1c0db0e9591de979b6572eb41bdd99f3cb6613d.zip
-extended lockmanager api
Diffstat (limited to 'src/lockmanager')
-rw-r--r--src/lockmanager/lockmanager_api.c237
1 files changed, 235 insertions, 2 deletions
diff --git a/src/lockmanager/lockmanager_api.c b/src/lockmanager/lockmanager_api.c
index e8d18666b..311f43b0f 100644
--- a/src/lockmanager/lockmanager_api.c
+++ b/src/lockmanager/lockmanager_api.c
@@ -28,11 +28,17 @@
28#include "gnunet_common.h" 28#include "gnunet_common.h"
29#include "gnunet_protocols.h" 29#include "gnunet_protocols.h"
30#include "gnunet_client_lib.h" 30#include "gnunet_client_lib.h"
31#include "gnunet_lockmanager_service.h"
31 32
32#include "lockmanager.h" 33#include "lockmanager.h"
33 34
34#define LOG(kind,...) \ 35#define LOG(kind,...) \
35 GNUNET_log_from (kind, "gnunet-service-lockmanager",__VA_ARGS__) 36 GNUNET_log_from (kind, "lockmanager-api",__VA_ARGS__)
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)
36 42
37/** 43/**
38 * Handler for the lockmanager service 44 * Handler for the lockmanager service
@@ -47,6 +53,121 @@ struct GNUNET_LOCKMANAGER_Handle
47 53
48 54
49/** 55/**
56 * Structure for Locking Request
57 */
58struct GNUNET_LOCKMANAGER_LockingRequest
59{
60 /**
61 * The handle associated with this request
62 */
63 struct GNUNET_LOCKMANAGER_Handle *handle;
64
65 /**
66 * The status callback
67 */
68 GNUNET_LOCKMANAGER_StatusCallback status_cb;
69
70 /**
71 * Closure for the status callback
72 */
73 void *status_cb_cls;
74
75 /**
76 * The pending transmit handle for the ACQUIRE message
77 */
78 struct GNUNET_CLIENT_TransmitHandle *transmit_handle;
79
80 /**
81 * The locking domain of this request
82 */
83 char *domain;
84
85 /**
86 * The lock
87 */
88 uint32_t lock;
89
90 /**
91 * The status of the lock
92 */
93 enum GNUNET_LOCKMANAGER_Status status;
94
95 /**
96 * The length of the locking domain string including the trailing NULL
97 */
98 uint16_t domain_name_length;
99};
100
101
102/**
103 * Message handler for SUCCESS messages
104 *
105 * @param cls the LOCKMANAGER_Handle
106 * @param msg message received, NULL on timeout or fatal error
107 */
108static void
109handle_success (void *cls,
110 const struct GNUNET_MessageHeader *msg)
111{
112 if (NULL == msg)
113 return;
114
115 LOG (GNUNET_ERROR_TYPE_DEBUG,
116 "Received SUCCESS message\n");
117}
118
119
120/**
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 "Lockmanger service went down\n");
134
135}
136
137
138/**
139 * Transmit notify for sending message to server
140 *
141 * @param cls the message to send
142 * @param size number of bytes available in buf
143 * @param buf where the callee should write the message
144 * @return number of bytes written to buf
145 */
146static size_t
147transmit_notify (void *cls, size_t size, void *buf)
148{
149 struct GNUNET_LOCKMANAGER_Message *msg = cls;
150 uint16_t msg_size;
151
152 if ((0 == size) || (NULL == buf))
153 {
154 /* FIXME: Timed out -- requeue? */
155 return 0;
156 }
157 msg_size = ntohs (msg->header.size);
158 GNUNET_assert (size >= msg_size);
159 memcpy (buf, msg, msg_size);
160 GNUNET_free (msg);
161 return msg_size;
162}
163
164
165
166/*******************/
167/* API Definitions */
168/*******************/
169
170/**
50 * Connect to the lockmanager service 171 * Connect to the lockmanager service
51 * 172 *
52 * @param cfg the configuration to use 173 * @param cfg the configuration to use
@@ -65,9 +186,20 @@ GNUNET_LOCKMANAGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
65 GNUNET_free (h); 186 GNUNET_free (h);
66 return NULL; 187 return NULL;
67 } 188 }
68 return NULL; 189
190 GNUNET_CLIENT_receive (h->conn,
191 &handle_server_crash,
192 NULL,
193 GNUNET_TIME_UNIT_FOREVER_REL);
194
195 GNUNET_CLIENT_receive (h->conn,
196 &handle_success,
197 h,
198 GNUNET_TIME_UNIT_FOREVER_REL);
199 return h;
69} 200}
70 201
202
71/** 203/**
72 * Disconnect from the lockmanager service 204 * Disconnect from the lockmanager service
73 * 205 *
@@ -76,5 +208,106 @@ GNUNET_LOCKMANAGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
76void 208void
77GNUNET_LOCKMANAGER_disconnect (struct GNUNET_LOCKMANAGER_Handle *handle) 209GNUNET_LOCKMANAGER_disconnect (struct GNUNET_LOCKMANAGER_Handle *handle)
78{ 210{
211 GNUNET_CLIENT_disconnect (handle->conn);
212 GNUNET_free (handle);
213}
214
215
216/**
217 * Tries to acquire the given lock(even if the lock has been lost) until the
218 * request is called. If the lock is available the status_cb will be
219 * called. If the lock is busy then the request is queued and status_cb
220 * will be called when the lock has been made available and acquired by us.
221 *
222 * @param handle the handle to the lockmanager service
223 *
224 * @param domain_name name of the locking domain. Clients who want to share
225 * locks must use the same name for the locking domain. Also the
226 * domain_name should be selected with the prefix
227 * "GNUNET_<PROGRAM_NAME>_" to avoid domain name collisions.
228 *
229 *
230 * @param lock which lock to lock
231 *
232 * @param status_cb the callback for signalling when the lock is acquired and
233 * when it is lost
234 *
235 * @param status_cb_cls the closure to the above callback
236 *
237 * @return the locking request handle for this request. It will be invalidated
238 * when status_cb is called.
239 */
240struct GNUNET_LOCKMANAGER_LockingRequest *
241GNUNET_LOCKMANAGER_acquire_lock (struct GNUNET_LOCKMANAGER_Handle *handle,
242 const char *domain_name,
243 uint32_t lock,
244 GNUNET_LOCKMANAGER_StatusCallback
245 status_cb,
246 void *status_cb_cls)
247{
248 struct GNUNET_LOCKMANAGER_LockingRequest *r;
249 struct GNUNET_LOCKMANAGER_Message *msg;
250 uint16_t msg_size;
251
252
253 r = GNUNET_malloc (sizeof (struct GNUNET_LOCKMANAGER_LockingRequest));
254 r->domain_name_length = strlen (domain_name) + 1;
255 r->handle = handle;
256 r->lock = lock;
257 r->domain = GNUNET_malloc (r->domain_name_length);
258 memcpy (r->domain, domain_name, r->domain_name_length);
79 259
260 msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message) + r->domain_name_length;
261 msg = GNUNET_malloc (msg_size);
262 msg->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE);
263 msg->header.size = htons (msg_size);
264 msg->lock = htonl (lock);
265 memcpy (&msg[1], r->domain, r->domain_name_length);
266
267 r->transmit_handle =
268 GNUNET_CLIENT_notify_transmit_ready (r->handle->conn,
269 msg_size,
270 TIMEOUT,
271 GNUNET_NO,
272 *transmit_notify,
273 msg);
274 return r;
275}
276
277
278
279/**
280 * Function to cancel the locking request generated by
281 * GNUNET_LOCKMANAGER_acquire_lock. If the lock is acquired us then the lock is
282 * released. GNUNET_LOCKMANAGER_StatusCallback will not be called upon any
283 * status changes resulting due to this call.
284 *
285 * @param request the LockingRequest to cancel
286 */
287void
288GNUNET_LOCKMANAGER_cancel_request (struct GNUNET_LOCKMANAGER_LockingRequest
289 *request)
290{
291 /* FIXME: Stop ACQUIRE retransmissions */
292 if (GNUNET_LOCKMANAGER_SUCCESS == request->status)
293 {
294 struct GNUNET_LOCKMANAGER_Message *msg;
295 uint16_t msg_size;
296
297 msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message)
298 + request->domain_name_length;
299 msg = GNUNET_malloc (msg_size);
300 msg->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_RELEASE);
301 msg->header.size = htons (msg_size);
302 msg->lock = htonl (request->lock);
303 memcpy (&msg[1], request->domain, request->domain_name_length);
304
305 GNUNET_CLIENT_notify_transmit_ready (request->handle->conn,
306 msg_size,
307 TIMEOUT, /* What if this fails */
308 GNUNET_NO,
309 &transmit_notify,
310 msg);
311 }
312 GNUNET_free (request);
80} 313}