Skip to content

Commit a0f2d32

Browse files
Fix segmentation fault caused by async_receive (apache#330)
### Motivation apache#326 fixes the possible segmentation fault caused by async_write, but it could still crash when triggering the callback of async_receive while the socket is destroyed. See apache#324 (comment) ### Modifications Capture the `shared_ptr` in `asyncReceive`.
1 parent ebae92e commit a0f2d32

File tree

1 file changed

+16
-28
lines changed

1 file changed

+16
-28
lines changed

lib/ClientConnection.cc

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -640,14 +640,11 @@ void ClientConnection::handleResolve(const boost::system::error_code& err,
640640

641641
void ClientConnection::readNextCommand() {
642642
const static uint32_t minReadSize = sizeof(uint32_t);
643-
auto weakSelf = weak_from_this();
643+
auto self = shared_from_this();
644644
asyncReceive(
645645
incomingBuffer_.asio_buffer(),
646-
customAllocReadHandler([weakSelf](const boost::system::error_code& err, size_t bytesTransferred) {
647-
auto self = weakSelf.lock();
648-
if (self) {
649-
self->handleRead(err, bytesTransferred, minReadSize);
650-
}
646+
customAllocReadHandler([this, self](const boost::system::error_code& err, size_t bytesTransferred) {
647+
handleRead(err, bytesTransferred, minReadSize);
651648
}));
652649
}
653650

@@ -672,15 +669,12 @@ void ClientConnection::handleRead(const boost::system::error_code& err, size_t b
672669
// Read the remaining part, use a slice of buffer to write on the next
673670
// region
674671
SharedBuffer buffer = incomingBuffer_.slice(bytesTransferred);
675-
auto weakSelf = weak_from_this();
672+
auto self = shared_from_this();
676673
auto nextMinReadSize = minReadSize - bytesTransferred;
677-
asyncReceive(buffer.asio_buffer(),
678-
customAllocReadHandler([weakSelf, nextMinReadSize](const boost::system::error_code& err,
679-
size_t bytesTransferred) {
680-
auto self = weakSelf.lock();
681-
if (self) {
682-
self->handleRead(err, bytesTransferred, nextMinReadSize);
683-
}
674+
asyncReceive(buffer.asio_buffer(), customAllocReadHandler([this, self, nextMinReadSize](
675+
const boost::system::error_code& err,
676+
size_t bytesTransferred) {
677+
handleRead(err, bytesTransferred, nextMinReadSize);
684678
}));
685679
} else {
686680
processIncomingBuffer();
@@ -707,15 +701,12 @@ void ClientConnection::processIncomingBuffer() {
707701
uint32_t newBufferSize = std::max<uint32_t>(DefaultBufferSize, frameSize + sizeof(uint32_t));
708702
incomingBuffer_ = SharedBuffer::copyFrom(incomingBuffer_, newBufferSize);
709703
}
710-
auto weakSelf = weak_from_this();
704+
auto self = shared_from_this();
711705
asyncReceive(
712706
incomingBuffer_.asio_buffer(),
713-
customAllocReadHandler([weakSelf, bytesToReceive](const boost::system::error_code& err,
714-
size_t bytesTransferred) {
715-
auto self = weakSelf.lock();
716-
if (self) {
717-
self->handleRead(err, bytesTransferred, bytesToReceive);
718-
}
707+
customAllocReadHandler([this, self, bytesToReceive](const boost::system::error_code& err,
708+
size_t bytesTransferred) {
709+
handleRead(err, bytesTransferred, bytesToReceive);
719710
}));
720711
return;
721712
}
@@ -793,14 +784,11 @@ void ClientConnection::processIncomingBuffer() {
793784
// At least we need to read 4 bytes to have the complete frame size
794785
uint32_t minReadSize = sizeof(uint32_t) - incomingBuffer_.readableBytes();
795786

796-
auto weakSelf = weak_from_this();
787+
auto self = shared_from_this();
797788
asyncReceive(incomingBuffer_.asio_buffer(),
798-
customAllocReadHandler([weakSelf, minReadSize](const boost::system::error_code& err,
799-
size_t bytesTransferred) {
800-
auto self = weakSelf.lock();
801-
if (self) {
802-
self->handleRead(err, bytesTransferred, minReadSize);
803-
}
789+
customAllocReadHandler([this, self, minReadSize](const boost::system::error_code& err,
790+
size_t bytesTransferred) {
791+
handleRead(err, bytesTransferred, minReadSize);
804792
}));
805793
return;
806794
}

0 commit comments

Comments
 (0)