Ticket #8538: epoll_reactor.ipp.patch

File epoll_reactor.ipp.patch, 4.7 KB (added by Leonid Gershanovich <gleonid@…>, 9 years ago)

patch for boost/asio/detail/impl/epoll_reactor.ipp

  • epoll_reactor.ipp

    diff -rNu  epoll_reactor.ipp.orig epoll_reactor.ipp > /mnt/builder/3rdParty/boost/srcs/epoll_reactor.ipp.patch
    
    old new  
    205205    epoll_reactor::per_descriptor_data& descriptor_data,
    206206    reactor_op* op, bool allow_speculative)
    207207{
    208   if (!descriptor_data)
     208  // LG
     209  epoll_reactor::per_descriptor_data local_descriptor_data = descriptor_data;
     210  if (!local_descriptor_data)
     211  // LG
    209212  {
    210213    op->ec_ = boost::asio::error::bad_descriptor;
    211214    post_immediate_completion(op);
    212215    return;
    213216  }
    214217
    215   mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
     218  // LG - use local_descriptor_data instead of descriptor_data to access mutex, as descriptor_data might have been reset to 0 by another thread
     219  mutex::scoped_lock descriptor_lock(local_descriptor_data->mutex_);
     220
     221  // LG - have to check descriptor_data again, as another thread might have set it to 0
     222  if (!descriptor_data)
     223  {
     224    op->ec_ = boost::asio::error::bad_descriptor;
     225    post_immediate_completion(op);
     226    return;
     227  }
     228  // LG
    216229
    217230  if (descriptor_data->shutdown_)
    218231  {
     
    251264void epoll_reactor::cancel_ops(socket_type,
    252265    epoll_reactor::per_descriptor_data& descriptor_data)
    253266{
    254   if (!descriptor_data)
     267  // LG
     268  epoll_reactor::per_descriptor_data local_descriptor_data = descriptor_data;
     269  if (!local_descriptor_data)
     270  // LG
    255271    return;
    256272
    257   mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
     273  // LG - use local_descriptor_data instead of descriptor_data to access mutex, as descriptor_data might have been reset to 0 by another thread
     274  mutex::scoped_lock descriptor_lock(local_descriptor_data->mutex_);
     275
     276  // LG - have to check descriptor_data again, as another thread might have set it to 0
     277  if (!descriptor_data)
     278    return;
     279  // LG
    258280
    259281  op_queue<operation> ops;
    260282  for (int i = 0; i < max_ops; ++i)
     
    275297void epoll_reactor::deregister_descriptor(socket_type descriptor,
    276298    epoll_reactor::per_descriptor_data& descriptor_data, bool closing)
    277299{
    278   if (!descriptor_data)
     300  // LG
     301  epoll_reactor::per_descriptor_data local_descriptor_data = descriptor_data;
     302  if (!local_descriptor_data)
     303  // LG
    279304    return;
    280305
    281   mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
     306  // LG - use local_descriptor_data instead of descriptor_data to access mutex, as descriptor_data might have been reset to 0 by another thread
     307  mutex::scoped_lock descriptor_lock(local_descriptor_data->mutex_);
     308  // LG - have to check descriptor_data again, as another thread might have set it to 0
     309  if (!descriptor_data)
     310    return;
     311  // LG
    282312
    283313  if (!descriptor_data->shutdown_)
    284314  {
     
    307337    descriptor_data->descriptor_ = -1;
    308338    descriptor_data->shutdown_ = true;
    309339
    310     descriptor_lock.unlock();
    311 
    312     free_descriptor_state(descriptor_data);
     340    //LG
     341    // ensure that descriptor_data is being reset INSIDE protected block (before descriptor_lock.unlock())
     342    // code is not strihtforward here because descriptor_lock lock on mutex that resides inside *descriptor_data
     343    epoll_reactor::per_descriptor_data descriptor_data_ = descriptor_data;
    313344    descriptor_data = 0;
     345    descriptor_lock.unlock();
     346    free_descriptor_state(descriptor_data_);
     347    //LG
    314348
    315349    io_service_.post_deferred_completions(ops);
    316350  }
     
    319353void epoll_reactor::deregister_internal_descriptor(socket_type descriptor,
    320354    epoll_reactor::per_descriptor_data& descriptor_data)
    321355{
    322   if (!descriptor_data)
     356  // LG
     357  epoll_reactor::per_descriptor_data local_descriptor_data = descriptor_data;
     358  if (!local_descriptor_data)
     359  // LG
    323360    return;
    324361
    325   mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
     362  // LG - use local_descriptor_data instead of descriptor_data to access mutex, as descriptor_data might have been reset to 0 by another thread
     363  mutex::scoped_lock descriptor_lock(local_descriptor_data->mutex_);
     364  // LG - have to check descriptor_data again, as another thread might have set it to 0
     365  if (!descriptor_data)
     366    return;
     367  // LG
    326368
    327369  if (!descriptor_data->shutdown_)
    328370  {
     
    336378    descriptor_data->descriptor_ = -1;
    337379    descriptor_data->shutdown_ = true;
    338380
    339     descriptor_lock.unlock();
    340 
    341     free_descriptor_state(descriptor_data);
     381    //LG
     382    // ensure that descriptor_data is being reset INSIDE protected block (before descriptor_lock.unlock())
     383    // code is not strihtforward here because descriptor_lock lock on mutex that resides inside *descriptor_data
     384    epoll_reactor::per_descriptor_data descriptor_data_ = descriptor_data;
    342385    descriptor_data = 0;
     386    descriptor_lock.unlock();
     387    free_descriptor_state(descriptor_data_);
     388    // LG
    343389  }
    344390}
    345391