title: Libev c++ can't stop dynamic loops in multithread application
body: <p>I write multithread server with c++ and libev and has one problem. I start default_loop in main thread and create and start dynamic_loop in every slave threads. When I handle signals to stop process I call break_loop(ev::ALL). After that default event loop stopped but all dynamic loops work, need help to stop dynamic loops.</p>
  
  <p>Environment:
  OS: Opensuse 13.1</p>
  
  <p>compiler: g++ (SUSE Linux) 4.8.1 20130909</p>
  
  <p>libev: 4.15</p>
  
  <p>source:</p>
  
  <pre><code>#include &lt;vector&gt;
  #include &lt;memory&gt;
  #include &lt;ev++.h&gt;
  #include &lt;thread&gt;
  #include &lt;iostream&gt;
  
  class Thread 
  {
  public:
      typedef std::thread thread_t;
      Thread() {std::cout &lt;&lt; "thread created" &lt;&lt; std::endl;}
      ~Thread() {std::cout &lt;&lt; "Thread destructed" &lt;&lt; std::endl;}
      virtual void start() {this-&gt;thread = thread_t(&amp;Thread::run, this);}
      virtual void stop()
      {
          std::cout &lt;&lt; "unloop" &lt;&lt; std::endl;
          std::cout &lt;&lt; this-&gt;thread.get_id() &lt;&lt; std::endl;
  
          if(this-&gt;thread.joinable())
              std::cout &lt;&lt; " it's joinable" &lt;&lt; std::endl;
  
          this-&gt;loop-&gt;break_loop(ev::ALL);
  
          this-&gt;thread.join();
          std::cout &lt;&lt; "Thread " &lt;&lt; this-&gt;thread.get_id() &lt;&lt; " stopped" &lt;&lt; std::endl;
      }
  
      void run()
      {
          this-&gt;loop = new ev::dynamic_loop(ev::AUTO);
  
          this-&gt;timer.set(*this-&gt;loop);
          this-&gt;timer.set&lt;Thread, &amp;Thread::on_timer&gt;(this);
          this-&gt;timer.start(1, 1);
  
          std::cout &lt;&lt; "Thread " &lt;&lt; this-&gt;thread.get_id() &lt;&lt; " started" &lt;&lt; std::endl;
  
          this-&gt;loop-&gt;run(0);
  
          this-&gt;timer.stop();
  
          std::cout &lt;&lt; "Thread " &lt;&lt; this-&gt;thread.get_id() &lt;&lt; " finalized" &lt;&lt; std::endl;
      }
  
      void on_timer()
      {
          std::cout &lt;&lt; "Time event" &lt;&lt; std::endl;
      }
  protected:
      thread_t thread;
      ev::dynamic_loop *loop;
      ev::timer timer;
  private:
      Thread(const Thread &amp;) = delete;
      void operator=(const Thread &amp;) = delete;
  };
  
  class Server {
  public:
      void run()
      {
          std::cout &lt;&lt; "Start server" &lt;&lt; std::endl;
  
          this-&gt;sigint.set&lt;&amp;Server::on_terminate_signal&gt;();
          this-&gt;sigint.start(SIGINT);
  
          this-&gt;sigterm.set&lt;&amp;Server::on_terminate_signal&gt;();
          this-&gt;sigterm.start(SIGTERM);
  
          this-&gt;sigkill.set&lt;Server::on_terminate_signal&gt;();
          this-&gt;sigkill.start(SIGKILL);
  
          std::vector&lt;Thread*&gt; threads;
  
          for(auto i = 0; i&lt; 5; i++)
          {
              auto buf = new Thread();
              buf-&gt;start();
              threads.push_back(buf);
          }
  
          this-&gt;loop.run(0);
  
          this-&gt;sigint.stop();
          this-&gt;sigterm.stop();
          this-&gt;sigkill.stop();
  
          for(auto *iter: threads)
          {
              iter-&gt;stop();
              delete (&amp;iter);
          }
  
          std::cout &lt;&lt; "Gracefull exit" &lt;&lt; std::endl;
      }
  protected:
      ev::default_loop loop;
      ev::sig sigint;
      ev::sig sigkill;
      ev::sig sigterm;
  
      static void on_terminate_signal(ev::sig&amp; signal, int)
      {
          signal.loop.break_loop(ev::ALL);
          signal.stop();
          std::cout &lt;&lt; "Signal handled" &lt;&lt; std::endl;
      }    
  };
  
  int main(int, char**)
  {
      std::cout &lt;&lt; "libev " &lt;&lt; ev::version_major() &lt;&lt; "." &lt;&lt; ev::version_minor() &lt;&lt; std::endl;
      Server server;
      server.run();
  
      return 0;
  }
  </code></pre>
  
  <p>Output:</p>
  
  <pre><code>  libev 4.15
      Start server
      thread created
      thread created
      thread created
      thread created
      thread created
      Thread 139639372617472 started
      Thread 139639326365440 started
      Thread 139639337928448 started
      Thread 139639361054464 started
      Thread 139639349491456 started
      Time event
      Time event
      Time event
      Time event
      Time event
      Time event
      Time event
      Time eventTime event
  
      Time event
      Time event
      Time event
      Time event
      Time event
      Time event
      ^CSignal handled
      unloop
      139639372617472
       it's joinable
      Time eventTime event
  
      Time event
      Time event
      Time event
      Time event
      Time event
      Time event
      Time event
  
      Time event
  </code></pre>
  
  <p>compilation flags: -O0 -g -std=c++11</p>
  
  <p>linker flags: -lev</p>
  
  <p>UPD, source with wok code:</p>
  
  <pre><code>    #include &lt;vector&gt;
      #include &lt;memory&gt;
      #include &lt;ev++.h&gt;
      #include &lt;thread&gt;
      #include &lt;iostream&gt;
  
      class Thread {
      public:
              typedef std::thread thread_t;
              Thread(): loop(ev::AUTO) {std::cout &lt;&lt; "thread created" &lt;&lt; std::endl;}
              virtual ~Thread() {std::cout &lt;&lt; "Thread destructed" &lt;&lt; std::endl;}
              virtual void start() {this-&gt;thread = thread_t(&amp;Thread::run, this);}
              virtual void stop()
              {
                      std::cout &lt;&lt; "Try stopping " &lt;&lt; this-&gt;thread.get_id() &lt;&lt; std::endl;
  
                      this-&gt;stopper.send();
                      this-&gt;thread.join();
              }
  
              void run()
              {
                      this-&gt;timer.set(this-&gt;loop);
                      this-&gt;timer.set&lt;Thread, &amp;Thread::on_timer&gt;(this);
                      this-&gt;timer.start(1, 1);
  
                      this-&gt;stopper.set(this-&gt;loop);
                      this-&gt;stopper.set&lt;Thread, &amp;Thread::on_stop&gt;(this);
                      this-&gt;stopper.start();
  
                      std::cout &lt;&lt; "Thread " &lt;&lt; this-&gt;thread.get_id() &lt;&lt; " started" &lt;&lt; std::endl;
  
                      this-&gt;loop.run(0);
  
                      std::cout &lt;&lt; "Thread " &lt;&lt; this-&gt;thread.get_id() &lt;&lt; " finalized" &lt;&lt; std::endl;
              }
      protected:
              thread_t thread;
              ev::dynamic_loop loop;
              ev::timer timer;
              ev::async stopper;
  
              void on_timer()
              {
                      std::cout &lt;&lt; "Time event" &lt;&lt; std::endl;
              }
  
              void on_stop()
              {
                      std::cout &lt;&lt; "On stop event " &lt;&lt; std::endl;
  
                      this-&gt;stopper.stop();
                      this-&gt;timer.stop();
  
                      this-&gt;loop.break_loop(ev::ALL);
              }
      private:
              Thread(const Thread &amp;) = delete;
              void operator=(const Thread &amp;) = delete;
      };
  
      class Server {
      public:
              void run()
              {
                      std::cout &lt;&lt; "Start server" &lt;&lt; std::endl;
  
                      this-&gt;sigint.set&lt;&amp;Server::on_terminate_signal&gt;();
                      this-&gt;sigint.start(SIGINT);
  
                      this-&gt;sigterm.set&lt;&amp;Server::on_terminate_signal&gt;();
                      this-&gt;sigterm.start(SIGTERM);
  
                      this-&gt;sigkill.set&lt;Server::on_terminate_signal&gt;();
                      this-&gt;sigkill.start(SIGKILL);
  
                      std::vector&lt;Thread*&gt; threads;
  
                      for(auto i = 0; i&lt; 5; i++)
                      {
                              auto buf = new Thread();
                              buf-&gt;start();
                              threads.push_back(buf);
                      }
  
                      this-&gt;loop.run(0);
  
                      this-&gt;sigint.stop();
                      this-&gt;sigterm.stop();
                      this-&gt;sigkill.stop();
  
                      for (auto &amp;iter: threads)
                      {
                              iter-&gt;stop();
                              delete iter;
                      }
  
                      std::cout &lt;&lt; "Gracefull exit" &lt;&lt; std::endl;
              }
      protected:
              ev::default_loop loop;
              ev::sig sigint;
              ev::sig sigkill;
              ev::sig sigterm;
  
              static void on_terminate_signal(ev::sig&amp; signal, int)
              {
                      signal.loop.break_loop(ev::ALL);
                      signal.stop();
                      std::cout &lt;&lt; "Signal handled" &lt;&lt; std::endl;
              }
      };
  
      int main(int, char**)
      {
              std::cout &lt;&lt; "libev " &lt;&lt; ev::version_major() &lt;&lt; "." &lt;&lt; ev::version_minor() &lt;&lt; std::endl;
              Server server;
              server.run();
  
              return 0;
      }
  </code></pre>