Skip to main content
Topic: Using main_thread_callback correctly (Read 1442 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Using main_thread_callback correctly

Essentially, during my plugin's initialization, I do some possibly-lengthy operations (like user authentication using a remote server). Obviously this is no good, because if say the server is down, foobar will be locked up for x seconds where x is the timeout I've specified in cURL. This is just one example.

So I figured I'd fire off a Boost worker thread to take care of this stuff. The problem I'm running into is that if all things go well (authentication, etc.) I want to dynamically register my playback_callback. Before, in the init() method, this wasn't a problem, but of course I'm now getting crashes soon after foobar is started.

From what I can gather, the best approach to solving this is to hand off the registering of my playback_callback to a main_thread_callback. I've been working at this for a few hours now... not sure if it's the sleep deprivation or what, but I'm having the hardest time implementing a working solution.

I hate to ask for example code, but could anyone possibly help me out here? I tried to go by the code posted in this thread, but I get an error about not being able to instantiate an abstract class. (I wrote a class that extends main_thread_callback, but apparently there are some virtual functions I didn't define?)

Any information or tips on implementing a main_thread_callback would very much be appreciated! Or if there's a better way to accomplish what I'm trying to do, I'd love to hear your thoughts on that too.

Using main_thread_callback correctly

Reply #1
Coincidentally, I smashed my face against doing things in the wrong thread just last night.

The only member function you need to override is void callback_run(); ensure that when you instantiate your service_impl_t template that the template argument is your derived type, not main_thread_callback.
The below code registers an arbitrary callable to be executed in the main thread and uses the 0x ability to have linkage of local classes, but it should be illustrative enough.
Code: [Select]
template <typename F>
void in_main_thread(F f)
{
    struct in_main : main_thread_callback
    {
        void callback_run() override
        {
            f();
        }

        in_main(F f) : f(f) {}
        F f;
    };

    static_api_ptr_t<main_thread_callback_manager>()->add_callback(new service_impl_t<in_main>(f));
}
Zao shang yong zao nong zao rang zao ren zao.
To, early in the morning, use a chisel to build a bathtub makes impatient people hot-tempered.

Using main_thread_callback correctly

Reply #2
Thanks Zao, I really appreciate your illustration. I think that's gonna help a lot of people out, including myself for reference purposes. I like the flexibility of your example, and I'll probably end up coming up with something similar for my own uses in the future.

That said, my problem code is now building without any changes to my main_thread_callback implementation. My service_impl_t template instantiation is the same too. I wish I hadn't rolled the changes back, so I could see exactly what the differences are, but I believe it had something to do with changing my handler's register helper methods from static to instance members. Reorganizing my classes probably helped as well, but it seems my initial implementation was correct after all. I need some sleep in any case.

Anyway thanks again, Zao!

 
SimplePortal 1.0.0 RC1 © 2008-2020