boost asio service returning too soon











up vote
0
down vote

favorite












been trying to solve this problem i am facing concerning the io_service object. The code in question in so:



    void connect_handler(const error_code &ec,iterator iterator){
cout<<"Connect handler"<<endl;
}

void resolver_handler(const error_code &ec,iterator iterator,boost::asio::io_service &io){
cout<<"Resolver handler..."<<endl;
boost::asio::ip::tcp::socket socket(io);
boost::asio::async_connect(socket,iterator,&connect_handler);
}

int main(){
boost::asio::io_service io;
resolver resolver(io);
resolver::query query("example.com","http");
resolver.async_resolve(query,boost::bind(resolver_handler,boost::asio::placeholders::error,boost::asio::placeholders::iterator,boost::ref(io)));
cout<<io.run()<<endl;

return 0;
}


Tried the same thing in another simple example, with everything running as intended:



void printTwo(const error_code& ec,boost::asio::deadline_timer &timer,boost::asio::io_service &io){
cout<<"print two"<<endl;
}

void printOne(const error_code& ec,boost::asio::deadline_timer &timer,boost::asio::io_service &io){
cout<<"print one"<<endl;
timer.async_wait(boost::bind(printTwo,boost::asio::placeholders::error,boost::ref(timer),boost::ref(io)));
}

int main(int argc, char** argv) {
boost::asio::io_service io;
boost::asio::deadline_timer timer(io,boost::posix_time::seconds(3));
timer.async_wait(boost::bind(printOne,boost::asio::placeholders::error,boost::ref(timer),boost::ref(io)));
cout<<io.run()<<endl;
return 0;
}


My assumptions is that the service object blocks until all work is done; also the thread that calls the run function is the thread that the handler functions are called from. So, why does the second block of code work as intended, but not the first? thanks in advance.










share|improve this question






















  • Your socket goes out of scope.
    – tkausl
    Nov 22 at 1:36










  • I didn't completely read your question, but I think you should check out boost.org/doc/libs/1_57_0/doc/html/boost_asio/reference/… If io_service runs out of work, it'll return from that call. By putting this into the io_service work queue, it will simply stay there doing nothing, making io_service think it needs to keep going.
    – Steve
    Nov 22 at 1:37










  • I'm assuming io.run() is returning too quickly, it's not completely clear.
    – Steve
    Nov 22 at 1:37










  • And your socket goes out of scope. @tkausl is right.
    – Steve
    Nov 22 at 1:45












  • In your second example, the deadline_timer is the thing that's keeping the io_service alive. For three seconds, there is "work to be done", and when that three seconds expires (or the timer is reset) that work is "completed".
    – Steve
    Nov 22 at 1:48

















up vote
0
down vote

favorite












been trying to solve this problem i am facing concerning the io_service object. The code in question in so:



    void connect_handler(const error_code &ec,iterator iterator){
cout<<"Connect handler"<<endl;
}

void resolver_handler(const error_code &ec,iterator iterator,boost::asio::io_service &io){
cout<<"Resolver handler..."<<endl;
boost::asio::ip::tcp::socket socket(io);
boost::asio::async_connect(socket,iterator,&connect_handler);
}

int main(){
boost::asio::io_service io;
resolver resolver(io);
resolver::query query("example.com","http");
resolver.async_resolve(query,boost::bind(resolver_handler,boost::asio::placeholders::error,boost::asio::placeholders::iterator,boost::ref(io)));
cout<<io.run()<<endl;

return 0;
}


Tried the same thing in another simple example, with everything running as intended:



void printTwo(const error_code& ec,boost::asio::deadline_timer &timer,boost::asio::io_service &io){
cout<<"print two"<<endl;
}

void printOne(const error_code& ec,boost::asio::deadline_timer &timer,boost::asio::io_service &io){
cout<<"print one"<<endl;
timer.async_wait(boost::bind(printTwo,boost::asio::placeholders::error,boost::ref(timer),boost::ref(io)));
}

int main(int argc, char** argv) {
boost::asio::io_service io;
boost::asio::deadline_timer timer(io,boost::posix_time::seconds(3));
timer.async_wait(boost::bind(printOne,boost::asio::placeholders::error,boost::ref(timer),boost::ref(io)));
cout<<io.run()<<endl;
return 0;
}


My assumptions is that the service object blocks until all work is done; also the thread that calls the run function is the thread that the handler functions are called from. So, why does the second block of code work as intended, but not the first? thanks in advance.










share|improve this question






















  • Your socket goes out of scope.
    – tkausl
    Nov 22 at 1:36










  • I didn't completely read your question, but I think you should check out boost.org/doc/libs/1_57_0/doc/html/boost_asio/reference/… If io_service runs out of work, it'll return from that call. By putting this into the io_service work queue, it will simply stay there doing nothing, making io_service think it needs to keep going.
    – Steve
    Nov 22 at 1:37










  • I'm assuming io.run() is returning too quickly, it's not completely clear.
    – Steve
    Nov 22 at 1:37










  • And your socket goes out of scope. @tkausl is right.
    – Steve
    Nov 22 at 1:45












  • In your second example, the deadline_timer is the thing that's keeping the io_service alive. For three seconds, there is "work to be done", and when that three seconds expires (or the timer is reset) that work is "completed".
    – Steve
    Nov 22 at 1:48















up vote
0
down vote

favorite









up vote
0
down vote

favorite











been trying to solve this problem i am facing concerning the io_service object. The code in question in so:



    void connect_handler(const error_code &ec,iterator iterator){
cout<<"Connect handler"<<endl;
}

void resolver_handler(const error_code &ec,iterator iterator,boost::asio::io_service &io){
cout<<"Resolver handler..."<<endl;
boost::asio::ip::tcp::socket socket(io);
boost::asio::async_connect(socket,iterator,&connect_handler);
}

int main(){
boost::asio::io_service io;
resolver resolver(io);
resolver::query query("example.com","http");
resolver.async_resolve(query,boost::bind(resolver_handler,boost::asio::placeholders::error,boost::asio::placeholders::iterator,boost::ref(io)));
cout<<io.run()<<endl;

return 0;
}


Tried the same thing in another simple example, with everything running as intended:



void printTwo(const error_code& ec,boost::asio::deadline_timer &timer,boost::asio::io_service &io){
cout<<"print two"<<endl;
}

void printOne(const error_code& ec,boost::asio::deadline_timer &timer,boost::asio::io_service &io){
cout<<"print one"<<endl;
timer.async_wait(boost::bind(printTwo,boost::asio::placeholders::error,boost::ref(timer),boost::ref(io)));
}

int main(int argc, char** argv) {
boost::asio::io_service io;
boost::asio::deadline_timer timer(io,boost::posix_time::seconds(3));
timer.async_wait(boost::bind(printOne,boost::asio::placeholders::error,boost::ref(timer),boost::ref(io)));
cout<<io.run()<<endl;
return 0;
}


My assumptions is that the service object blocks until all work is done; also the thread that calls the run function is the thread that the handler functions are called from. So, why does the second block of code work as intended, but not the first? thanks in advance.










share|improve this question













been trying to solve this problem i am facing concerning the io_service object. The code in question in so:



    void connect_handler(const error_code &ec,iterator iterator){
cout<<"Connect handler"<<endl;
}

void resolver_handler(const error_code &ec,iterator iterator,boost::asio::io_service &io){
cout<<"Resolver handler..."<<endl;
boost::asio::ip::tcp::socket socket(io);
boost::asio::async_connect(socket,iterator,&connect_handler);
}

int main(){
boost::asio::io_service io;
resolver resolver(io);
resolver::query query("example.com","http");
resolver.async_resolve(query,boost::bind(resolver_handler,boost::asio::placeholders::error,boost::asio::placeholders::iterator,boost::ref(io)));
cout<<io.run()<<endl;

return 0;
}


Tried the same thing in another simple example, with everything running as intended:



void printTwo(const error_code& ec,boost::asio::deadline_timer &timer,boost::asio::io_service &io){
cout<<"print two"<<endl;
}

void printOne(const error_code& ec,boost::asio::deadline_timer &timer,boost::asio::io_service &io){
cout<<"print one"<<endl;
timer.async_wait(boost::bind(printTwo,boost::asio::placeholders::error,boost::ref(timer),boost::ref(io)));
}

int main(int argc, char** argv) {
boost::asio::io_service io;
boost::asio::deadline_timer timer(io,boost::posix_time::seconds(3));
timer.async_wait(boost::bind(printOne,boost::asio::placeholders::error,boost::ref(timer),boost::ref(io)));
cout<<io.run()<<endl;
return 0;
}


My assumptions is that the service object blocks until all work is done; also the thread that calls the run function is the thread that the handler functions are called from. So, why does the second block of code work as intended, but not the first? thanks in advance.







c++ asynchronous boost service asio






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 22 at 1:34









tom

1




1












  • Your socket goes out of scope.
    – tkausl
    Nov 22 at 1:36










  • I didn't completely read your question, but I think you should check out boost.org/doc/libs/1_57_0/doc/html/boost_asio/reference/… If io_service runs out of work, it'll return from that call. By putting this into the io_service work queue, it will simply stay there doing nothing, making io_service think it needs to keep going.
    – Steve
    Nov 22 at 1:37










  • I'm assuming io.run() is returning too quickly, it's not completely clear.
    – Steve
    Nov 22 at 1:37










  • And your socket goes out of scope. @tkausl is right.
    – Steve
    Nov 22 at 1:45












  • In your second example, the deadline_timer is the thing that's keeping the io_service alive. For three seconds, there is "work to be done", and when that three seconds expires (or the timer is reset) that work is "completed".
    – Steve
    Nov 22 at 1:48




















  • Your socket goes out of scope.
    – tkausl
    Nov 22 at 1:36










  • I didn't completely read your question, but I think you should check out boost.org/doc/libs/1_57_0/doc/html/boost_asio/reference/… If io_service runs out of work, it'll return from that call. By putting this into the io_service work queue, it will simply stay there doing nothing, making io_service think it needs to keep going.
    – Steve
    Nov 22 at 1:37










  • I'm assuming io.run() is returning too quickly, it's not completely clear.
    – Steve
    Nov 22 at 1:37










  • And your socket goes out of scope. @tkausl is right.
    – Steve
    Nov 22 at 1:45












  • In your second example, the deadline_timer is the thing that's keeping the io_service alive. For three seconds, there is "work to be done", and when that three seconds expires (or the timer is reset) that work is "completed".
    – Steve
    Nov 22 at 1:48


















Your socket goes out of scope.
– tkausl
Nov 22 at 1:36




Your socket goes out of scope.
– tkausl
Nov 22 at 1:36












I didn't completely read your question, but I think you should check out boost.org/doc/libs/1_57_0/doc/html/boost_asio/reference/… If io_service runs out of work, it'll return from that call. By putting this into the io_service work queue, it will simply stay there doing nothing, making io_service think it needs to keep going.
– Steve
Nov 22 at 1:37




I didn't completely read your question, but I think you should check out boost.org/doc/libs/1_57_0/doc/html/boost_asio/reference/… If io_service runs out of work, it'll return from that call. By putting this into the io_service work queue, it will simply stay there doing nothing, making io_service think it needs to keep going.
– Steve
Nov 22 at 1:37












I'm assuming io.run() is returning too quickly, it's not completely clear.
– Steve
Nov 22 at 1:37




I'm assuming io.run() is returning too quickly, it's not completely clear.
– Steve
Nov 22 at 1:37












And your socket goes out of scope. @tkausl is right.
– Steve
Nov 22 at 1:45






And your socket goes out of scope. @tkausl is right.
– Steve
Nov 22 at 1:45














In your second example, the deadline_timer is the thing that's keeping the io_service alive. For three seconds, there is "work to be done", and when that three seconds expires (or the timer is reset) that work is "completed".
– Steve
Nov 22 at 1:48






In your second example, the deadline_timer is the thing that's keeping the io_service alive. For three seconds, there is "work to be done", and when that three seconds expires (or the timer is reset) that work is "completed".
– Steve
Nov 22 at 1:48














1 Answer
1






active

oldest

votes

















up vote
0
down vote













io.run() in your program will return as soon as the io_service thinks it's done with the work it has to do. This could happen between operations or maybe when the last async callback is called (I'm not completely sure).



Use a work object to inform the io_service to keep running, and when you reset that work object, the io_service's run() call should return once it's done executing any pending operations.



The basic use is something like this:



boost::asio::io_service io_service;
boost::asio::io_service::work work(io_service);
// ...
io_service.run(); // Blocks here


And usually in another thread or maybe in one of the async callbacks, you do this:



work.reset();


And some time later, run() will return.






share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53422725%2fboost-asio-service-returning-too-soon%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote













    io.run() in your program will return as soon as the io_service thinks it's done with the work it has to do. This could happen between operations or maybe when the last async callback is called (I'm not completely sure).



    Use a work object to inform the io_service to keep running, and when you reset that work object, the io_service's run() call should return once it's done executing any pending operations.



    The basic use is something like this:



    boost::asio::io_service io_service;
    boost::asio::io_service::work work(io_service);
    // ...
    io_service.run(); // Blocks here


    And usually in another thread or maybe in one of the async callbacks, you do this:



    work.reset();


    And some time later, run() will return.






    share|improve this answer

























      up vote
      0
      down vote













      io.run() in your program will return as soon as the io_service thinks it's done with the work it has to do. This could happen between operations or maybe when the last async callback is called (I'm not completely sure).



      Use a work object to inform the io_service to keep running, and when you reset that work object, the io_service's run() call should return once it's done executing any pending operations.



      The basic use is something like this:



      boost::asio::io_service io_service;
      boost::asio::io_service::work work(io_service);
      // ...
      io_service.run(); // Blocks here


      And usually in another thread or maybe in one of the async callbacks, you do this:



      work.reset();


      And some time later, run() will return.






      share|improve this answer























        up vote
        0
        down vote










        up vote
        0
        down vote









        io.run() in your program will return as soon as the io_service thinks it's done with the work it has to do. This could happen between operations or maybe when the last async callback is called (I'm not completely sure).



        Use a work object to inform the io_service to keep running, and when you reset that work object, the io_service's run() call should return once it's done executing any pending operations.



        The basic use is something like this:



        boost::asio::io_service io_service;
        boost::asio::io_service::work work(io_service);
        // ...
        io_service.run(); // Blocks here


        And usually in another thread or maybe in one of the async callbacks, you do this:



        work.reset();


        And some time later, run() will return.






        share|improve this answer












        io.run() in your program will return as soon as the io_service thinks it's done with the work it has to do. This could happen between operations or maybe when the last async callback is called (I'm not completely sure).



        Use a work object to inform the io_service to keep running, and when you reset that work object, the io_service's run() call should return once it's done executing any pending operations.



        The basic use is something like this:



        boost::asio::io_service io_service;
        boost::asio::io_service::work work(io_service);
        // ...
        io_service.run(); // Blocks here


        And usually in another thread or maybe in one of the async callbacks, you do this:



        work.reset();


        And some time later, run() will return.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 22 at 1:42









        Steve

        4,58222854




        4,58222854






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53422725%2fboost-asio-service-returning-too-soon%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Berounka

            Different font size/position of beamer's navigation symbols template's content depending on regular/plain...

            Sphinx de Gizeh