Exemplo n.º 1
0
 size_t udp_socket::send_to( const char* b, size_t l, const ip::endpoint& to ) {
   try {
     return my->_sock.send_to( boost::asio::buffer(b, l), to_asio_ep(to) );
   } catch( const boost::system::system_error& e ) {
       if( e.code() == boost::asio::error::would_block ) {
           promise<size_t>::ptr p(new promise<size_t>("udp_socket::send_to"));
           my->_sock.async_send_to( boost::asio::buffer(b,l), to_asio_ep(to), 
               [=]( const boost::system::error_code& ec, size_t bt ) {
                   if( !ec ) p->set_value(bt);
                   else 
                     p->set_exception( fc::exception_ptr( new fc::exception( 
                             FC_LOG_MESSAGE( error, "${message} ", 
                             ("message", boost::system::system_error(ec).what())) ) ) );
               });
           return p->wait();
       }
       throw;
   }
 }
Exemplo n.º 2
0
 size_t udp_socket::receive_from( char* b, size_t l, fc::ip::endpoint& _from ) {
   try {
     boost::asio::ip::udp::endpoint from;
     size_t r =  my->_sock.receive_from( boost::asio::buffer(b, l), from );
     _from = to_fc_ep(from);
     return r;
   } catch( const boost::system::system_error& e ) {
       if( e.code() == boost::asio::error::would_block ) {
           boost::asio::ip::udp::endpoint from;
           promise<size_t>::ptr p(new promise<size_t>("udp_socket::send_to"));
           my->_sock.async_receive_from( boost::asio::buffer(b,l), from,
               [=]( const boost::system::error_code& ec, size_t bt ) {
                   if( !ec ) p->set_value(bt);
                   else p->set_exception( fc::exception_ptr( new fc::exception( 
                             FC_LOG_MESSAGE( error, "${message} ", 
                             ("message", boost::system::system_error(ec).what())) ) ) );
               });
           auto r =  p->wait();
           _from = to_fc_ep(from);
           return r;
       }
       throw;
   }
 }
    void message_oriented_connection_impl::read_loop()
    {
      VERIFY_CORRECT_THREAD();
      const unsigned int BUFFER_SIZE = 16;
      static_assert(BUFFER_SIZE >= sizeof(message_header), "insufficient buffer");
      const int LEFTOVER = BUFFER_SIZE - sizeof(message_header);

      _connected_time = fc::time_point::now();

      fc::oexception exception_to_rethrow;
      bool call_on_connection_closed = false;

      try
      {
        message m;
        while( true )
        {
          char buffer[BUFFER_SIZE];
          _sock.read(buffer, BUFFER_SIZE);
          _bytes_received += BUFFER_SIZE;
          memcpy((char*)&m, buffer, sizeof(message_header));

          FC_ASSERT( m.size <= MAX_MESSAGE_SIZE, "", ("m.size",m.size)("MAX_MESSAGE_SIZE",MAX_MESSAGE_SIZE) );

          size_t remaining_bytes_with_padding = 16 * ((m.size - LEFTOVER + 15) / 16);
          m.data.resize(LEFTOVER + remaining_bytes_with_padding); //give extra 16 bytes to allow for padding added in send call
          std::copy(buffer + sizeof(message_header), buffer + sizeof(buffer), m.data.begin());
          if (remaining_bytes_with_padding)
          {
            _sock.read(&m.data[LEFTOVER], remaining_bytes_with_padding);
            _bytes_received += remaining_bytes_with_padding;
          }
          m.data.resize(m.size); // truncate off the padding bytes

          _last_message_received_time = fc::time_point::now();

          try
          {
            // message handling errors are warnings...
            _delegate->on_message(_self, m);
          }
          /// Dedicated catches needed to distinguish from general fc::exception
          catch ( const fc::canceled_exception& e ) { throw e; }
          catch ( const fc::eof_exception& e ) { throw e; }
          catch ( const fc::exception& e)
          {
            /// Here loop should be continued so exception should be just caught locally.
            wlog( "message transmission failed ${er}", ("er", e.to_detail_string() ) );
            throw;
          }
        }
      }
      catch ( const fc::canceled_exception& e )
      {
        wlog( "caught a canceled_exception in read_loop.  this should mean we're in the process of deleting this object already, so there's no need to notify the delegate: ${e}", ("e", e.to_detail_string() ) );
        throw;
      }
      catch ( const fc::eof_exception& e )
      {
        wlog( "disconnected ${e}", ("e", e.to_detail_string() ) );
        call_on_connection_closed = true;
      }
      catch ( const fc::exception& e )
      {
        elog( "disconnected ${er}", ("er", e.to_detail_string() ) );
        call_on_connection_closed = true;
        exception_to_rethrow = fc::unhandled_exception(FC_LOG_MESSAGE(warn, "disconnected: ${e}", ("e", e.to_detail_string())));
      }
      catch ( const std::exception& e )
      {
        elog( "disconnected ${er}", ("er", e.what() ) );
        call_on_connection_closed = true;
        exception_to_rethrow = fc::unhandled_exception(FC_LOG_MESSAGE(warn, "disconnected: ${e}", ("e", e.what())));
      }
      catch ( ... )
      {
        elog( "unexpected exception" );
        call_on_connection_closed = true;
        exception_to_rethrow = fc::unhandled_exception(FC_LOG_MESSAGE(warn, "disconnected: ${e}", ("e", fc::except_str())));
      }

      if (call_on_connection_closed)
        _delegate->on_connection_closed(_self);

      if (exception_to_rethrow)
        throw *exception_to_rethrow;
    }
Exemplo n.º 4
0
iprocess& process::exec( const fc::path& exe, 
                         std::vector<std::string> args, 
                         const fc::path& work_dir, int opt  ) 
{

  my->pctx.work_dir = work_dir.string();
  my->pctx.suppress_console = (opt & suppress_console) != 0;
    
  if( opt&open_stdout)
      my->pctx.streams[boost::process::stdout_id] = bp::behavior::async_pipe();
  else 
      my->pctx.streams[boost::process::stdout_id] = bp::behavior::null();


  if( opt& open_stderr )
      my->pctx.streams[boost::process::stderr_id] = bp::behavior::async_pipe();
  else
      my->pctx.streams[boost::process::stderr_id] = bp::behavior::null();

  if( opt& open_stdin )
      my->pctx.streams[boost::process::stdin_id]  = bp::behavior::async_pipe();
  else
      my->pctx.streams[boost::process::stdin_id]  = bp::behavior::close();

  /*
  std::vector<std::string> a;
  a.reserve(size_t(args.size()));
  for( uint32_t i = 0; i < args.size(); ++i ) {
    a.push_back( fc::move(args[i]) ); 
  }
  */
  my->child.reset( new bp::child( bp::create_child( exe.string(), fc::move(args), my->pctx ) ) );

  if( opt & open_stdout ) {
     bp::handle outh = my->child->get_handle( bp::stdout_id );
     my->_outp.reset( new bp::pipe( fc::asio::default_io_service(), outh.release() ) );
  }
  if( opt & open_stderr ) {
     bp::handle errh = my->child->get_handle( bp::stderr_id );
     my->_errp.reset( new bp::pipe( fc::asio::default_io_service(), errh.release() ) );
  }
  if( opt & open_stdin ) {
     bp::handle inh  = my->child->get_handle( bp::stdin_id );
     my->_inp.reset(  new bp::pipe( fc::asio::default_io_service(), inh.release()  ) );
  }


  promise<int>::ptr p(new promise<int>("process"));
  my->stat.async_wait(  my->child->get_id(), [=]( const boost::system::error_code& ec, int exit_code )
    {
      //slog( "process::result %d", exit_code );
      if( !ec ) {
          #ifdef BOOST_POSIX_API
          if( WIFEXITED(exit_code) ) p->set_value(  WEXITSTATUS(exit_code) );
          else
          {
             p->set_exception( 
                 fc::exception_ptr( new fc::exception( 
                     FC_LOG_MESSAGE( error, "process exited with: ${message} ", 
                                     ("message", strsignal(WTERMSIG(exit_code))) ) ) ) );
          }
          #else
          p->set_value(exit_code);
          #endif
       }
       else
       {
          p->set_exception( 
              fc::exception_ptr( new fc::exception( 
                  FC_LOG_MESSAGE( error, "process exited with: ${message} ", 
                                  ("message", boost::system::system_error(ec).what())) ) ) );
       }
    });
  if( opt & open_stdin )
    my->_in     = std::make_shared<buffered_ostream>(std::make_shared<fc::asio::ostream<bp::pipe>>(my->_inp));
  if( opt & open_stdout )
    my->_out    = std::make_shared<buffered_istream>(std::make_shared<fc::asio::istream<bp::pipe>>(my->_outp));
  if( opt & open_stderr )
    my->_err    = std::make_shared<buffered_istream>(std::make_shared<fc::asio::istream<bp::pipe>>(my->_errp));
  my->_exited = p;
  return *this;
}