| 540 | } |
| 541 | |
| 542 | static void parse_and_save_result(const char *buffer, int len, |
| 543 | struct pc_worker *worker) |
| 544 | { |
| 545 | struct pc_item_result *res; |
| 546 | struct parallel_checkout_item *pc_item; |
| 547 | struct stat *st = NULL; |
| 548 | |
| 549 | if (len < PC_ITEM_RESULT_BASE_SIZE) |
| 550 | BUG("too short result from checkout worker (got %dB, exp >=%dB)", |
| 551 | len, (int)PC_ITEM_RESULT_BASE_SIZE); |
| 552 | |
| 553 | res = (struct pc_item_result *)buffer; |
| 554 | |
| 555 | /* |
| 556 | * Worker should send either the full result struct on success, or |
| 557 | * just the base (i.e. no stat data), otherwise. |
| 558 | */ |
| 559 | if (res->status == PC_ITEM_WRITTEN) { |
| 560 | assert_pc_item_result_size(len, (int)sizeof(struct pc_item_result)); |
| 561 | st = &res->st; |
| 562 | } else { |
| 563 | assert_pc_item_result_size(len, (int)PC_ITEM_RESULT_BASE_SIZE); |
| 564 | } |
| 565 | |
| 566 | if (!worker->nr_items_to_complete) |
| 567 | BUG("received result from supposedly finished checkout worker"); |
| 568 | if (res->id != worker->next_item_to_complete) |
| 569 | BUG("unexpected item id from checkout worker (got %"PRIuMAX", exp %"PRIuMAX")", |
| 570 | (uintmax_t)res->id, (uintmax_t)worker->next_item_to_complete); |
| 571 | |
| 572 | worker->next_item_to_complete++; |
| 573 | worker->nr_items_to_complete--; |
| 574 | |
| 575 | pc_item = ¶llel_checkout.items[res->id]; |
| 576 | pc_item->status = res->status; |
| 577 | if (st) |
| 578 | pc_item->st = *st; |
| 579 | |
| 580 | if (res->status != PC_ITEM_COLLIDED) |
| 581 | advance_progress_meter(); |
| 582 | } |
| 583 | |
| 584 | static void gather_results_from_workers(struct pc_worker *workers, |
| 585 | int num_workers) |
no test coverage detected