Skip to content

Commit 879c23e

Browse files
committed
test: improved pthread code for integration test
1 parent 6f8f4b7 commit 879c23e

2 files changed

Lines changed: 74 additions & 18 deletions

File tree

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ else ifeq ($(PLATFORM),wasm)
123123
else # linux
124124
TARGET := $(DIST_DIR)/cloudsync.so
125125
LDFLAGS += -shared -lssl -lcrypto
126+
T_LDFLAGS += -lpthread
126127
CURL_CONFIG = --with-openssl
127128
STRIP = strip --strip-unneeded $@
128129
endif

test/main.c

Lines changed: 73 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,18 @@
88

99
#include <stdio.h>
1010
#include <stdlib.h>
11+
#include <string.h>
12+
#include <errno.h>
13+
#include <stdint.h>
1114
#include "utils.h"
1215
#include "sqlite3.h"
1316

14-
#ifndef __linux__
1517
#ifdef _WIN32
1618
#include <windows.h>
1719
#else
1820
#include <pthread.h>
1921
#endif
2022
#define PEERS 5
21-
#endif
2223

2324
#ifdef CLOUDSYNC_LOAD_FROM_SOURCES
2425
#include "cloudsync.h"
@@ -318,24 +319,29 @@ int test_report(const char *description, int rc){
318319
return rc;
319320
}
320321

321-
#ifndef __linux__
322322
#ifdef _WIN32
323323
DWORD WINAPI worker(LPVOID arg) {
324324
#else
325325
void* worker(void* arg) {
326326
#endif
327327
int thread_id = *(int*)arg;
328+
int result = 0;
328329

329330
char description[32];
330331
snprintf(description, sizeof(description), "%d/%d Peer Test", thread_id+1, PEERS);
331-
if(test_report(description, test_init(":memory:", 1))){
332+
result = test_init(":memory:", 1);
333+
if(test_report(description, result)){
332334
printf("PEER %d FAIL.\n", thread_id+1);
333-
exit(thread_id+1);
335+
// Return error code instead of exiting entire process
336+
return (void*)(intptr_t)(thread_id+1);
334337
}
335338

339+
#ifdef _WIN32
340+
return 0;
341+
#else
336342
return NULL;
337-
}
338343
#endif
344+
}
339345

340346
int main (void) {
341347
int rc = SQLITE_OK;
@@ -357,43 +363,92 @@ int main (void) {
357363

358364
remove(DB_PATH); // remove the database file
359365

360-
#ifndef __linux__
361366
#ifdef _WIN32
362367
HANDLE threads[PEERS];
363368
#else
364369
pthread_t threads[PEERS];
365370
#endif
366371
int thread_ids[PEERS];
372+
int threads_created = 0;
373+
int thread_errors = 0;
374+
375+
// Initialize threads array to invalid values for cleanup
376+
#ifdef _WIN32
377+
for (int i = 0; i < PEERS; i++) {
378+
threads[i] = NULL;
379+
}
380+
#else
381+
memset(threads, 0, sizeof(threads));
382+
#endif
367383

384+
// Create threads with proper error handling
368385
for (int i = 0; i < PEERS; i++) {
369386
thread_ids[i] = i;
370387
#ifdef _WIN32
371388
threads[i] = CreateThread(NULL, 0, worker, &thread_ids[i], 0, NULL);
372389
if (threads[i] == NULL) {
373-
fprintf(stderr, "CreateThread failed\n");
374-
return 1;
390+
fprintf(stderr, "CreateThread failed for thread %d: %lu\n", i, GetLastError());
391+
thread_errors++;
392+
break; // Stop creating more threads on failure
375393
}
376394
#else
377-
if (pthread_create(&threads[i], NULL, worker, &thread_ids[i]) != 0) {
378-
perror("pthread_create");
379-
exit(1);
395+
int pthread_result = pthread_create(&threads[i], NULL, worker, &thread_ids[i]);
396+
if (pthread_result != 0) {
397+
fprintf(stderr, "pthread_create failed for thread %d: %s\n", i, strerror(pthread_result));
398+
threads[i] = 0; // Mark as invalid
399+
thread_errors++;
400+
break; // Stop creating more threads on failure
380401
}
381402
#endif
403+
threads_created++;
382404
}
383405

384-
// Wait for all threads to finish
406+
// Wait for all successfully created threads to finish and collect results
385407
#ifdef _WIN32
386-
WaitForMultipleObjects(PEERS, threads, TRUE, INFINITE);
408+
if (threads_created > 0) {
409+
DWORD wait_result = WaitForMultipleObjects(threads_created, threads, TRUE, INFINITE);
410+
if (wait_result == WAIT_FAILED) {
411+
fprintf(stderr, "WaitForMultipleObjects failed: %lu\n", GetLastError());
412+
thread_errors++;
413+
}
414+
}
387415
#endif
388-
for (int i = 0; i < PEERS; i++) {
416+
417+
// Join threads and collect exit codes
418+
for (int i = 0; i < threads_created; i++) {
389419
#ifdef _WIN32
390-
CloseHandle(threads[i]);
420+
if (threads[i] != NULL) {
421+
DWORD exit_code;
422+
if (GetExitCodeThread(threads[i], &exit_code) && exit_code != 0) {
423+
thread_errors++;
424+
printf("Thread %d failed with exit code %lu\n", i, exit_code);
425+
}
426+
CloseHandle(threads[i]);
427+
threads[i] = NULL;
428+
}
391429
#else
392-
pthread_join(threads[i], NULL);
430+
if (threads[i] != 0) {
431+
void* thread_result = NULL;
432+
int join_result = pthread_join(threads[i], &thread_result);
433+
if (join_result != 0) {
434+
fprintf(stderr, "pthread_join failed for thread %d: %s\n", i, strerror(join_result));
435+
thread_errors++;
436+
} else if (thread_result != NULL) {
437+
int exit_code = (int)(intptr_t)thread_result;
438+
thread_errors++;
439+
printf("Thread %d failed with exit code %d\n", i, exit_code);
440+
}
441+
threads[i] = 0;
442+
}
393443
#endif
394444
}
395-
#endif
396445

446+
// Update return code if any thread errors occurred
447+
if (thread_errors > 0) {
448+
printf("Threading test failed: %d thread(s) had errors\n", thread_errors);
449+
rc += thread_errors;
450+
}
451+
397452
printf("\n");
398453
return rc;
399454
}

0 commit comments

Comments
 (0)