cyclic_read_session::optional_error_code
cyclic_read_session::do_start_extern_stop()
{
  if ((extern_state::stopped == extern_state_)
      || (extern_state::stop == extern_state_))
  {
    return boost::system::error_code(nmea::error::invalid_state);
  }

  // Start shutdown
  extern_state_ = extern_state::stop;

  // Do shutdown - abort outer operations
  if (extern_read_handler_.has_target())
  {
    extern_read_handler_.post(
        read_result_type(nmea::error::operation_aborted, 0));
  }

  // Do shutdown - abort inner operations
  serial_port_.close(stop_error_);

  // Check for shutdown completion
  if (may_complete_stop())
  {
    complete_stop();
    // Signal shutdown completion
    return stop_error_;
  }

  return optional_error_code();
}
void cyclic_read_session::handle_read_head(
    const boost::system::error_code& error,
    const std::size_t bytes_transferred)
{
  port_read_in_progress_ = false;

  // Check for pending session do_start_extern_stop operation
  if (extern_state::stop == extern_state_)
  {
    if (may_complete_stop())
    {
      complete_stop();
      post_extern_stop_handler();
    }
    return;
  }

  if (error)
  {
    // Check for pending session read operation
    if (extern_read_handler_.has_target())
    {
      extern_read_handler_.post(read_result_type(error, 0));
      return;
    }

    // Store error for the next outer read operation.
    read_error_ = error;
    return;
  }

  // We do not need in-between-frame-garbage and frame's head
  read_buffer_.consume(bytes_transferred);
  read_until_tail();
}
Beispiel #3
0
void playback_stop (void)
{
    g_return_if_fail (playing);
    wait_until_ready ();

    if (current_decoder)
        current_decoder->stop (& playback_api);

    playback_cleanup ();
    complete_stop ();
}
Beispiel #4
0
static bool_t end_cb (void * unused)
{
    g_return_val_if_fail (playing, FALSE);

    hook_call ("playback end", NULL);

    if (playback_error)
        failed_entries ++;
    else
        failed_entries = 0;

    playback_cleanup ();

    int playlist = playlist_get_playing ();
    bool_t play;

    if (get_bool (NULL, "no_playlist_advance"))
        play = get_bool (NULL, "repeat") && ! failed_entries;
    else if (! (play = playlist_next_song (playlist, get_bool (NULL, "repeat"))))
        playlist_set_position (playlist, -1);
    else if (failed_entries >= 10)
        play = FALSE;

    if (get_bool (NULL, "stop_after_current_song"))
        play = FALSE;

    if (play)
        playback_start (playlist, playlist_get_position (playlist), 0, FALSE);
    else
    {
        complete_stop ();
        hook_call ("playlist end reached", NULL);
    }

    return FALSE;
}
void cyclic_read_session::handle_read_tail(
    const boost::system::error_code& error,
    const std::size_t bytes_transferred)
{
  port_read_in_progress_ = false;

  // Check for pending session do_start_extern_stop operation
  if (extern_state::stop == extern_state_)
  {
    if (may_complete_stop())
    {
      complete_stop();
      post_extern_stop_handler();
    }
    return;
  }

  if (error)
  {
    // Check for pending session read operation
    if (extern_read_handler_.has_target())
    {
      extern_read_handler_.post(read_result_type(error, 0));
      return;
    }

    // Store error for the next outer read operation.
    read_error_ = error;
    return;
  }

  typedef boost::asio::streambuf::const_buffers_type        const_buffers_type;
  typedef boost::asio::buffers_iterator<const_buffers_type> buffers_iterator;
  // Extract frame from buffer to distinct memory area
  const_buffers_type committed_buffers(read_buffer_.data());
  buffers_iterator data_begin(buffers_iterator::begin(committed_buffers));
  buffers_iterator data_end(
      data_begin + bytes_transferred - frame_tail_.length());

  frame_ptr new_frame;
  if (frame_buffer_.full())
  {
    new_frame = frame_buffer_.front();
    new_frame->assign(data_begin, data_end);
  }
  else
  {
    new_frame = boost::make_shared<frame>(data_begin, data_end);
  }

  // Consume processed data
  read_buffer_.consume(bytes_transferred);

  // Continue inner operations loop.
  read_until_head();

  // Save ready frame into the cyclic read buffer
  frame_buffer_.push_back(new_frame);

  // If there is waiting read operation - complete it
  if (extern_read_handler_base* handler = extern_read_handler_.target())
  {
    read_result_type copy_result = handler->copy(frame_buffer_);
    frame_buffer_.erase_begin(copy_result.get<1>());
    extern_read_handler_.post(copy_result);
  }
}