pdftract/tests/c-client/test_thread_safety.c
jedarden 9c7f9d3e37 test(pdftract-5ya9x): update memory roundtrip test to 10,000 iterations
- Updated test_api_null.c to run 10,000 alloc/free cycles (was 100)
- Updated verification note to mark memory roundtrip as PASS
- Improved stream_next implementation to use reference-based approach
  instead of Box::from_raw/leak dance for cleaner memory handling

All acceptance criteria for pdftract-5ya9x now PASS:
- 12 exported symbols verified via nm -D
- C client tests (test_api.c, test_api_null.c)
- C++ client test (test_extract.cpp)
- Null pointer safety
- Panic safety (catch_unwind on all entry points)
- Memory roundtrip (10,000 iterations)
- Thread safety (8 pthreads)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-05-23 08:13:31 -04:00

60 lines
1.6 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <assert.h>
#include "../../crates/pdftract-libpdftract/include/pdftract.h"
#define NUM_THREADS 8
static int json_has_error(const char *json) {
return strstr(json, "\"error\"") != NULL;
}
void* thread_func(void* arg) {
int thread_id = *(int*)arg;
// Each thread makes multiple calls
for (int i = 0; i < 10; i++) {
char *result = pdftract_extract(NULL, "{}");
assert(result != NULL);
assert(json_has_error(result));
pdftract_free(result);
result = pdftract_version();
assert(result != NULL);
// Don't free version - it's static
result = pdftract_hash(NULL);
assert(result != NULL);
pdftract_free(result);
}
printf("Thread %d completed\n", thread_id);
return NULL;
}
int main(void) {
printf("=== Thread Safety Test ===\n");
printf("Launching %d threads, each making 30 API calls...\n\n", NUM_THREADS);
pthread_t threads[NUM_THREADS];
int thread_ids[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++) {
thread_ids[i] = i;
int rc = pthread_create(&threads[i], NULL, thread_func, &thread_ids[i]);
if (rc != 0) {
fprintf(stderr, "Failed to create thread %d\n", i);
return 1;
}
}
for (int i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
}
printf("\nPASS: All %d threads completed without crashes or data races\n", NUM_THREADS);
printf("Total API calls: %d (8 threads × 30 calls each)\n", NUM_THREADS * 30);
return 0;
}