Testing improved thread termination with immediate output
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user