diff -rNu epoll_reactor.ipp.orig epoll_reactor.ipp > /mnt/builder/3rdParty/boost/srcs/epoll_reactor.ipp.patch --- epoll_reactor.ipp.orig 2012-02-28 17:35:48.000000000 -0500 +++ epoll_reactor.ipp 2012-12-17 11:10:02.000000000 -0500 @@ -205,14 +205,27 @@ epoll_reactor::per_descriptor_data& descriptor_data, reactor_op* op, bool allow_speculative) { - if (!descriptor_data) + // LG + epoll_reactor::per_descriptor_data local_descriptor_data = descriptor_data; + if (!local_descriptor_data) + // LG { op->ec_ = boost::asio::error::bad_descriptor; post_immediate_completion(op); return; } - mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); + // LG - use local_descriptor_data instead of descriptor_data to access mutex, as descriptor_data might have been reset to 0 by another thread + mutex::scoped_lock descriptor_lock(local_descriptor_data->mutex_); + + // LG - have to check descriptor_data again, as another thread might have set it to 0 + if (!descriptor_data) + { + op->ec_ = boost::asio::error::bad_descriptor; + post_immediate_completion(op); + return; + } + // LG if (descriptor_data->shutdown_) { @@ -251,10 +264,19 @@ void epoll_reactor::cancel_ops(socket_type, epoll_reactor::per_descriptor_data& descriptor_data) { - if (!descriptor_data) + // LG + epoll_reactor::per_descriptor_data local_descriptor_data = descriptor_data; + if (!local_descriptor_data) + // LG return; - mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); + // LG - use local_descriptor_data instead of descriptor_data to access mutex, as descriptor_data might have been reset to 0 by another thread + mutex::scoped_lock descriptor_lock(local_descriptor_data->mutex_); + + // LG - have to check descriptor_data again, as another thread might have set it to 0 + if (!descriptor_data) + return; + // LG op_queue ops; for (int i = 0; i < max_ops; ++i) @@ -275,10 +297,18 @@ void epoll_reactor::deregister_descriptor(socket_type descriptor, epoll_reactor::per_descriptor_data& descriptor_data, bool closing) { - if (!descriptor_data) + // LG + epoll_reactor::per_descriptor_data local_descriptor_data = descriptor_data; + if (!local_descriptor_data) + // LG return; - mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); + // LG - use local_descriptor_data instead of descriptor_data to access mutex, as descriptor_data might have been reset to 0 by another thread + mutex::scoped_lock descriptor_lock(local_descriptor_data->mutex_); + // LG - have to check descriptor_data again, as another thread might have set it to 0 + if (!descriptor_data) + return; + // LG if (!descriptor_data->shutdown_) { @@ -307,10 +337,14 @@ descriptor_data->descriptor_ = -1; descriptor_data->shutdown_ = true; - descriptor_lock.unlock(); - - free_descriptor_state(descriptor_data); + //LG + // ensure that descriptor_data is being reset INSIDE protected block (before descriptor_lock.unlock()) + // code is not strihtforward here because descriptor_lock lock on mutex that resides inside *descriptor_data + epoll_reactor::per_descriptor_data descriptor_data_ = descriptor_data; descriptor_data = 0; + descriptor_lock.unlock(); + free_descriptor_state(descriptor_data_); + //LG io_service_.post_deferred_completions(ops); } @@ -319,10 +353,18 @@ void epoll_reactor::deregister_internal_descriptor(socket_type descriptor, epoll_reactor::per_descriptor_data& descriptor_data) { - if (!descriptor_data) + // LG + epoll_reactor::per_descriptor_data local_descriptor_data = descriptor_data; + if (!local_descriptor_data) + // LG return; - mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); + // LG - use local_descriptor_data instead of descriptor_data to access mutex, as descriptor_data might have been reset to 0 by another thread + mutex::scoped_lock descriptor_lock(local_descriptor_data->mutex_); + // LG - have to check descriptor_data again, as another thread might have set it to 0 + if (!descriptor_data) + return; + // LG if (!descriptor_data->shutdown_) { @@ -336,10 +378,14 @@ descriptor_data->descriptor_ = -1; descriptor_data->shutdown_ = true; - descriptor_lock.unlock(); - - free_descriptor_state(descriptor_data); + //LG + // ensure that descriptor_data is being reset INSIDE protected block (before descriptor_lock.unlock()) + // code is not strihtforward here because descriptor_lock lock on mutex that resides inside *descriptor_data + epoll_reactor::per_descriptor_data descriptor_data_ = descriptor_data; descriptor_data = 0; + descriptor_lock.unlock(); + free_descriptor_state(descriptor_data_); + // LG } }