From e017fa8e86f8e88a7c0ee2d5e1a742d7f8af836a Mon Sep 17 00:00:00 2001 From: x72417256 Date: Fri, 16 Oct 2020 17:08:01 +0800 Subject: [PATCH 1/2] add smart pointer for TcpClient and Connector ,Solve the problem that the bound object has been destroyed during callback --- muduo/net/CMakeLists.txt | 2 +- muduo/net/Connector.cc | 51 +++++++++++++++++++++++++++++++++++++--- muduo/net/Connector.h | 12 ++++++++-- muduo/net/TcpClient.cc | 4 ++++ 4 files changed, 63 insertions(+), 6 deletions(-) diff --git a/muduo/net/CMakeLists.txt b/muduo/net/CMakeLists.txt index 7510d8760..dee07363e 100644 --- a/muduo/net/CMakeLists.txt +++ b/muduo/net/CMakeLists.txt @@ -27,7 +27,7 @@ set(net_SRCS TimerQueue.cc ) -add_library(muduo_net ${net_SRCS}) +add_library(muduo_net SHARED ${net_SRCS}) target_link_libraries(muduo_net muduo_base) #add_library(muduo_net_cpp11 ${net_SRCS}) diff --git a/muduo/net/Connector.cc b/muduo/net/Connector.cc index 0b492ad95..bfd22cdb9 100644 --- a/muduo/net/Connector.cc +++ b/muduo/net/Connector.cc @@ -28,9 +28,14 @@ Connector::Connector(EventLoop* loop, const InetAddress& serverAddr) state_(kDisconnected), retryDelayMs_(kInitRetryDelayMs) { - LOG_DEBUG << "ctor[" << this << "]"; + LOG_DEBUG << "ctor[" << this << "]"; } - +#ifdef _USE_SMART_POINTER_ +std::shared_ptr Connector::create(EventLoop *loop, const InetAddress &serverAddr) +{ + return std::shared_ptr(new Connector(loop,serverAddr)); +} +#endif Connector::~Connector() { LOG_DEBUG << "dtor[" << this << "]"; @@ -40,7 +45,19 @@ Connector::~Connector() void Connector::start() { connect_ = true; +#ifndef _USE_SMART_POINTER_ loop_->runInLoop(std::bind(&Connector::startInLoop, this)); // FIXME: unsafe +#else + std::weak_ptr pthis = shared_from_this(); + loop_->runInLoop([pthis]{ + auto pConnect = pthis.lock(); + if(pConnect){ + pConnect->startInLoop(); + }else{ + LOG_WARN<<"start connect ,but it is expired"; + } + }); +#endif } void Connector::startInLoop() @@ -60,7 +77,12 @@ void Connector::startInLoop() void Connector::stop() { connect_ = false; +#ifndef _USE_SMART_POINTER_ loop_->queueInLoop(std::bind(&Connector::stopInLoop, this)); // FIXME: unsafe + +#else + loop_->queueInLoop(std::bind(&Connector::stopInLoop, shared_from_this())); +#endif // FIXME: cancel timer } @@ -130,11 +152,30 @@ void Connector::connecting(int sockfd) setState(kConnecting); assert(!channel_); channel_.reset(new Channel(loop_, sockfd)); +#ifndef _USE_SMART_POINTER_ channel_->setWriteCallback( std::bind(&Connector::handleWrite, this)); // FIXME: unsafe channel_->setErrorCallback( std::bind(&Connector::handleError, this)); // FIXME: unsafe - +#else + std::weak_ptr pthis = shared_from_this(); + channel_->setWriteCallback([pthis]{ + auto p=pthis.lock(); + if(p){ + p->handleWrite(); + }else{ + LOG_WARN<<"connect writeable,but it is closed"; + } + }); + channel_->setErrorCallback([pthis]{ + auto p=pthis.lock(); + if(p){ + p->handleError(); + }else{ + LOG_WARN<<"connect error,but it is closed"; + } + }); +#endif // channel_->tie(shared_from_this()); is not working, // as channel_ is not managed by shared_ptr channel_->enableWriting(); @@ -146,7 +187,11 @@ int Connector::removeAndResetChannel() channel_->remove(); int sockfd = channel_->fd(); // Can't reset channel_ here, because we are inside Channel::handleEvent + #ifndef _USE_SMART_POINTER_ loop_->queueInLoop(std::bind(&Connector::resetChannel, this)); // FIXME: unsafe + #else + loop_->queueInLoop(std::bind(&Connector::resetChannel, shared_from_this())); +#endif return sockfd; } diff --git a/muduo/net/Connector.h b/muduo/net/Connector.h index 4b79fb2b2..136918313 100644 --- a/muduo/net/Connector.h +++ b/muduo/net/Connector.h @@ -16,7 +16,7 @@ #include #include - +#define _USE_SMART_POINTER_ namespace muduo { namespace net @@ -28,10 +28,18 @@ class EventLoop; class Connector : noncopyable, public std::enable_shared_from_this { + +#ifdef _USE_SMART_POINTER_ +protected: + Connector(EventLoop* loop, const InetAddress& serverAddr); +#endif public: typedef std::function NewConnectionCallback; - +#ifndef _USE_SMART_POINTER_ Connector(EventLoop* loop, const InetAddress& serverAddr); +#else + static std::shared_ptr create(EventLoop* loop, const InetAddress& serverAddr); +#endif ~Connector(); void setNewConnectionCallback(const NewConnectionCallback& cb) diff --git a/muduo/net/TcpClient.cc b/muduo/net/TcpClient.cc index 1e668b3c2..6df6e5b71 100644 --- a/muduo/net/TcpClient.cc +++ b/muduo/net/TcpClient.cc @@ -55,7 +55,11 @@ TcpClient::TcpClient(EventLoop* loop, const InetAddress& serverAddr, const string& nameArg) : loop_(CHECK_NOTNULL(loop)), + #ifndef _USE_SMART_POINTER_ connector_(new Connector(loop, serverAddr)), + #else + connector_(Connector::create(loop,serverAddr)), + #endif name_(nameArg), connectionCallback_(defaultConnectionCallback), messageCallback_(defaultMessageCallback), From 67fcbfd931dc72436e8637cfbd668fbce6de5877 Mon Sep 17 00:00:00 2001 From: x72417256 Date: Fri, 16 Oct 2020 17:18:35 +0800 Subject: [PATCH 2/2] revert net/CMakeLists.txt --- muduo/net/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/muduo/net/CMakeLists.txt b/muduo/net/CMakeLists.txt index dee07363e..7510d8760 100644 --- a/muduo/net/CMakeLists.txt +++ b/muduo/net/CMakeLists.txt @@ -27,7 +27,7 @@ set(net_SRCS TimerQueue.cc ) -add_library(muduo_net SHARED ${net_SRCS}) +add_library(muduo_net ${net_SRCS}) target_link_libraries(muduo_net muduo_base) #add_library(muduo_net_cpp11 ${net_SRCS})