feat: sendfile works with -m, error on -f + -c/-s

- load_files_multithreaded skips file_load_data when sendfile is active
- -f + -m works: sendfile bypasses loader, sender uses sendfile directly
- -f combined with -c or -s prints error and exits with rc=1
- Add Sendfile + Multithreading test case
This commit is contained in:
2026-07-05 16:31:08 +02:00
parent 01045d7d14
commit 2fb7203c82
3 changed files with 11 additions and 8 deletions
+1 -1
View File
@@ -49,7 +49,7 @@ The client-server communication uses the following status codes:
| `-m` | Enable multithreading mode | | `-m` | Enable multithreading mode |
| `-c [level]` | Enable compression with optional level (1-22, default: 5) | | `-c [level]` | Enable compression with optional level (1-22, default: 5) |
| `-s` | Enable chunk serialization (batch-transfer all files per chunk) | | `-s` | Enable chunk serialization (batch-transfer all files per chunk) |
| `-f` | Enable sendfile (zero-copy file transfer, bypasses userspace memory) | | `-f` | Enable sendfile (zero-copy file transfer, bypasses userspace memory). Can be combined with `-m`. Incompatible with `-c` and `-s`. |
| `--source-dir <path>` | Source directory to sync (overrides `FASTSYNC_SOURCE_DIR`) | | `--source-dir <path>` | Source directory to sync (overrides `FASTSYNC_SOURCE_DIR`) |
| `--dest-dir <path>` | Server-side destination directory (overrides `FASTSYNC_DEST_DIR`) | | `--dest-dir <path>` | Server-side destination directory (overrides `FASTSYNC_DEST_DIR`) |
| `--save-to-disk` | Persist received files to disk | | `--save-to-disk` | Persist received files to disk |
+9 -7
View File
@@ -86,8 +86,10 @@ int load_files_multithreaded(void *pipeline_context) {
mtx_unlock(&context->mutex_loader); mtx_unlock(&context->mutex_loader);
return thrd_success; return thrd_success;
} }
for (int i = 0; i < chunk->element_count; i++) if (!context->config->use_sendfile) {
file_load_data(chunk->items[i]); for (int i = 0; i < chunk->element_count; i++)
file_load_data(chunk->items[i]);
}
queue_enqueue_multithreaded(context->queue_loader, chunk, queue_enqueue_multithreaded(context->queue_loader, chunk,
&context->mutex_loader, &context->mutex_loader,
&context->condition_not_empty_loader, &context->condition_not_empty_loader,
@@ -152,11 +154,6 @@ int send_files(Config *config) {
} }
int send_files_multithreaded(Config *config) { int send_files_multithreaded(Config *config) {
if (config->use_sendfile) {
log_message(LOG_LEVEL_INFO, "Sendfile enabled, falling back to single-threaded");
return send_files(config);
}
PipelineContextSender *context = PipelineContextSender *context =
pipeline_context_sender_create(config, queue_create(100, chunk_destroy), pipeline_context_sender_create(config, queue_create(100, chunk_destroy),
queue_create(100, chunk_destroy)); queue_create(100, chunk_destroy));
@@ -238,6 +235,11 @@ int main(int argc, char *argv[]) {
} }
} }
if (config->use_sendfile && (config->use_chunk_serialization || config->use_compression)) {
fprintf(stderr, "Error: -f/--sendfile cannot be combined with -c (compression) or -s (chunk serialization)\n");
return 1;
}
if (config->use_multithreading) if (config->use_multithreading)
return send_files_multithreaded(config); return send_files_multithreaded(config);
return send_files(config); return send_files(config);
+1
View File
@@ -49,6 +49,7 @@ TEST_CASES = [
"flags": ["-m", "-c", "-s"], "flags": ["-m", "-c", "-s"],
}, },
{"name": "Sendfile (-f)", "flags": ["-f"]}, {"name": "Sendfile (-f)", "flags": ["-f"]},
{"name": "Sendfile + Multithreading (-f -m)", "flags": ["-f", "-m"]},
] ]