diff options
author | Christian Grothoff <christian@grothoff.org> | 2010-05-06 19:59:59 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2010-05-06 19:59:59 +0000 |
commit | 7db4f64461a77f19bb39f1b84d26f96e6acf40ab (patch) | |
tree | 7d2adef1cebe18d80806bba3d534e9a1e4a44ac6 /src/util/crypto_hash.c | |
parent | 0ece77aca2114b6e5ec153477fccb43ceb807c77 (diff) | |
download | gnunet-7db4f64461a77f19bb39f1b84d26f96e6acf40ab.tar.gz gnunet-7db4f64461a77f19bb39f1b84d26f96e6acf40ab.zip |
allow file hashing cancellation -- and make use of it
Diffstat (limited to 'src/util/crypto_hash.c')
-rw-r--r-- | src/util/crypto_hash.c | 76 |
1 files changed, 57 insertions, 19 deletions
diff --git a/src/util/crypto_hash.c b/src/util/crypto_hash.c index dcee545f7..60104b604 100644 --- a/src/util/crypto_hash.c +++ b/src/util/crypto_hash.c | |||
@@ -372,7 +372,7 @@ GNUNET_CRYPTO_hash (const void *block, size_t size, GNUNET_HashCode * ret) | |||
372 | /** | 372 | /** |
373 | * Context used when hashing a file. | 373 | * Context used when hashing a file. |
374 | */ | 374 | */ |
375 | struct FileHashContext | 375 | struct GNUNET_CRYPTO_FileHashContext |
376 | { | 376 | { |
377 | 377 | ||
378 | /** | 378 | /** |
@@ -396,14 +396,19 @@ struct FileHashContext | |||
396 | char *filename; | 396 | char *filename; |
397 | 397 | ||
398 | /** | 398 | /** |
399 | * Cummulated hash. | 399 | * File descriptor. |
400 | */ | 400 | */ |
401 | struct sha512_ctx hctx; | 401 | struct GNUNET_DISK_FileHandle *fh; |
402 | 402 | ||
403 | /** | 403 | /** |
404 | * Blocksize. | 404 | * Our scheduler. |
405 | */ | 405 | */ |
406 | size_t bsize; | 406 | struct GNUNET_SCHEDULER_Handle *sched; |
407 | |||
408 | /** | ||
409 | * Cummulated hash. | ||
410 | */ | ||
411 | struct sha512_ctx hctx; | ||
407 | 412 | ||
408 | /** | 413 | /** |
409 | * Size of the file. | 414 | * Size of the file. |
@@ -416,9 +421,14 @@ struct FileHashContext | |||
416 | uint64_t offset; | 421 | uint64_t offset; |
417 | 422 | ||
418 | /** | 423 | /** |
419 | * File descriptor. | 424 | * Current task for hashing. |
420 | */ | 425 | */ |
421 | struct GNUNET_DISK_FileHandle *fh; | 426 | GNUNET_SCHEDULER_TaskIdentifier task; |
427 | |||
428 | /** | ||
429 | * Blocksize. | ||
430 | */ | ||
431 | size_t bsize; | ||
422 | 432 | ||
423 | }; | 433 | }; |
424 | 434 | ||
@@ -428,7 +438,8 @@ struct FileHashContext | |||
428 | * and free associated resources. | 438 | * and free associated resources. |
429 | */ | 439 | */ |
430 | static void | 440 | static void |
431 | file_hash_finish (struct FileHashContext *fhc, const GNUNET_HashCode * res) | 441 | file_hash_finish (struct GNUNET_CRYPTO_FileHashContext *fhc, |
442 | const GNUNET_HashCode * res) | ||
432 | { | 443 | { |
433 | fhc->callback (fhc->callback_cls, res); | 444 | fhc->callback (fhc->callback_cls, res); |
434 | GNUNET_free (fhc->filename); | 445 | GNUNET_free (fhc->filename); |
@@ -447,10 +458,11 @@ file_hash_finish (struct FileHashContext *fhc, const GNUNET_HashCode * res) | |||
447 | static void | 458 | static void |
448 | file_hash_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 459 | file_hash_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
449 | { | 460 | { |
450 | struct FileHashContext *fhc = cls; | 461 | struct GNUNET_CRYPTO_FileHashContext *fhc = cls; |
451 | GNUNET_HashCode res; | 462 | GNUNET_HashCode res; |
452 | size_t delta; | 463 | size_t delta; |
453 | 464 | ||
465 | fhc->task = GNUNET_SCHEDULER_NO_TASK; | ||
454 | GNUNET_assert (fhc->offset < fhc->fsize); | 466 | GNUNET_assert (fhc->offset < fhc->fsize); |
455 | delta = fhc->bsize; | 467 | delta = fhc->bsize; |
456 | if (fhc->fsize - fhc->offset < delta) | 468 | if (fhc->fsize - fhc->offset < delta) |
@@ -470,8 +482,10 @@ file_hash_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
470 | file_hash_finish (fhc, &res); | 482 | file_hash_finish (fhc, &res); |
471 | return; | 483 | return; |
472 | } | 484 | } |
473 | GNUNET_SCHEDULER_add_after (tc->sched, | 485 | fhc->task |
474 | GNUNET_SCHEDULER_NO_TASK, &file_hash_task, fhc); | 486 | = GNUNET_SCHEDULER_add_after (tc->sched, |
487 | GNUNET_SCHEDULER_NO_TASK, | ||
488 | &file_hash_task, fhc); | ||
475 | } | 489 | } |
476 | 490 | ||
477 | 491 | ||
@@ -484,8 +498,9 @@ file_hash_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
484 | * @param blocksize number of bytes to process in one task | 498 | * @param blocksize number of bytes to process in one task |
485 | * @param callback function to call upon completion | 499 | * @param callback function to call upon completion |
486 | * @param callback_cls closure for callback | 500 | * @param callback_cls closure for callback |
501 | * @return NULL on (immediate) errror | ||
487 | */ | 502 | */ |
488 | void | 503 | struct GNUNET_CRYPTO_FileHashContext * |
489 | GNUNET_CRYPTO_hash_file (struct GNUNET_SCHEDULER_Handle *sched, | 504 | GNUNET_CRYPTO_hash_file (struct GNUNET_SCHEDULER_Handle *sched, |
490 | enum GNUNET_SCHEDULER_Priority priority, | 505 | enum GNUNET_SCHEDULER_Priority priority, |
491 | const char *filename, | 506 | const char *filename, |
@@ -493,12 +508,13 @@ GNUNET_CRYPTO_hash_file (struct GNUNET_SCHEDULER_Handle *sched, | |||
493 | GNUNET_CRYPTO_HashCompletedCallback callback, | 508 | GNUNET_CRYPTO_HashCompletedCallback callback, |
494 | void *callback_cls) | 509 | void *callback_cls) |
495 | { | 510 | { |
496 | struct FileHashContext *fhc; | 511 | struct GNUNET_CRYPTO_FileHashContext *fhc; |
497 | 512 | ||
498 | GNUNET_assert (blocksize > 0); | 513 | GNUNET_assert (blocksize > 0); |
499 | fhc = GNUNET_malloc (sizeof (struct FileHashContext) + blocksize); | 514 | fhc = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_FileHashContext) + blocksize); |
500 | fhc->callback = callback; | 515 | fhc->callback = callback; |
501 | fhc->callback_cls = callback_cls; | 516 | fhc->callback_cls = callback_cls; |
517 | fhc->sched = sched; | ||
502 | fhc->buffer = (unsigned char *) &fhc[1]; | 518 | fhc->buffer = (unsigned char *) &fhc[1]; |
503 | fhc->filename = GNUNET_strdup (filename); | 519 | fhc->filename = GNUNET_strdup (filename); |
504 | fhc->fh = NULL; | 520 | fhc->fh = NULL; |
@@ -506,21 +522,43 @@ GNUNET_CRYPTO_hash_file (struct GNUNET_SCHEDULER_Handle *sched, | |||
506 | fhc->bsize = blocksize; | 522 | fhc->bsize = blocksize; |
507 | if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fhc->fsize, GNUNET_NO)) | 523 | if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fhc->fsize, GNUNET_NO)) |
508 | { | 524 | { |
509 | file_hash_finish (fhc, NULL); | 525 | GNUNET_free (fhc->filename); |
510 | return; | 526 | GNUNET_free (fhc); |
527 | return NULL; | ||
511 | } | 528 | } |
512 | fhc->fh = GNUNET_DISK_file_open (filename, | 529 | fhc->fh = GNUNET_DISK_file_open (filename, |
513 | GNUNET_DISK_OPEN_READ, | 530 | GNUNET_DISK_OPEN_READ, |
514 | GNUNET_DISK_PERM_NONE); | 531 | GNUNET_DISK_PERM_NONE); |
515 | if (!fhc->fh) | 532 | if (!fhc->fh) |
516 | { | 533 | { |
517 | file_hash_finish (fhc, NULL); | 534 | GNUNET_free (fhc->filename); |
518 | return; | 535 | GNUNET_free (fhc); |
536 | return NULL; | ||
519 | } | 537 | } |
520 | GNUNET_SCHEDULER_add_with_priority (sched, priority, &file_hash_task, fhc); | 538 | fhc->task |
539 | = GNUNET_SCHEDULER_add_with_priority (sched, priority, | ||
540 | &file_hash_task, fhc); | ||
541 | return fhc; | ||
542 | } | ||
543 | |||
544 | |||
545 | /** | ||
546 | * Cancel a file hashing operation. | ||
547 | * | ||
548 | * @param fhc operation to cancel (callback must not yet have been invoked) | ||
549 | */ | ||
550 | void | ||
551 | GNUNET_CRYPTO_hash_file_cancel (struct GNUNET_CRYPTO_FileHashContext *fhc) | ||
552 | { | ||
553 | GNUNET_SCHEDULER_cancel (fhc->sched, | ||
554 | fhc->task); | ||
555 | GNUNET_free (fhc->filename); | ||
556 | GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fhc->fh)); | ||
557 | GNUNET_free (fhc); | ||
521 | } | 558 | } |
522 | 559 | ||
523 | 560 | ||
561 | |||
524 | /* ***************** binary-ASCII encoding *************** */ | 562 | /* ***************** binary-ASCII encoding *************** */ |
525 | 563 | ||
526 | /** | 564 | /** |