Skip to content
  • Ole John Aske's avatar
    625fd728
    Patch for Bug#20112700 ASSERT(SHOULD_BE_EMPTY) IN \'RESET_SEND_BUFFER\' · 625fd728
    Ole John Aske authored
    Assert in TransporterFacade::reset_send_buffers as send buffers
    were not empty as expected when reconnected to a node after
    a previous disconnect
    
    TransporterFacade::reset_send_buffer() reset the two-level
    send buffers in the TransporterFacade. Whenever a node
    disconnected from the TransporterFacade, its send buffers
    are reset (cleared). In addition to TransporterFacade
    send buffers, each trp_client has its own send buffers
    (Introduced as part of the 'ATC-patches', wl3860). These
    were introduced in order to reduce lock contention as each
    trp_client appends to the send buffers. However, the
    trp_client's send buffers were *not* cleared as part
    of TransporterFacade::reset_send_buffer().
    
    As the trp_client appended its send buffers to the
    TransporterFacade send buffers whenever it found fit,
    we could either:
    
    1) Append the trp_clients send buffer to the TransporterFacade
       after a node had disconnected. When it reconnected
       again, we found the TransporterFacade had a non-empty send buffer
       to the reconnected node which resulted in the assert in
       this bug-subject.
    
    2) (Possibly, but not proved:) The trp_client send buffers could
       be flushed to the TransporterFacade after the node had
       disconnected *and reconnected* again. I am not sure what
       this could cause of strange behavior, but it would certainly not
       be very healthy for the system.
    
    This patch enhance TransporterFacade::reset_send_buffer() to also
    reset the send_buffers of the trp_clients being known to
    the TransporterFacade. In order to provide concurrency protection
    of the TransporterFacade's set of trp_clients, this has to
    be done while holding the poll right: Thus, the call to
    ::reset_send_buffer() had to be moved from TransporterRegistry::do_connect()
    to TransporterRegistry::report_disconnect(). (Note ::report_disconnect()
    and ::report_connect() is only called by the poll owner!).
    
    Furthermore, the odd call to ::reset_send_buffer(..., should_be_empty=true)
    from within ::report_connect() has been removed. That call was mainly
    a safeguard / assert against send buffers not being empty when we
    reconnected again. At this point the send buffers should be empty,
    so an extra reset is redundant. If not empty, it would assert at this
    point. This call to reset_send_buffer was replaced with an assert check
    of the send buffers really being empty (!has_data_to_send()). (Required
    a few non used implementations of the virtual ::has_data_to_send()
    to be fixed), The now non used argument 'should_be_empty' to
    reset_send_buffer() was removed as part of this.
    
    The patch also fix an issue with
    TransporterFacade::m_current_send_buffer_size neither being
    initialized by the C'tor, correctly updated by ::flush_send_buffer(),
    nor zero'ed by ::reset_send_buffer().
    625fd728
    Patch for Bug#20112700 ASSERT(SHOULD_BE_EMPTY) IN \'RESET_SEND_BUFFER\'
    Ole John Aske authored
    Assert in TransporterFacade::reset_send_buffers as send buffers
    were not empty as expected when reconnected to a node after
    a previous disconnect
    
    TransporterFacade::reset_send_buffer() reset the two-level
    send buffers in the TransporterFacade. Whenever a node
    disconnected from the TransporterFacade, its send buffers
    are reset (cleared). In addition to TransporterFacade
    send buffers, each trp_client has its own send buffers
    (Introduced as part of the 'ATC-patches', wl3860). These
    were introduced in order to reduce lock contention as each
    trp_client appends to the send buffers. However, the
    trp_client's send buffers were *not* cleared as part
    of TransporterFacade::reset_send_buffer().
    
    As the trp_client appended its send buffers to the
    TransporterFacade send buffers whenever it found fit,
    we could either:
    
    1) Append the trp_clients send buffer to the TransporterFacade
       after a node had disconnected. When it reconnected
       again, we found the TransporterFacade had a non-empty send buffer
       to the reconnected node which resulted in the assert in
       this bug-subject.
    
    2) (Possibly, but not proved:) The trp_client send buffers could
       be flushed to the TransporterFacade after the node had
       disconnected *and reconnected* again. I am not sure what
       this could cause of strange behavior, but it would certainly not
       be very healthy for the system.
    
    This patch enhance TransporterFacade::reset_send_buffer() to also
    reset the send_buffers of the trp_clients being known to
    the TransporterFacade. In order to provide concurrency protection
    of the TransporterFacade's set of trp_clients, this has to
    be done while holding the poll right: Thus, the call to
    ::reset_send_buffer() had to be moved from TransporterRegistry::do_connect()
    to TransporterRegistry::report_disconnect(). (Note ::report_disconnect()
    and ::report_connect() is only called by the poll owner!).
    
    Furthermore, the odd call to ::reset_send_buffer(..., should_be_empty=true)
    from within ::report_connect() has been removed. That call was mainly
    a safeguard / assert against send buffers not being empty when we
    reconnected again. At this point the send buffers should be empty,
    so an extra reset is redundant. If not empty, it would assert at this
    point. This call to reset_send_buffer was replaced with an assert check
    of the send buffers really being empty (!has_data_to_send()). (Required
    a few non used implementations of the virtual ::has_data_to_send()
    to be fixed), The now non used argument 'should_be_empty' to
    reset_send_buffer() was removed as part of this.
    
    The patch also fix an issue with
    TransporterFacade::m_current_send_buffer_size neither being
    initialized by the C'tor, correctly updated by ::flush_send_buffer(),
    nor zero'ed by ::reset_send_buffer().
Loading