Question: Call Rust DLL function to spawn new thread from C wrapper and return the main thread back to C

I have a use case where C wrapper is loading the Rust DLL. Both C and Rust have infinate loop.
C code
#include "main.h"
#include <stdio.h>
#include "addition.h"
#include <time.h>
#include <unistd.h>

extern void spawn_thread_and_get_back(); // Rust function :
extern void keep_calling_rust_fn(); // Rust function :

int main()
{
    spawn_thread_and_get_back(); // This should spawn thread with infinite loop in rust

    int sleep_seconds = 7;
    
    
    while(1){
      
        printf("Calling rust function);

        keep_calling_rust_fn(); // Call rust function
    }
}

and here is the rust lib code

async fn counter() {
    loop {
        println!("I am getting called by Tokio every 2 seconds");
        // Sleep for 1 second
        sleep(Duration::from_secs(2)).await;
    }
}

#[tokio::main]
async fn runForever() {
    let counterTask = tokio::spawn(
        counter()
    );
    tokio::try_join!(counterTask);

}

use std::thread;

#[no_mangle]
pub unsafe extern "C" fn spawn_thread_and_get_back() {
    let handle = thread::spawn(move || {
        // some work here
        println!("Trying to create new thread for Tokio runtime");
        runForever();

    });
    handle.join();
}

#[no_mangle]
pub unsafe extern "C" fn keep_calling_rust_fn() {
    println!("I am getting called by C wrapper every 7 second");
    someRandomPrintTask();
}


async fn printTask(task_number: u32) {
    println!("Print task {} -", task_number);
}

async fn someRandomPrintTask() {
    let printTask = tokio::spawn(
        printTask(10)
    );
    tokio::try_join!(printTask);
}


The issue I am facing is once I call the spawn_thread_and_get_back() from C and never get the thread back to execute while loop in C
I would like to call the rust DLL from C and spawn seperate thread for rust. And the idea is the caller thread from C will get free once it initializes the rust forever loop thread.


Answer:
Thanks everyone, After discussing in the comments above, here is the working answer. We just need to change Rust code

async fn counter() {
    loop {
        println!("I am getting called by Tokio every 2 seconds");
        // Sleep for 1 second
        sleep(Duration::from_secs(2)).await;
    }
}

#[tokio::main]
async fn runForever() {
    let counterTask = tokio::spawn(
        counter()
    );
    tokio::try_join!(counterTask);

}

use std::thread;

#[no_mangle]
pub unsafe extern "C" fn spawn_thread_and_get_back() {
    let handle = thread::spawn(move || {
        // some work here
        println!("Trying to create new thread for Tokio runtime");
        runForever();

    });
    

   `handle.join();` *** Update - Removed this as it was blocking the main thread as it was waiting for handle to finish ***

}

#[no_mangle]
pub unsafe extern "C" fn keep_calling_rust_fn() {
    println!("I am getting called by C wrapper every 7 second");
    someRandomPrintTask();
}


async fn printTask(task_number: u32) {
    println!("Print task {} -", task_number);
}

#[tokio::main]  *** Update - Added the decorater here ***
async fn someRandomPrintTask() {
    let printTask = tokio::spawn(
        printTask(10)
    );
    tokio::try_join!(printTask);
}