diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-07-13 11:07:19 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-07-13 11:07:19 +0000 |
commit | c94be01c832866f9c0169963c658e36dd3329cc2 (patch) | |
tree | 6032e13b5c7016f460d4e04e568cb397f28716ca | |
parent | c584d8950bda4b27ccc2fa03de2cee23a8ae56d2 (diff) | |
download | gnunet-c94be01c832866f9c0169963c658e36dd3329cc2.tar.gz gnunet-c94be01c832866f9c0169963c658e36dd3329cc2.zip |
revised fragmentation API for blocking writes
-rw-r--r-- | src/fragmentation/defragmentation_new.c | 6 | ||||
-rw-r--r-- | src/fragmentation/fragmentation_new.c | 30 | ||||
-rw-r--r-- | src/fragmentation/test_fragmentation.c | 7 | ||||
-rw-r--r-- | src/include/gnunet_fragmentation_lib.h | 34 |
4 files changed, 65 insertions, 12 deletions
diff --git a/src/fragmentation/defragmentation_new.c b/src/fragmentation/defragmentation_new.c index 379ec57d4..cc42d3e75 100644 --- a/src/fragmentation/defragmentation_new.c +++ b/src/fragmentation/defragmentation_new.c | |||
@@ -161,7 +161,7 @@ struct GNUNET_DEFRAGMENT_Context | |||
161 | /** | 161 | /** |
162 | * Function to call with acknowledgements. | 162 | * Function to call with acknowledgements. |
163 | */ | 163 | */ |
164 | GNUNET_FRAGMENT_MessageProcessor ackp; | 164 | GNUNET_DEFRAGMENT_AckProcessor ackp; |
165 | 165 | ||
166 | /** | 166 | /** |
167 | * Running average of the latency (delay between messages) for this | 167 | * Running average of the latency (delay between messages) for this |
@@ -207,7 +207,7 @@ GNUNET_DEFRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats, | |||
207 | unsigned int num_msgs, | 207 | unsigned int num_msgs, |
208 | void *cls, | 208 | void *cls, |
209 | GNUNET_FRAGMENT_MessageProcessor proc, | 209 | GNUNET_FRAGMENT_MessageProcessor proc, |
210 | GNUNET_FRAGMENT_MessageProcessor ackp) | 210 | GNUNET_DEFRAGMENT_AckProcessor ackp) |
211 | { | 211 | { |
212 | struct GNUNET_DEFRAGMENT_Context *dc; | 212 | struct GNUNET_DEFRAGMENT_Context *dc; |
213 | 213 | ||
@@ -270,7 +270,7 @@ send_ack (void *cls, | |||
270 | fa.header.type = htons (GNUNET_MESSAGE_TYPE_FRAGMENT_ACK); | 270 | fa.header.type = htons (GNUNET_MESSAGE_TYPE_FRAGMENT_ACK); |
271 | fa.fragment_id = htonl (mc->fragment_id); | 271 | fa.fragment_id = htonl (mc->fragment_id); |
272 | fa.bits = GNUNET_htonll (mc->bits); | 272 | fa.bits = GNUNET_htonll (mc->bits); |
273 | dc->ackp (dc->cls, &fa.header); | 273 | dc->ackp (dc->cls, mc->fragment_id, &fa.header); |
274 | } | 274 | } |
275 | 275 | ||
276 | 276 | ||
diff --git a/src/fragmentation/fragmentation_new.c b/src/fragmentation/fragmentation_new.c index dbbaa859b..db66f5a5b 100644 --- a/src/fragmentation/fragmentation_new.c +++ b/src/fragmentation/fragmentation_new.c | |||
@@ -89,9 +89,14 @@ struct GNUNET_FRAGMENT_Context | |||
89 | unsigned int next_transmission; | 89 | unsigned int next_transmission; |
90 | 90 | ||
91 | /** | 91 | /** |
92 | * GNUNET_YES if we called 'proc' and are now waiting for 'GNUNET_FRAGMENT_transmission_done' | ||
93 | */ | ||
94 | int8_t proc_busy; | ||
95 | |||
96 | /** | ||
92 | * GNUNET_YES if we are waiting for an ACK. | 97 | * GNUNET_YES if we are waiting for an ACK. |
93 | */ | 98 | */ |
94 | int wack; | 99 | int8_t wack; |
95 | 100 | ||
96 | /** | 101 | /** |
97 | * Target fragment size. | 102 | * Target fragment size. |
@@ -122,6 +127,7 @@ transmit_next (void *cls, | |||
122 | int wrap; | 127 | int wrap; |
123 | 128 | ||
124 | fc->task = GNUNET_SCHEDULER_NO_TASK; | 129 | fc->task = GNUNET_SCHEDULER_NO_TASK; |
130 | GNUNET_assert (GNUNET_NO == fc->proc_busy); | ||
125 | if (0 == fc->acks) | 131 | if (0 == fc->acks) |
126 | return; /* all done */ | 132 | return; /* all done */ |
127 | 133 | ||
@@ -194,9 +200,7 @@ transmit_next (void *cls, | |||
194 | fc->last_round = GNUNET_TIME_absolute_get (); | 200 | fc->last_round = GNUNET_TIME_absolute_get (); |
195 | fc->wack = GNUNET_YES; | 201 | fc->wack = GNUNET_YES; |
196 | } | 202 | } |
197 | fc->task = GNUNET_SCHEDULER_add_delayed (delay, | 203 | fc->proc_busy = GNUNET_YES; |
198 | &transmit_next, | ||
199 | fc); | ||
200 | fc->proc (fc->proc_cls, &fh->header); | 204 | fc->proc (fc->proc_cls, &fh->header); |
201 | } | 205 | } |
202 | 206 | ||
@@ -265,6 +269,24 @@ GNUNET_FRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats, | |||
265 | 269 | ||
266 | 270 | ||
267 | /** | 271 | /** |
272 | * Continuation to call from the 'proc' function after the fragment | ||
273 | * has been transmitted (and hence the next fragment can now be | ||
274 | * given to proc). | ||
275 | * | ||
276 | * @param fc fragmentation context | ||
277 | */ | ||
278 | void | ||
279 | GNUNET_FRAGMENT_context_transmission_done (struct GNUNET_FRAGMENT_Context *fc) | ||
280 | { | ||
281 | GNUNET_assert (fc->proc_busy == GNUNET_YES); | ||
282 | fc->proc_busy = GNUNET_NO; | ||
283 | GNUNET_assert (fc->task == GNUNET_SCHEDULER_NO_TASK); | ||
284 | fc->task = GNUNET_SCHEDULER_add_now (&transmit_next, | ||
285 | fc); | ||
286 | } | ||
287 | |||
288 | |||
289 | /** | ||
268 | * Process an acknowledgement message we got from the other | 290 | * Process an acknowledgement message we got from the other |
269 | * side (to control re-transmits). | 291 | * side (to control re-transmits). |
270 | * | 292 | * |
diff --git a/src/fragmentation/test_fragmentation.c b/src/fragmentation/test_fragmentation.c index 8a9af04e7..1a231bbb4 100644 --- a/src/fragmentation/test_fragmentation.c +++ b/src/fragmentation/test_fragmentation.c | |||
@@ -42,7 +42,7 @@ | |||
42 | /** | 42 | /** |
43 | * Simulate dropping of 1 out of how many messages? (must be > 1) | 43 | * Simulate dropping of 1 out of how many messages? (must be > 1) |
44 | */ | 44 | */ |
45 | #define DROPRATE 2 | 45 | #define DROPRATE 10 |
46 | 46 | ||
47 | static int ret = 1; | 47 | static int ret = 1; |
48 | 48 | ||
@@ -102,6 +102,7 @@ proc_msgs (void *cls, | |||
102 | */ | 102 | */ |
103 | static void | 103 | static void |
104 | proc_acks (void *cls, | 104 | proc_acks (void *cls, |
105 | uint32_t msg_id, | ||
105 | const struct GNUNET_MessageHeader *hdr) | 106 | const struct GNUNET_MessageHeader *hdr) |
106 | { | 107 | { |
107 | unsigned int i; | 108 | unsigned int i; |
@@ -150,8 +151,10 @@ static void | |||
150 | proc_frac (void *cls, | 151 | proc_frac (void *cls, |
151 | const struct GNUNET_MessageHeader *hdr) | 152 | const struct GNUNET_MessageHeader *hdr) |
152 | { | 153 | { |
154 | struct GNUNET_FRAGMENT_Context **fc = cls; | ||
153 | int ret; | 155 | int ret; |
154 | 156 | ||
157 | GNUNET_FRAGMENT_context_transmission_done (*fc); | ||
155 | if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, DROPRATE)) | 158 | if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, DROPRATE)) |
156 | { | 159 | { |
157 | frag_drops++; | 160 | frag_drops++; |
@@ -211,7 +214,7 @@ run (void *cls, | |||
211 | GNUNET_TIME_UNIT_SECONDS, | 214 | GNUNET_TIME_UNIT_SECONDS, |
212 | msg, | 215 | msg, |
213 | &proc_frac, | 216 | &proc_frac, |
214 | NULL); | 217 | &frags[i]); |
215 | } | 218 | } |
216 | } | 219 | } |
217 | 220 | ||
diff --git a/src/include/gnunet_fragmentation_lib.h b/src/include/gnunet_fragmentation_lib.h index bb29a5fba..e91e74c6f 100644 --- a/src/include/gnunet_fragmentation_lib.h +++ b/src/include/gnunet_fragmentation_lib.h | |||
@@ -49,8 +49,10 @@ struct GNUNET_FRAGMENT_Context; | |||
49 | 49 | ||
50 | 50 | ||
51 | /** | 51 | /** |
52 | * Function that is called with messages | 52 | * Function that is called with messages created by the fragmentation |
53 | * created by the fragmentation module. | 53 | * module. In the case of the 'proc' callback of the |
54 | * GNUNET_FRAGMENT_context_create function, this function must | ||
55 | * eventually call 'GNUNET_FRAGMENT_context_transmission_done'. | ||
54 | * | 56 | * |
55 | * @param cls closure | 57 | * @param cls closure |
56 | * @param msg the message that was created | 58 | * @param msg the message that was created |
@@ -88,6 +90,17 @@ GNUNET_FRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats, | |||
88 | 90 | ||
89 | 91 | ||
90 | /** | 92 | /** |
93 | * Continuation to call from the 'proc' function after the fragment | ||
94 | * has been transmitted (and hence the next fragment can now be | ||
95 | * given to proc). | ||
96 | * | ||
97 | * @param fc fragmentation context | ||
98 | */ | ||
99 | void | ||
100 | GNUNET_FRAGMENT_context_transmission_done (struct GNUNET_FRAGMENT_Context *fc); | ||
101 | |||
102 | |||
103 | /** | ||
91 | * Process an acknowledgement message we got from the other | 104 | * Process an acknowledgement message we got from the other |
92 | * side (to control re-transmits). | 105 | * side (to control re-transmits). |
93 | * | 106 | * |
@@ -121,6 +134,21 @@ struct GNUNET_DEFRAGMENT_Context; | |||
121 | 134 | ||
122 | 135 | ||
123 | /** | 136 | /** |
137 | * Function that is called with acknowledgement messages created by | ||
138 | * the fragmentation module. Acknowledgements are cummulative, | ||
139 | * so it is OK to only transmit the 'latest' ack message for the same | ||
140 | * message ID. | ||
141 | * | ||
142 | * @param cls closure | ||
143 | * @param id unique message ID (modulo collisions) | ||
144 | * @param msg the message that was created | ||
145 | */ | ||
146 | typedef void (*GNUNET_DEFRAGMENT_AckProcessor) (void *cls, | ||
147 | uint32_t id, | ||
148 | const struct GNUNET_MessageHeader *msg); | ||
149 | |||
150 | |||
151 | /** | ||
124 | * Create a defragmentation context. | 152 | * Create a defragmentation context. |
125 | * | 153 | * |
126 | * @param stats statistics context | 154 | * @param stats statistics context |
@@ -139,7 +167,7 @@ GNUNET_DEFRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats, | |||
139 | unsigned int num_msgs, | 167 | unsigned int num_msgs, |
140 | void *cls, | 168 | void *cls, |
141 | GNUNET_FRAGMENT_MessageProcessor proc, | 169 | GNUNET_FRAGMENT_MessageProcessor proc, |
142 | GNUNET_FRAGMENT_MessageProcessor ackp); | 170 | GNUNET_DEFRAGMENT_AckProcessor ackp); |
143 | 171 | ||
144 | 172 | ||
145 | /** | 173 | /** |