Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solve the problem that the bound object has been destroyed during callback for TcpClient #489

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 48 additions & 3 deletions muduo/net/Connector.cc
Original file line number Diff line number Diff line change
@@ -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> Connector::create(EventLoop *loop, const InetAddress &serverAddr)
{
return std::shared_ptr<Connector>(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<Connector> 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<Connector> 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;
}

12 changes: 10 additions & 2 deletions muduo/net/Connector.h
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@

#include <functional>
#include <memory>

#define _USE_SMART_POINTER_
namespace muduo
{
namespace net
@@ -28,10 +28,18 @@ class EventLoop;
class Connector : noncopyable,
public std::enable_shared_from_this<Connector>
{

#ifdef _USE_SMART_POINTER_
protected:
Connector(EventLoop* loop, const InetAddress& serverAddr);
#endif
public:
typedef std::function<void (int sockfd)> NewConnectionCallback;

#ifndef _USE_SMART_POINTER_
Connector(EventLoop* loop, const InetAddress& serverAddr);
#else
static std::shared_ptr<Connector> create(EventLoop* loop, const InetAddress& serverAddr);
#endif
~Connector();

void setNewConnectionCallback(const NewConnectionCallback& cb)
4 changes: 4 additions & 0 deletions muduo/net/TcpClient.cc
Original file line number Diff line number Diff line change
@@ -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),