mutt stable branch with some hacks
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Compress: pull the lock/unlock operations into the open,close,sync operations.

Some operations, such as open_append and sync, need an exclusive lock
across a longer period than a single compress/decompress. Remove it
from the execute_command and pull into the outer callers. Store lock
information inside compress_info.

Sync and check_mailbox need more fixes, which will be addressed in
subsequent patches.

+73 -50
+73 -50
compress.c
··· 49 49 const char *open; /* open-hook command */ 50 50 off_t size; /* size of the compressed file */ 51 51 struct mx_ops *child_ops; /* callbacks of de-compressed file */ 52 + int locked; /* if realpath is locked */ 53 + FILE *lockfp; /* fp used for locking */ 52 54 } COMPRESS_INFO; 53 55 54 56 55 57 /** 56 - * lock_mailbox - Try to lock a mailbox (exclusively) 58 + * lock_realpath - Try to lock the ctx->realpath 57 59 * @ctx: Mailbox to lock 58 - * @fp: File pointer to the mailbox file 59 60 * @excl: Lock exclusively? 60 61 * 61 62 * Try to (exclusively) lock the mailbox. If we succeed, then we mark the ··· 67 68 * 0: Error (can't lock the file) 68 69 */ 69 70 static int 70 - lock_mailbox (CONTEXT *ctx, FILE *fp, int excl) 71 + lock_realpath (CONTEXT *ctx, int excl) 71 72 { 72 - if (!ctx || !fp) 73 + if (!ctx) 73 74 return 0; 74 75 75 - int r = mx_lock_file (ctx->realpath, fileno (fp), excl, 1, 1); 76 + COMPRESS_INFO *ci = ctx->compress_info; 77 + if (!ci) 78 + return 0; 79 + 80 + if (ci->locked) 81 + return 1; 76 82 77 - if (r == 0) 83 + if (excl) 84 + ci->lockfp = fopen (ctx->realpath, "a"); 85 + else 86 + ci->lockfp = fopen (ctx->realpath, "r"); 87 + if (!ci->lockfp) 78 88 { 79 - ctx->locked = 1; 89 + mutt_perror (ctx->realpath); 90 + return 0; 80 91 } 92 + 93 + int r = mx_lock_file (ctx->realpath, fileno (ci->lockfp), excl, 1, 1); 94 + 95 + if (r == 0) 96 + ci->locked = 1; 81 97 else if (excl == 0) 82 98 { 99 + safe_fclose (&ci->lockfp); 83 100 ctx->readonly = 1; 84 101 return 1; 85 102 } ··· 88 105 } 89 106 90 107 /** 91 - * unlock_mailbox - Unlock a mailbox 108 + * unlock_realpath - Unlock the ctx->realpath 92 109 * @ctx: Mailbox to unlock 93 - * @fp: File pointer to mailbox file 94 110 * 95 111 * Unlock a mailbox previously locked by lock_mailbox(). 96 112 */ 97 113 static void 98 - unlock_mailbox (CONTEXT *ctx, FILE *fp) 114 + unlock_realpath (CONTEXT *ctx) 99 115 { 100 - if (!ctx || !fp) 116 + if (!ctx) 117 + return; 118 + 119 + COMPRESS_INFO *ci = ctx->compress_info; 120 + if (!ci) 101 121 return; 102 122 103 - if (!ctx->locked) 123 + if (!ci->locked) 104 124 return; 105 125 106 - fflush (fp); 126 + mx_unlock_file (ctx->realpath, fileno (ci->lockfp), 1); 107 127 108 - mx_unlock_file (ctx->realpath, fileno (fp), 1); 109 - ctx->locked = 0; 128 + ci->locked = 0; 129 + safe_fclose (&ci->lockfp); 110 130 } 111 131 112 132 /** ··· 270 290 FREE (&ci->close); 271 291 FREE (&ci->append); 272 292 293 + unlock_realpath (ctx); 294 + 273 295 FREE (&ctx->compress_info); 274 296 } 275 297 ··· 345 367 * execute_command - Run a system command 346 368 * @ctx: Mailbox to work with 347 369 * @command: Command string to execute 348 - * @create_file: Should the tmp file be created? 349 370 * @progress: Message to show the user 350 371 * 351 372 * Run the supplied command, taking care of all the Mutt requirements, ··· 356 377 * 0: Failure 357 378 */ 358 379 static int 359 - execute_command (CONTEXT *ctx, const char *command, int create_file, const char *progress) 380 + execute_command (CONTEXT *ctx, const char *command, const char *progress) 360 381 { 361 - FILE *fp; 362 - int rc = 0; 363 - int unlock = 0; 382 + int rc = 1; 364 383 char sys_cmd[HUGE_STRING]; 365 384 366 385 if (!ctx || !command || !progress) ··· 369 388 if (!ctx->quiet) 370 389 mutt_message (progress, ctx->realpath); 371 390 372 - if (create_file) 373 - fp = fopen (ctx->realpath, "a"); 374 - else 375 - fp = fopen (ctx->realpath, "r"); 376 - if (!fp) 377 - { 378 - mutt_perror (ctx->realpath); 379 - return 0; 380 - } 381 - 382 391 mutt_block_signals(); 383 - /* If we're creating the file, lock it exclusively */ 384 - if (!lock_mailbox (ctx, fp, create_file)) 385 - { 386 - mutt_error (_("Unable to lock mailbox!")); 387 - goto cleanup; 388 - } 389 - 390 - unlock = 1; 391 392 endwin(); 392 393 fflush (stdout); 393 394 ··· 395 396 396 397 if (mutt_system (sys_cmd) != 0) 397 398 { 399 + rc = 0; 398 400 mutt_any_key_to_continue (NULL); 399 401 mutt_error (_("Error executing: %s\n"), sys_cmd); 400 - goto cleanup; 401 402 } 402 403 403 - rc = 1; 404 - 405 - cleanup: 406 - if (unlock) 407 - unlock_mailbox (ctx, fp); 408 404 mutt_unblock_signals(); 409 - safe_fclose (&fp); 410 405 411 406 return rc; 412 407 } ··· 438 433 goto or_fail; 439 434 store_size (ctx); 440 435 441 - int rc = execute_command (ctx, ci->open, 0, _("Decompressing %s")); 436 + if (!lock_realpath (ctx, 0)) 437 + { 438 + mutt_error (_("Unable to lock mailbox!")); 439 + goto or_fail; 440 + } 441 + 442 + int rc = execute_command (ctx, ci->open, _("Decompressing %s")); 442 443 if (rc == 0) 443 444 goto or_fail; 444 445 446 + unlock_realpath (ctx); 447 + 445 448 ctx->magic = mx_get_magic (ctx->path); 446 449 if (ctx->magic == 0) 447 450 { ··· 511 514 goto oa_fail2; 512 515 } 513 516 517 + /* Lock the realpath for the duration of the append. 518 + * It will be unlocked in the close */ 519 + if (!lock_realpath (ctx, 1)) 520 + { 521 + mutt_error (_("Unable to lock mailbox!")); 522 + goto oa_fail2; 523 + } 524 + 514 525 /* Open the existing mailbox, unless we are appending */ 515 - if (!ci->append && (access (ctx->realpath, F_OK) == 0)) 526 + if (!ci->append && (get_size (ctx->realpath) > 0)) 516 527 { 517 - int rc = execute_command (ctx, ci->open, 0, _("Decompressing %s")); 528 + int rc = execute_command (ctx, ci->open, _("Decompressing %s")); 518 529 if (rc == 0) 519 530 { 520 531 mutt_error (_("Compress command failed: %s"), ci->open); ··· 595 606 msg = _("Compressing %s..."); 596 607 } 597 608 598 - int rc = execute_command (ctx, append, 1, msg); 609 + int rc = execute_command (ctx, append, msg); 599 610 if (rc == 0) 600 611 { 601 612 mutt_any_key_to_continue (NULL); ··· 603 614 } 604 615 else 605 616 remove (ctx->path); 617 + 618 + unlock_realpath (ctx); 606 619 607 620 return 0; 608 621 } ··· 829 842 return -1; 830 843 } 831 844 832 - int rc = execute_command (ctx, ci->close, 1, _("Compressing %s")); 845 + /* TODO: need to refactor sync so we can lock around the 846 + * path sync as well as the compress operation */ 847 + if (!lock_realpath (ctx, 1)) 848 + { 849 + mutt_error (_("Unable to lock mailbox!")); 850 + return -1; 851 + } 852 + 853 + int rc = execute_command (ctx, ci->close, _("Compressing %s")); 833 854 if (rc == 0) 834 855 return -1; 856 + 857 + unlock_realpath (ctx); 835 858 836 859 store_size (ctx); 837 860