Testing improved thread termination with immediate output

This commit is contained in:
Your Name
2025-08-17 12:39:06 -04:00
parent 46977c882c
commit 5047023489
4 changed files with 809147 additions and 31 deletions

View File

@@ -578,7 +578,7 @@ static int mine_event(mining_context_t* ctx) {
// Check for signals
if (g_signal_received) {
if (ctx->verbose_enabled) {
printf("Signal received, shutting down...\n");
fprintf(stderr, "Signal received, shutting down...\n");
}
break;
}
@@ -587,50 +587,77 @@ static int mine_event(mining_context_t* ctx) {
usleep(10000); // 10ms
}
// Signal all workers to stop
if (ctx->verbose_enabled) {
printf("Signaling threads to stop...\n");
}
for (int i = 0; i < ctx->thread_count; i++) {
worker_contexts[i].should_stop = 1;
}
// Wait for all threads to finish and capture exit statuses
if (ctx->verbose_enabled) {
printf("Waiting for threads to finish...\n");
}
for (int i = 0; i < ctx->thread_count; i++) {
void* exit_status;
pthread_join(threads[i], &exit_status);
// Log exit status if it wasn't already logged by the thread
long status_code = (long)exit_status;
if (status_code == THREAD_EXIT_ERROR) {
log_thread_exit(i, exit_status, "Thread error (not previously logged)", ctx->verbose_enabled);
}
}
// Handle results
// Handle results - OUTPUT IMMEDIATELY when solution is found
if (main_ctx.solution_found && main_ctx.result_event) {
ctx->result_event = main_ctx.result_event; // Transfer ownership
// Transfer ownership and output result immediately
ctx->result_event = main_ctx.result_event;
result = 1; // Success
if (ctx->verbose_enabled) {
printf("Solution found successfully by Thread %d\n", main_ctx.solution_thread_id);
fprintf(stderr, "Solution found successfully by Thread %d\n", main_ctx.solution_thread_id);
}
// Output the solution JSON immediately to stdout
char* output_json = cJSON_Print(ctx->result_event);
if (output_json) {
printf("%s\n", output_json);
fflush(stdout); // Ensure immediate output
free(output_json);
}
} else if (main_ctx.timeout_reached) {
result = -1; // Timeout
if (ctx->verbose_enabled) {
printf("Mining timed out\n");
fprintf(stderr, "Mining timed out\n");
}
// Output timeout message
printf("timeout\n");
fflush(stdout);
} else if (g_shutdown_requested || g_signal_received) {
result = -3; // Signal/emergency shutdown
if (ctx->verbose_enabled) {
printf("Emergency shutdown completed\n");
fprintf(stderr, "Emergency shutdown completed\n");
}
} else {
result = -2; // Error
if (ctx->verbose_enabled) {
printf("Mining failed with error\n");
fprintf(stderr, "Mining failed with error\n");
}
}
// Now terminate other threads quickly - use pthread_cancel for immediate termination
if (ctx->verbose_enabled) {
fprintf(stderr, "Terminating remaining threads...\n");
}
// First try graceful shutdown
for (int i = 0; i < ctx->thread_count; i++) {
worker_contexts[i].should_stop = 1;
}
// Wait briefly for graceful shutdown, then force cancellation
struct timespec timeout_spec = {0, 50000000}; // 50ms timeout
for (int i = 0; i < ctx->thread_count; i++) {
void* exit_status;
// Try timed join for graceful exit
int join_result = pthread_timedjoin_np(threads[i], &exit_status, &timeout_spec);
if (join_result == ETIMEDOUT) {
// Thread didn't exit gracefully, cancel it
if (ctx->verbose_enabled) {
fprintf(stderr, "Force-canceling Thread %d\n", i);
}
pthread_cancel(threads[i]);
pthread_join(threads[i], &exit_status); // Wait for cancellation to complete
log_thread_exit(i, exit_status, "Force-canceled", ctx->verbose_enabled);
} else if (join_result == 0) {
// Thread exited gracefully
long status_code = (long)exit_status;
if (status_code == THREAD_EXIT_ERROR) {
log_thread_exit(i, exit_status, "Thread error (not previously logged)", ctx->verbose_enabled);
}
}
}