Просмотр исходного кода

修复message和meta在send阶段可能由于局部变量被析构的bug

tanghai 14 лет назад
Родитель
Сommit
68921379f1

+ 3 - 3
Src/Egametang/Rpc/CMakeLists.txt

@@ -6,7 +6,7 @@ SET(RpcSrc
 	RpcCommunicator.cc
 	RpcController.cc
 	RpcHandler.cc
-	RpcChannel.cc
+#	RpcChannel.cc
 	${proto_srcs}
 	)
 
@@ -14,11 +14,11 @@ SET(RpcSrc
 ADD_LIBRARY(Rpc ${RpcSrc})
 
 ADD_EXECUTABLE(RpcCommunicatorTest RpcCommunicatorTest.cc)
-ADD_EXECUTABLE(RpcChannelTest RpcChannelTest.cc)
+#ADD_EXECUTABLE(RpcChannelTest RpcChannelTest.cc)
 
 SET(Excutes 
 	RpcCommunicatorTest
-	RpcChannelTest
+#	RpcChannelTest
 )
 
 FOREACH(Excute ${Excutes})

+ 31 - 28
Src/Egametang/Rpc/RpcCommunicator.cc

@@ -16,28 +16,33 @@ boost::asio::ip::tcp::socket& RpcCommunicator::Socket()
 	return socket_;
 }
 
-void RpcCommunicator::RecvMeta()
+void RpcCommunicator::Stop()
+{
+	socket_.close();
+}
+
+
+void RpcCommunicator::RecvMeta(RpcMetaPtr meta, StringPtr message)
 {
-	RpcMetaPtr meta(new RpcMeta());
 	boost::asio::async_read(socket_,
 			boost::asio::buffer(reinterpret_cast<char*>(meta.get()), sizeof(*meta)),
-			boost::bind(&RpcCommunicator::RecvMessage, this, meta,
-					boost::asio::placeholders::error));
+			boost::bind(&RpcCommunicator::RecvMessage, this,
+					meta, message, boost::asio::placeholders::error));
 }
 
-void RpcCommunicator::RecvMessage(RpcMetaPtr meta, const boost::system::error_code& err)
+void RpcCommunicator::RecvMessage(RpcMetaPtr meta, StringPtr message,
+		const boost::system::error_code& err)
 {
 	if (err)
 	{
 		LOG(ERROR) << "receive message size failed: " << err.message();
 		return;
 	}
-	StringPtr message(new std::string(meta->size, '\0'));
+	message->resize(meta->size, '\0');
 	boost::asio::async_read(socket_,
 			boost::asio::buffer(reinterpret_cast<char*>(&message->at(0)), meta->size),
 			boost::bind(&RpcCommunicator::RecvDone, this,
-					meta, message,
-					boost::asio::placeholders::error));
+					meta, message, boost::asio::placeholders::error));
 }
 
 void RpcCommunicator::RecvDone(RpcMetaPtr meta, StringPtr message,
@@ -51,48 +56,46 @@ void RpcCommunicator::RecvDone(RpcMetaPtr meta, StringPtr message,
 	OnRecvMessage(meta, message);
 }
 
-void RpcCommunicator::SendMeta(RpcMeta meta, std::string message)
+void RpcCommunicator::OnRecvMessage(RpcMetaPtr meta, StringPtr message)
+{
+}
+
+
+void RpcCommunicator::SendMeta(RpcMetaPtr meta, StringPtr message)
 {
-	CHECK_EQ(meta.size, message.size()) << "meta and message size not match!";
+	CHECK_EQ(meta->size, message->size()) << "meta and message size not match!";
 	boost::asio::async_write(socket_,
-			boost::asio::buffer(reinterpret_cast<char*>(&meta), sizeof(meta)),
-			boost::bind(&RpcCommunicator::SendMessage, this, message,
-					boost::asio::placeholders::error));
+			boost::asio::buffer(reinterpret_cast<char*>(meta.get()), sizeof(*meta)),
+			boost::bind(&RpcCommunicator::SendMessage, this,
+					meta, message, boost::asio::placeholders::error));
 }
 
-void RpcCommunicator::SendMessage(std::string message, const boost::system::error_code& err)
+void RpcCommunicator::SendMessage(RpcMetaPtr meta, StringPtr message,
+		const boost::system::error_code& err)
 {
 	if (err)
 	{
 		LOG(ERROR) << "send message size failed: " << err.message();
 		return;
 	}
-	boost::asio::async_write(socket_, boost::asio::buffer(message),
+	boost::asio::async_write(socket_, boost::asio::buffer(*message),
 			boost::bind(&RpcCommunicator::SendDone, this,
-					boost::asio::placeholders::error));
+					meta, message, boost::asio::placeholders::error));
 }
 
-void RpcCommunicator::SendDone(const boost::system::error_code& err)
+void RpcCommunicator::SendDone(RpcMetaPtr meta, StringPtr message,
+		const boost::system::error_code& err)
 {
 	if (err)
 	{
 		LOG(ERROR) << "send message failed: " << err.message();
 		return;
 	}
-	OnSendMessage();
-}
-
-void RpcCommunicator::OnRecvMessage(RpcMetaPtr meta, StringPtr message)
-{
-}
-
-void RpcCommunicator::OnSendMessage()
-{
+	OnSendMessage(meta, message);
 }
 
-void RpcCommunicator::Stop()
+void RpcCommunicator::OnSendMessage(RpcMetaPtr meta, StringPtr message)
 {
-	socket_.close();
 }
 
 } // namespace Egametang

+ 9 - 11
Src/Egametang/Rpc/RpcCommunicator.h

@@ -39,25 +39,23 @@ protected:
 	boost::asio::io_service& io_service_;
 	boost::asio::ip::tcp::socket socket_;
 
-public:
 	explicit RpcCommunicator(boost::asio::io_service& io_service);
 
 	boost::asio::ip::tcp::socket& Socket();
 
+	virtual void Stop();
+
 	// recieve response
-	void RecvMeta();
-	void RecvMessage(RpcMetaPtr meta, const boost::system::error_code& err);
+	void RecvMeta(RpcMetaPtr meta, StringPtr message);
+	void RecvMessage(RpcMetaPtr meta, StringPtr message, const boost::system::error_code& err);
 	void RecvDone(RpcMetaPtr meta, StringPtr message, const boost::system::error_code& err);
-
-	// send request
-	void SendMeta(RpcMeta meta, std::string message);
-	void SendMessage(std::string message, const boost::system::error_code& err);
-	void SendDone(const boost::system::error_code& err);
-
 	virtual void OnRecvMessage(RpcMetaPtr meta, StringPtr message);
-	virtual void OnSendMessage();
 
-	virtual void Stop();
+	// send request
+	void SendMeta(RpcMetaPtr meta, StringPtr message);
+	void SendMessage(RpcMetaPtr meta, StringPtr message, const boost::system::error_code& err);
+	void SendDone(RpcMetaPtr meta, StringPtr message, const boost::system::error_code& err);
+	virtual void OnSendMessage(RpcMetaPtr meta, StringPtr message);
 };
 
 } // namespace Egametang

+ 27 - 20
Src/Egametang/Rpc/RpcCommunicatorTest.cc

@@ -16,7 +16,7 @@ class RpcServerTest: public RpcCommunicator
 public:
 	CountBarrier& barrier_;
 	std::string recv_string_;
-	RpcMetaPtr meta_;
+	RpcMeta meta_;
 	boost::asio::ip::tcp::acceptor acceptor_;
 
 public:
@@ -43,7 +43,10 @@ public:
 			LOG(ERROR) << "async accept failed: " << err.message();
 			return;
 		}
-		RecvMeta();
+
+		RpcMetaPtr meta(new RpcMeta());
+		StringPtr message(new std::string);
+		RecvMeta(meta, message);
 	}
 
 	void Start()
@@ -62,15 +65,16 @@ public:
 	{
 		VLOG(2) << "Server Recv string: " << *message;
 		recv_string_ = *message;
-		meta_ = meta;
+		meta_ = *meta;
 
 		boost::hash<std::string> string_hash;
 
-		std::string response_string("response test rpc communicator string");
-		RpcMeta response_meta;
-		response_meta.size = response_string.size();
-		response_meta.method = 123456;
-		SendMeta(response_meta, response_string);
+		RpcMetaPtr response_meta(new RpcMeta());
+		StringPtr response_message(new std::string("response test rpc communicator string"));
+		response_meta->size = response_message->size();
+		response_meta->method = 123456;
+		SendMeta(response_meta, response_message);
+
 		barrier_.Signal();
 	}
 	virtual void OnSendMessage()
@@ -83,7 +87,7 @@ class RpcClientTest: public RpcCommunicator
 public:
 	CountBarrier& barrier_;
 	std::string recv_string_;
-	RpcMetaPtr meta_;
+	RpcMeta meta_;
 
 public:
 	RpcClientTest(boost::asio::io_service& io_service, int port,
@@ -118,19 +122,22 @@ public:
 		}
 		boost::hash<std::string> string_hash;
 
-		std::string send_string("send test rpc communicator string");
-		RpcMeta meta;
-		meta.size = send_string.size();
-		meta.method = 654321;
-		SendMeta(meta, send_string);
-		RecvMeta();
+		RpcMetaPtr send_meta(new RpcMeta());
+		StringPtr send_message(new std::string("send test rpc communicator string"));
+		send_meta->size = send_message->size();
+		send_meta->method = 654321;
+		SendMeta(send_meta, send_message);
+
+		RpcMetaPtr meta(new RpcMeta());
+		StringPtr message(new std::string);
+		RecvMeta(meta, message);
 	}
 
 	virtual void OnRecvMessage(RpcMetaPtr meta, StringPtr message)
 	{
 		VLOG(2) << "Client Recv string: " << *message;
 		recv_string_ = *message;
-		meta_ = meta;
+		meta_ = *meta;
 		barrier_.Signal();
 	}
 
@@ -169,12 +176,12 @@ TEST_F(RpcCommunicatorTest, SendAndRecvString)
 	rpc_client_.Stop();
 
 	ASSERT_EQ(std::string("send test rpc communicator string"), rpc_server_.recv_string_);
-	ASSERT_EQ(rpc_server_.meta_->size, rpc_server_.recv_string_.size());
-	ASSERT_EQ(654321U, rpc_server_.meta_->method);
+	ASSERT_EQ(rpc_server_.meta_.size, rpc_server_.recv_string_.size());
+	ASSERT_EQ(654321U, rpc_server_.meta_.method);
 
 	ASSERT_EQ(std::string("response test rpc communicator string"), rpc_client_.recv_string_);
-	ASSERT_EQ(rpc_client_.meta_->size, rpc_client_.recv_string_.size());
-	ASSERT_EQ(123456U, rpc_client_.meta_->method);
+	ASSERT_EQ(rpc_client_.meta_.size, rpc_client_.recv_string_.size());
+	ASSERT_EQ(123456U, rpc_client_.meta_.method);
 }
 
 } // namespace Egametang