Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6780957
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T16:34:03+00:00 2026-05-26T16:34:03+00:00

I’ve created a wrapper around boost::asio::io_service to handle asynchronous tasks on the GUI thread

  • 0

I’ve created a wrapper around boost::asio::io_service to handle asynchronous tasks on the GUI thread of an OpenGL application.

Tasks might be created from other threads so boost::asio seems ideal for this purpose and means I don’t need to write my own task queue with associated mutexes and locking. I want to keep the work done on each frame below an acceptable threshold (e.g. 5ms) so I’m calling poll_one until the desired budget is exceeded, rather than calling run. As far as I can tell this requires me to call reset whenever new tasks are posted, which seems to be working well.

Since it’s short, here’s the whole thing, sans #include:

typedef std::function<void(void)> VoidFunc;
typedef std::shared_ptr<class UiTaskQueue> UiTaskQueueRef;

class UiTaskQueue {

public:

    static UiTaskQueueRef create()
    {
        return UiTaskQueueRef( new UiTaskQueue() );
    }

    ~UiTaskQueue() {} 

    // normally just hand off the results of std/boost::bind to this function:
    void pushTask( VoidFunc f )
    {
        mService.post( f );
        mService.reset();
    }

    // called from UI thread; defaults to ~5ms budget (but always does one call)        
    void update( const float &budgetSeconds = 0.005f )
    {
        // getElapsedSeconds is a utility function from the GUI lib I'm using
        const float t = getElapsedSeconds();
        while ( mService.poll_one() && getElapsedSeconds() - t < budgetSeconds );
    }

private:

    UiTaskQueue() {}

    boost::asio::io_service mService;
};

I keep an instance of UiTaskQueueRef in my main app class and call mUiTaskQueue->update() from within my app’s animation loop.

I’d like to extend the functionality of this class to allow a task to be canceled. My previous implementation (using almost the same interface) returned a numeric ID for each task and allowed tasks to be canceled using this ID. But now the management of the queue and associated locking is handled by boost::asio I’m not sure how best to do this.

I’ve made an attempt by wrapping any tasks I might want to cancel in a shared_ptr and making a wrapper object that stores a weak_ptr to the task and implements the () operator so it can be passed to the io_service. It looks like this:

struct CancelableTask {
    CancelableTask( std::weak_ptr<VoidFunc> f ): mFunc(f) {}
    void operator()(void) const {
        std::shared_ptr<VoidFunc> f = mFunc.lock();
        if (f) {
            (*f)();
        }
    }
    std::weak_ptr<VoidFunc> mFunc;
};

I then have an overload of my pushTask method that looks like this:

void pushTask( std::weak_ptr<VoidFunc> f )
{
    mService.post( CancelableTask(f) );
    mService.reset();
}

I then post cancelable tasks to the queue using:

std::function<void(void)> *task = new std::function<void(void)>( boost::bind(&MyApp::doUiTask, this) );
mTask = std::shared_ptr< std::function<void(void)> >( task );
mUiTaskQueue->pushTask( std::weak_ptr< std::function<void(void)> >( mTask ) );

Or with the VoidFunc typedef if you prefer:

VoidFunc *task = new VoidFunc( std::bind(&MyApp::doUiTask, this) );
mTask = std::shared_ptr<VoidFunc>( task );
mUiTaskQueue->pushTask( std::weak_ptr<VoidFunc>( mTask ) );

So long as I keep the shared_ptr to mTask around then the io_service will execute the task. If I call reset on mTask then the weak_ptr can’t lock and the task is skipped as desired.

My question is really one of confidence with all these new tools: is new std::function<void(void)>( std::bind( ... ) ) an OK thing to be doing, and a safe thing to manage with a shared_ptr?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T16:34:03+00:00Added an answer on May 26, 2026 at 4:34 pm

    Yes, this is safe.

    For the code:

    VoidFunc *task = new VoidFunc( std::bind(&MyApp::doUiTask, this) );
    mTask = std::shared_ptr<VoidFunc>( task );
    

    Just do:

    mTask.reset(new VoidFunc( std::bind(&MyApp::doUiTask, this) ) );
    

    (and elsewhere).

    Bear in mind that you need to deal with the race condition where a tread might be getting a lock on the weak_ptr just before you reset the shared_ptr keeping the callback alive, and as a result you will occasionally see callbacks even though you went down the code path resetting the callback shared_ptr.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

link Im having trouble converting the html entites into html characters, (&# 8217;) i
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I am using Paperclip to handle profile photo uploads in my app. They upload
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
Basically, what I'm trying to create is a page of div tags, each has
I am trying to understand how to use SyndicationItem to display feed which is
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I have just tried to save a simple *.rtf file with some websites and
I want to count how many characters a certain string has in PHP, but
I would like to count the length of a string with PHP. The string

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.