diff options
author | Sree Harsha Totakura <totakura@in.tum.de> | 2012-04-26 20:49:58 +0000 |
---|---|---|
committer | Sree Harsha Totakura <totakura@in.tum.de> | 2012-04-26 20:49:58 +0000 |
commit | c1c0db0e9591de979b6572eb41bdd99f3cb6613d (patch) | |
tree | 08df1e643470afc6e8996224e0cf8522e1ac51a6 /src/lockmanager | |
parent | 01c524d5a9d16305e6d6a14000da2635548e96a0 (diff) | |
download | gnunet-c1c0db0e9591de979b6572eb41bdd99f3cb6613d.tar.gz gnunet-c1c0db0e9591de979b6572eb41bdd99f3cb6613d.zip |
-extended lockmanager api
Diffstat (limited to 'src/lockmanager')
-rw-r--r-- | src/lockmanager/lockmanager_api.c | 237 |
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 | */ | ||
58 | struct 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 | */ | ||
108 | static void | ||
109 | handle_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 | */ | ||
128 | static void | ||
129 | handle_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 | */ | ||
146 | static size_t | ||
147 | transmit_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) | |||
76 | void | 208 | void |
77 | GNUNET_LOCKMANAGER_disconnect (struct GNUNET_LOCKMANAGER_Handle *handle) | 209 | GNUNET_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 | */ | ||
240 | struct GNUNET_LOCKMANAGER_LockingRequest * | ||
241 | GNUNET_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 | */ | ||
287 | void | ||
288 | GNUNET_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 | } |