Fix a crash that can occur when destroying a handler object that owns its
own memory (as is the case when destroying handlers in an orphaned strand).
This commit is contained in:
parent
596e733ed4
commit
fb4f83d903
@ -198,6 +198,15 @@ private:
|
||||
this_type* h(static_cast<this_type*>(base));
|
||||
typedef handler_alloc_traits<Handler, this_type> alloc_traits;
|
||||
handler_ptr<alloc_traits> ptr(h->handler_, h);
|
||||
|
||||
// A sub-object of the handler may be the true owner of the memory
|
||||
// associated with the handler. Consequently, a local copy of the handler
|
||||
// is required to ensure that any owning sub-object remains valid until
|
||||
// after we have deallocated the memory here.
|
||||
Handler handler(h->handler_);
|
||||
|
||||
// Free the memory associated with the handler.
|
||||
ptr.reset();
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -245,6 +245,15 @@ private:
|
||||
this_type* h(static_cast<this_type*>(base));
|
||||
typedef handler_alloc_traits<Handler, this_type> alloc_traits;
|
||||
handler_ptr<alloc_traits> ptr(h->handler_, h);
|
||||
|
||||
// A sub-object of the handler may be the true owner of the memory
|
||||
// associated with the handler. Consequently, a local copy of the handler
|
||||
// is required to ensure that any owning sub-object remains valid until
|
||||
// after we have deallocated the memory here.
|
||||
Handler handler(h->handler_);
|
||||
|
||||
// Free the memory associated with the handler.
|
||||
ptr.reset();
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -417,6 +417,15 @@ private:
|
||||
this_type* this_op(static_cast<this_type*>(base));
|
||||
typedef handler_alloc_traits<Operation, this_type> alloc_traits;
|
||||
handler_ptr<alloc_traits> ptr(this_op->operation_, this_op);
|
||||
|
||||
// A sub-object of the operation may be the true owner of the memory
|
||||
// associated with the operation. Consequently, a local copy of the
|
||||
// operation is required to ensure that any owning sub-object remains
|
||||
// valid until after we have deallocated the memory here.
|
||||
Operation operation(this_op->operation_);
|
||||
|
||||
// Free the memory associated with the operation.
|
||||
ptr.reset();
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -340,6 +340,15 @@ public:
|
||||
this_type* h(static_cast<this_type*>(base));
|
||||
typedef handler_alloc_traits<Handler, this_type> alloc_traits;
|
||||
handler_ptr<alloc_traits> ptr(h->handler_, h);
|
||||
|
||||
// A sub-object of the handler may be the true owner of the memory
|
||||
// associated with the handler. Consequently, a local copy of the handler
|
||||
// is required to ensure that any owning sub-object remains valid until
|
||||
// after we have deallocated the memory here.
|
||||
Handler handler(h->handler_);
|
||||
|
||||
// Free the memory associated with the handler.
|
||||
ptr.reset();
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -306,6 +306,15 @@ private:
|
||||
this_type* this_timer(static_cast<this_type*>(base));
|
||||
typedef handler_alloc_traits<Handler, this_type> alloc_traits;
|
||||
handler_ptr<alloc_traits> ptr(this_timer->handler_, this_timer);
|
||||
|
||||
// A sub-object of the handler may be the true owner of the memory
|
||||
// associated with the handler. Consequently, a local copy of the handler
|
||||
// is required to ensure that any owning sub-object remains valid until
|
||||
// after we have deallocated the memory here.
|
||||
Handler handler(this_timer->handler_);
|
||||
|
||||
// Free the memory associated with the handler.
|
||||
ptr.reset();
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -408,6 +408,15 @@ public:
|
||||
op_type* handler_op(static_cast<op_type*>(op));
|
||||
typedef handler_alloc_traits<Handler, op_type> alloc_traits;
|
||||
handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
|
||||
|
||||
// A sub-object of the handler may be the true owner of the memory
|
||||
// associated with the handler. Consequently, a local copy of the handler
|
||||
// is required to ensure that any owning sub-object remains valid until
|
||||
// after we have deallocated the memory here.
|
||||
Handler handler(handler_op->handler_);
|
||||
|
||||
// Free the memory associated with the handler.
|
||||
ptr.reset();
|
||||
}
|
||||
|
||||
asio::io_service::work work_;
|
||||
@ -634,6 +643,15 @@ public:
|
||||
Handler, op_type> alloc_traits;
|
||||
asio::detail::handler_ptr<alloc_traits> ptr(
|
||||
handler_op->handler_, handler_op);
|
||||
|
||||
// A sub-object of the handler may be the true owner of the memory
|
||||
// associated with the handler. Consequently, a local copy of the handler
|
||||
// is required to ensure that any owning sub-object remains valid until
|
||||
// after we have deallocated the memory here.
|
||||
Handler handler(handler_op->handler_);
|
||||
|
||||
// Free the memory associated with the handler.
|
||||
ptr.reset();
|
||||
}
|
||||
|
||||
asio::io_service::work work_;
|
||||
|
@ -649,6 +649,15 @@ private:
|
||||
op_type* handler_op(static_cast<op_type*>(op));
|
||||
typedef handler_alloc_traits<Handler, op_type> alloc_traits;
|
||||
handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
|
||||
|
||||
// A sub-object of the handler may be the true owner of the memory
|
||||
// associated with the handler. Consequently, a local copy of the handler
|
||||
// is required to ensure that any owning sub-object remains valid until
|
||||
// after we have deallocated the memory here.
|
||||
Handler handler(handler_op->handler_);
|
||||
|
||||
// Free the memory associated with the handler.
|
||||
ptr.reset();
|
||||
}
|
||||
|
||||
win_iocp_io_service& io_service_;
|
||||
|
@ -801,6 +801,15 @@ public:
|
||||
op_type* handler_op(static_cast<op_type*>(op));
|
||||
typedef handler_alloc_traits<Handler, op_type> alloc_traits;
|
||||
handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
|
||||
|
||||
// A sub-object of the handler may be the true owner of the memory
|
||||
// associated with the handler. Consequently, a local copy of the handler
|
||||
// is required to ensure that any owning sub-object remains valid until
|
||||
// after we have deallocated the memory here.
|
||||
Handler handler(handler_op->handler_);
|
||||
|
||||
// Free the memory associated with the handler.
|
||||
ptr.reset();
|
||||
}
|
||||
|
||||
asio::io_service::work work_;
|
||||
@ -1070,6 +1079,15 @@ public:
|
||||
op_type* handler_op(static_cast<op_type*>(op));
|
||||
typedef handler_alloc_traits<Handler, op_type> alloc_traits;
|
||||
handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
|
||||
|
||||
// A sub-object of the handler may be the true owner of the memory
|
||||
// associated with the handler. Consequently, a local copy of the handler
|
||||
// is required to ensure that any owning sub-object remains valid until
|
||||
// after we have deallocated the memory here.
|
||||
Handler handler(handler_op->handler_);
|
||||
|
||||
// Free the memory associated with the handler.
|
||||
ptr.reset();
|
||||
}
|
||||
|
||||
asio::io_service::work work_;
|
||||
@ -1329,6 +1347,15 @@ public:
|
||||
op_type* handler_op(static_cast<op_type*>(op));
|
||||
typedef handler_alloc_traits<Handler, op_type> alloc_traits;
|
||||
handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
|
||||
|
||||
// A sub-object of the handler may be the true owner of the memory
|
||||
// associated with the handler. Consequently, a local copy of the handler
|
||||
// is required to ensure that any owning sub-object remains valid until
|
||||
// after we have deallocated the memory here.
|
||||
Handler handler(handler_op->handler_);
|
||||
|
||||
// Free the memory associated with the handler.
|
||||
ptr.reset();
|
||||
}
|
||||
|
||||
asio::io_service::work work_;
|
||||
@ -1647,6 +1674,15 @@ public:
|
||||
op_type* handler_op(static_cast<op_type*>(op));
|
||||
typedef handler_alloc_traits<Handler, op_type> alloc_traits;
|
||||
handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
|
||||
|
||||
// A sub-object of the handler may be the true owner of the memory
|
||||
// associated with the handler. Consequently, a local copy of the handler
|
||||
// is required to ensure that any owning sub-object remains valid until
|
||||
// after we have deallocated the memory here.
|
||||
Handler handler(handler_op->handler_);
|
||||
|
||||
// Free the memory associated with the handler.
|
||||
ptr.reset();
|
||||
}
|
||||
|
||||
endpoint_type& endpoint_;
|
||||
@ -2001,6 +2037,15 @@ public:
|
||||
op_type* handler_op(static_cast<op_type*>(op));
|
||||
typedef handler_alloc_traits<Handler, op_type> alloc_traits;
|
||||
handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
|
||||
|
||||
// A sub-object of the handler may be the true owner of the memory
|
||||
// associated with the handler. Consequently, a local copy of the handler
|
||||
// is required to ensure that any owning sub-object remains valid until
|
||||
// after we have deallocated the memory here.
|
||||
Handler handler(handler_op->handler_);
|
||||
|
||||
// Free the memory associated with the handler.
|
||||
ptr.reset();
|
||||
}
|
||||
|
||||
win_iocp_io_service& io_service_;
|
||||
|
@ -160,6 +160,21 @@ void strand_test()
|
||||
// The run() calls will not return until all work has finished.
|
||||
BOOST_CHECK(count == 3);
|
||||
BOOST_CHECK(exception_count == 2);
|
||||
|
||||
count = 0;
|
||||
ios.reset();
|
||||
|
||||
// Check for clean shutdown when handlers posted through an orphaned strand
|
||||
// are abandoned.
|
||||
{
|
||||
strand s2(ios);
|
||||
s2.post(boost::bind(increment, &count));
|
||||
s2.post(boost::bind(increment, &count));
|
||||
s2.post(boost::bind(increment, &count));
|
||||
}
|
||||
|
||||
// No handlers can be called until run() is called.
|
||||
BOOST_CHECK(count == 0);
|
||||
}
|
||||
|
||||
test_suite* init_unit_test_suite(int, char*[])
|
||||
|
Loading…
Reference in New Issue
Block a user