Objective C++, how to use runloop in background thread?

1k views Asked by At

Big edit: I think the question can be simplified to--how can I run corebluetooth and initialize CBCentralManager in background thread? Thank you!

I am making an an objective c++ application with CoreBluetooth that runs through the commandline, so the object C portion needs the runloop to be explicitly called [see this]. CoreBluetooth requires there to be an active runloop so callbacks are performed. The code below makes a call to the runloop in the beginning of the program to make everything work:

implementation.mm

// inside init method

// initialize bluetooth manager, must initialize before the runloop
self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
// start run loop
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
            while(([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]))
            {} 

and I can make async calls from my c++ main method:

main.cpp

int main() {

    std::thread worker(do_cpp_things); // c++ things in background thread
    run_objective_c_code(); // call objective c code using main thread
}

However with this approach, my c++ portion must be run in the background thread. and the objective C application is in the main thread which is opposite to what I want. So I tried to make a new thread in the objective C file then call the current run loop of the thread:

implementation.mm

// start a new thread
-(void)startThread {
    NSThread *A = [[NSThread alloc] initWithTarget:self selector:@selector(runTheLoop) object:nil]; //create thread A
    [A start];
}

// call runloop while in new thread
-(void) runTheLoop {
    // Commenting out initialization for the sake of simplicity before it terminates when trying to initialize the manager in this example
    // self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil]; 


    NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; 
    // TERMINATES HERE
    while(([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]))
    {} 


}

But this just terminates early. Not sure if there is something fundamentally wrong with my approach. Again--I want to run my objective-C code in the background thread with an active runloop and my c++ code in the main thread.

Thanks!

Actually wait, this solution doesn't properly make a runloop in background thread:

One of my problems is getting a runloop to run in a background thread. main.cpp

int main() {
  std::thread worker(run_cpp_in_thread);

}

implementation.mm // somewhere in init method

NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop run];

Now the problem is that CoreBluetooth is exiting immediately after powered on the central manager. Seems like something to do with the framework and threading.

1

There are 1 answers

4
user9559196 On

I believe you are asking c++ to run in thread which is working in background. Instead, just push C function to run in background

int main() {

    std::thread worker(run_objective c function); // objective c in background thread
   do_cpp_things; // call c++ things code using main thread
}

You still need to handle join properly otherwise can make your application unresponsive/crash