aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2009-08-29 20:58:34 +0000
committerChristian Grothoff <christian@grothoff.org>2009-08-29 20:58:34 +0000
commit70e446850e82317805db0a2f1508e3edc81b6a7f (patch)
tree651dcd40fe9148256f2d5de239e40e31ce3661d9
parent61b1c378568bbf7ca7cb1a51d2f1920d5d36fd26 (diff)
downloadgnunet-70e446850e82317805db0a2f1508e3edc81b6a7f.tar.gz
gnunet-70e446850e82317805db0a2f1508e3edc81b6a7f.zip
more
-rw-r--r--src/fs/fs.h11
-rw-r--r--src/fs/fs_file_information.c1
-rw-r--r--src/fs/fs_publish.c136
-rw-r--r--src/include/gnunet_fs_service.h24
-rw-r--r--src/util/time.c2
5 files changed, 166 insertions, 8 deletions
diff --git a/src/fs/fs.h b/src/fs/fs.h
index 3c92b42ae..3f1ffad30 100644
--- a/src/fs/fs.h
+++ b/src/fs/fs.h
@@ -220,6 +220,11 @@ struct GNUNET_FS_FileInformation
220 struct GNUNET_TIME_Absolute expirationTime; 220 struct GNUNET_TIME_Absolute expirationTime;
221 221
222 /** 222 /**
223 * At what time did we start this upload?
224 */
225 struct GNUNET_TIME_Absolute start_time;
226
227 /**
223 * Under what filename is this struct serialized 228 * Under what filename is this struct serialized
224 * (for operational persistence). 229 * (for operational persistence).
225 */ 230 */
@@ -237,6 +242,12 @@ struct GNUNET_FS_FileInformation
237 * finally freed once the upload is complete. 242 * finally freed once the upload is complete.
238 */ 243 */
239 struct ContentHashKey *chk_tree; 244 struct ContentHashKey *chk_tree;
245
246 /**
247 * Error message (non-NULL if this operation
248 * failed).
249 */
250 char *emsg;
240 251
241 /** 252 /**
242 * Number of entries in "chk_tree". 253 * Number of entries in "chk_tree".
diff --git a/src/fs/fs_file_information.c b/src/fs/fs_file_information.c
index 60bcc2529..e72f42f9a 100644
--- a/src/fs/fs_file_information.c
+++ b/src/fs/fs_file_information.c
@@ -822,6 +822,7 @@ GNUNET_FS_file_information_destroy (struct GNUNET_FS_FileInformation *fi,
822 &fi->expirationTime, 822 &fi->expirationTime,
823 &fi->client_info); 823 &fi->client_info);
824 } 824 }
825 GNUNET_free_non_null (fi->emsg);
825 GNUNET_free_non_null (fi->chk_tree); 826 GNUNET_free_non_null (fi->chk_tree);
826 /* clean up serialization */ 827 /* clean up serialization */
827 if (0 != UNLINK (fi->serialization)) 828 if (0 != UNLINK (fi->serialization))
diff --git a/src/fs/fs_publish.c b/src/fs/fs_publish.c
index f5c2b4cdc..eae97b1d8 100644
--- a/src/fs/fs_publish.c
+++ b/src/fs/fs_publish.c
@@ -76,6 +76,38 @@ struct PutContCtx
76 GNUNET_SCHEDULER_Task cont; 76 GNUNET_SCHEDULER_Task cont;
77}; 77};
78 78
79
80/**
81 * Fill in all of the generic fields for
82 * a publish event.
83 *
84 * @param pc structure to fill in
85 * @param sc overall publishing context
86 * @param p file information for the file being published
87 */
88static void
89make_publish_status (struct GNUNET_FS_ProgressInfo *pi,
90 struct GNUNET_FS_PublishContext *sc,
91 const struct GNUNET_FS_FileInformation *p)
92{
93 pi->value.publish.sc = sc;
94 pi->value.publish.fi = p;
95 pi->value.publish.cctx
96 = p->client_info;
97 pi->value.publish.pctx
98 = (NULL == p->dir) ? NULL : p->dir->client_info;
99 pi->value.publish.size
100 = (p->is_directory) ? p->data.dir.dir_size : p->data.file.file_size;
101 pi->value.publish.eta
102 = GNUNET_TIME_calculate_eta (p->start_time,
103 p->publish_offset,
104 pi->value.publish.size);
105 pi->value.publish.duration = GNUNET_TIME_absolute_get_duration (p->start_time);
106 pi->value.publish.completed = p->publish_offset;
107 pi->value.publish.anonymity = p->anonymity;
108}
109
110
79/** 111/**
80 * Function called by the datastore API with 112 * Function called by the datastore API with
81 * the result from the PUT request. 113 * the result from the PUT request.
@@ -90,12 +122,20 @@ ds_put_cont (void *cls,
90 const char *msg) 122 const char *msg)
91{ 123{
92 struct PutContCtx *pcc = cls; 124 struct PutContCtx *pcc = cls;
125 struct GNUNET_FS_ProgressInfo pi;
93 126
94 if (GNUNET_OK != success) 127 if (GNUNET_OK != success)
95 { 128 {
96 // FIXME: call progress CB with error 129 GNUNET_asprintf (&pcc->p->emsg,
97 // FIXME: update pcc->p to indicate abort 130 _("Upload failed: %s"),
131 msg);
98 GNUNET_FS_file_information_sync (pcc->p); 132 GNUNET_FS_file_information_sync (pcc->p);
133 pi.status = GNUNET_FS_STATUS_PUBLISH_ERROR;
134 make_publish_status (&pi, pcc->sc, pcc->p);
135 pi.value.publish.eta = GNUNET_TIME_UNIT_FOREVER_REL;
136 pi.value.publish.specifics.error.message = pcc->p->emsg;
137 pcc->sc->h->upcb (pcc->sc->h->upcb_cls,
138 &pi);
99 return; 139 return;
100 } 140 }
101 GNUNET_FS_file_information_sync (pcc->p); 141 GNUNET_FS_file_information_sync (pcc->p);
@@ -159,6 +199,29 @@ publish_block (struct GNUNET_FS_PublishContext *sc,
159 199
160 200
161/** 201/**
202 * Generate the callback that signals clients
203 * that a file (or directory) has been completely
204 * published.
205 *
206 * @param p the completed upload
207 * @param sc context of the publication
208 */
209static void
210signal_publish_completion (struct GNUNET_FS_FileInformation *p,
211 struct GNUNET_FS_PublishContext *sc)
212{
213 struct GNUNET_FS_ProgressInfo pi;
214
215 pi.status = GNUNET_FS_STATUS_PUBLISH_COMPLETED;
216 make_publish_status (&pi, sc, p);
217 pi.value.publish.eta = GNUNET_TIME_UNIT_ZERO;
218 pi.value.publish.specifics.completed.chk_uri = p->chk_uri;
219 sc->h->upcb (sc->h->upcb_cls,
220 &pi);
221}
222
223
224/**
162 * We are almost done publishing the structure, 225 * We are almost done publishing the structure,
163 * add SBlocks (if needed). 226 * add SBlocks (if needed).
164 * 227 *
@@ -175,6 +238,8 @@ publish_sblock (struct GNUNET_FS_PublishContext *sc)
175 // FIXME: continuation should 238 // FIXME: continuation should
176 // be releasing the datastore reserve 239 // be releasing the datastore reserve
177 // (once implemented) 240 // (once implemented)
241 // FIXME: finally, signal overall completion
242 signal_publish_completion (p, sc);
178} 243}
179 244
180 245
@@ -194,6 +259,12 @@ publish_kblocks (struct GNUNET_FS_PublishContext *sc,
194{ 259{
195 // FIXME: build all kblocks 260 // FIXME: build all kblocks
196 // call publish_kblock on each 261 // call publish_kblock on each
262
263
264 GNUNET_FS_file_information_sync (p);
265 if (NULL != p->dir)
266 signal_publish_completion (p, sc);
267
197 // last continuation should then call the main continuation again 268 // last continuation should then call the main continuation again
198} 269}
199 270
@@ -306,6 +377,7 @@ static void
306publish_content (struct GNUNET_FS_PublishContext *sc, 377publish_content (struct GNUNET_FS_PublishContext *sc,
307 struct GNUNET_FS_FileInformation *p) 378 struct GNUNET_FS_FileInformation *p)
308{ 379{
380 struct GNUNET_FS_ProgressInfo pi;
309 struct ContentHashKey *mychk; 381 struct ContentHashKey *mychk;
310 const void *pt_block; 382 const void *pt_block;
311 uint16_t pt_size; 383 uint16_t pt_size;
@@ -397,8 +469,27 @@ publish_content (struct GNUNET_FS_PublishContext *sc,
397 iob, 469 iob,
398 &emsg)) 470 &emsg))
399 { 471 {
400 // FIXME: abort with error "emsg" 472 GNUNET_asprintf (&p->emsg,
473 _("Upload failed: %s"),
474 emsg);
401 GNUNET_free (emsg); 475 GNUNET_free (emsg);
476 GNUNET_FS_file_information_sync (p);
477 pi.status = GNUNET_FS_STATUS_PUBLISH_ERROR;
478 make_publish_status (&pi, sc, p);
479 pi.value.publish.eta = GNUNET_TIME_UNIT_FOREVER_REL;
480 pi.value.publish.specifics.error.message = p->emsg;
481 sc->h->upcb (sc->h->upcb_cls,
482 &pi);
483 /* continue with main (to propagate error up) */
484 sc->upload_task
485 = GNUNET_SCHEDULER_add_delayed (sc->h->sched,
486 GNUNET_NO,
487 GNUNET_SCHEDULER_PRIORITY_BACKGROUND,
488 GNUNET_SCHEDULER_NO_TASK,
489 GNUNET_TIME_UNIT_ZERO,
490 &do_upload,
491 sc);
492 return;
402 } 493 }
403 pt_block = iob; 494 pt_block = iob;
404 } 495 }
@@ -432,7 +523,16 @@ publish_content (struct GNUNET_FS_PublishContext *sc,
432 ? GNUNET_DATASTORE_BLOCKTYPE_DBLOCK 523 ? GNUNET_DATASTORE_BLOCKTYPE_DBLOCK
433 : GNUNET_DATASTORE_BLOCKTYPE_IBLOCK, 524 : GNUNET_DATASTORE_BLOCKTYPE_IBLOCK,
434 &do_upload); 525 &do_upload);
435 // FIXME: should call progress function somewhere here! 526 if (p->current_depth == p->chk_tree_depth)
527 {
528 pi.status = GNUNET_FS_STATUS_PUBLISH_PROGRESS;
529 make_publish_status (&pi, sc, p);
530 pi.value.publish.specifics.progress.data = pt_block;
531 pi.value.publish.specifics.progress.offset = p->publish_offset;
532 pi.value.publish.specifics.progress.data_len = pt_size;
533 sc->h->upcb (sc->h->upcb_cls,
534 &pi);
535 }
436 GNUNET_CRYPTO_hash (enc, pt_size, &mychk->query); 536 GNUNET_CRYPTO_hash (enc, pt_size, &mychk->query);
437 if (p->current_depth == p->chk_tree_depth) 537 if (p->current_depth == p->chk_tree_depth)
438 { 538 {
@@ -471,7 +571,9 @@ do_upload (void *cls,
471 const struct GNUNET_SCHEDULER_TaskContext *tc) 571 const struct GNUNET_SCHEDULER_TaskContext *tc)
472{ 572{
473 struct GNUNET_FS_PublishContext *sc = cls; 573 struct GNUNET_FS_PublishContext *sc = cls;
574 struct GNUNET_FS_ProgressInfo pi;
474 struct GNUNET_FS_FileInformation *p; 575 struct GNUNET_FS_FileInformation *p;
576 char *fn;
475 577
476 sc->upload_task = GNUNET_SCHEDULER_NO_TASK; 578 sc->upload_task = GNUNET_SCHEDULER_NO_TASK;
477 p = sc->fi_pos; 579 p = sc->fi_pos;
@@ -482,6 +584,29 @@ do_upload (void *cls,
482 publish_sblock (sc); 584 publish_sblock (sc);
483 return; 585 return;
484 } 586 }
587 if (NULL != p->emsg)
588 {
589 /* error with current file, abort all
590 related files as well! */
591 while (NULL != p->dir)
592 {
593 fn = GNUNET_CONTAINER_meta_data_get_by_type (p->meta,
594 EXTRACTOR_FILENAME);
595 p = p->dir;
596 GNUNET_asprintf (&p->emsg,
597 _("Recursive upload failed at `%s'"),
598 fn);
599 GNUNET_free (fn);
600 GNUNET_FS_file_information_sync (p);
601 pi.status = GNUNET_FS_STATUS_PUBLISH_ERROR;
602 make_publish_status (&pi, sc, p);
603 pi.value.publish.eta = GNUNET_TIME_UNIT_FOREVER_REL;
604 pi.value.publish.specifics.error.message = p->emsg;
605 sc->h->upcb (sc->h->upcb_cls,
606 &pi);
607 }
608 return;
609 }
485 if (NULL != p->chk_uri) 610 if (NULL != p->chk_uri)
486 { 611 {
487 /* move on to next file */ 612 /* move on to next file */
@@ -551,6 +676,9 @@ GNUNET_FS_publish_start (struct GNUNET_FS_Handle *h,
551 } 676 }
552 // FIXME: make upload persistent! 677 // FIXME: make upload persistent!
553 678
679 /* signal start */
680
681
554 /* find first leaf, DFS */ 682 /* find first leaf, DFS */
555 p = ret->fi; 683 p = ret->fi;
556 while ( (p->is_directory) && 684 while ( (p->is_directory) &&
diff --git a/src/include/gnunet_fs_service.h b/src/include/gnunet_fs_service.h
index f78ed51e5..6e18e67c8 100644
--- a/src/include/gnunet_fs_service.h
+++ b/src/include/gnunet_fs_service.h
@@ -726,7 +726,7 @@ struct GNUNET_FS_ProgressInfo
726 * (will be a value in the past for completed 726 * (will be a value in the past for completed
727 * uploads). 727 * uploads).
728 */ 728 */
729 struct GNUNET_TIME_Absolute eta; 729 struct GNUNET_TIME_Relative eta;
730 730
731 /** 731 /**
732 * How long has this upload been actively running 732 * How long has this upload been actively running
@@ -782,11 +782,29 @@ struct GNUNET_FS_ProgressInfo
782 * Error message, NULL if no error was encountered so far. 782 * Error message, NULL if no error was encountered so far.
783 */ 783 */
784 const char *message; 784 const char *message;
785
786 /**
787 * URI of the file (if the download had been completed)
788 */
789 const struct GNUNET_FS_Uri *chk_uri;
785 790
786 } resume; 791 } resume;
787 792
788 /** 793 /**
789 * These values are only valid for 794 * These values are only valid for
795 * GNUNET_FS_STATUS_PUBLISH_COMPLETED events.
796 */
797 struct {
798
799 /**
800 * URI of the file.
801 */
802 const struct GNUNET_FS_Uri *chk_uri;
803
804 } completed;
805
806 /**
807 * These values are only valid for
790 * GNUNET_FS_STATUS_PUBLISH_ERROR events. 808 * GNUNET_FS_STATUS_PUBLISH_ERROR events.
791 */ 809 */
792 struct { 810 struct {
@@ -844,7 +862,7 @@ struct GNUNET_FS_ProgressInfo
844 * (will be a value in the past for completed 862 * (will be a value in the past for completed
845 * uploads). 863 * uploads).
846 */ 864 */
847 struct GNUNET_TIME_Absolute eta; 865 struct GNUNET_TIME_Relative eta;
848 866
849 /** 867 /**
850 * How long has this download been active? 868 * How long has this download been active?
@@ -1256,7 +1274,7 @@ struct GNUNET_FS_ProgressInfo
1256 * (will be a value in the past for completed 1274 * (will be a value in the past for completed
1257 * unindexing opeations). 1275 * unindexing opeations).
1258 */ 1276 */
1259 struct GNUNET_TIME_Absolute eta; 1277 struct GNUNET_TIME_Relative eta;
1260 1278
1261 /** 1279 /**
1262 * How long has this upload been actively running 1280 * How long has this upload been actively running
diff --git a/src/util/time.c b/src/util/time.c
index 6b6be7917..f818fc9a1 100644
--- a/src/util/time.c
+++ b/src/util/time.c
@@ -261,7 +261,7 @@ struct GNUNET_TIME_Relative GNUNET_TIME_calculate_eta (struct GNUNET_TIME_Absolu
261 if (finished >= total) 261 if (finished >= total)
262 return GNUNET_TIME_UNIT_ZERO; 262 return GNUNET_TIME_UNIT_ZERO;
263 if (finished == 0) 263 if (finished == 0)
264 return GNUNET_TIME_UNIT_FOREVER; 264 return GNUNET_TIME_UNIT_FOREVER_REL;
265 dur = GNUNET_TIME_absolute_get_duration (start); 265 dur = GNUNET_TIME_absolute_get_duration (start);
266 exp = ((double)dur.value) * ((double) total) / ((double)finished); 266 exp = ((double)dur.value) * ((double) total) / ((double)finished);
267 ret.value = ((uint64_t) exp) - dur.value; 267 ret.value = ((uint64_t) exp) - dur.value;