Fix potential data race due to reading the reactor pointer outside the lock.
diff --git a/asio/include/asio/detail/impl/epoll_reactor.ipp b/asio/include/asio/detail/impl/epoll_reactor.ipp index 7e092bd..5502144 100644 --- a/asio/include/asio/detail/impl/epoll_reactor.ipp +++ b/asio/include/asio/detail/impl/epoll_reactor.ipp
@@ -606,8 +606,9 @@ operation* epoll_reactor::descriptor_state::perform_io(uint32_t events) { + mutex_.lock(); perform_io_cleanup_on_block_exit io_cleanup(reactor_); - mutex::scoped_lock descriptor_lock(mutex_); + mutex::scoped_lock descriptor_lock(mutex_, mutex::scoped_lock::adopt_lock); // Exception operations must be processed first to ensure that any // out-of-band data is read before normal data.
diff --git a/asio/include/asio/detail/scoped_lock.hpp b/asio/include/asio/detail/scoped_lock.hpp index cc225f2..5529818 100644 --- a/asio/include/asio/detail/scoped_lock.hpp +++ b/asio/include/asio/detail/scoped_lock.hpp
@@ -28,8 +28,18 @@ : private noncopyable { public: + // Tag type used to distinguish constructors. + enum adopt_lock_t { adopt_lock }; + + // Constructor adopts a lock that is already held. + scoped_lock(Mutex& m, adopt_lock_t) + : mutex_(m), + locked_(true) + { + } + // Constructor acquires the lock. - scoped_lock(Mutex& m) + explicit scoped_lock(Mutex& m) : mutex_(m) { mutex_.lock();