From bcd96a9ffa306a10d96b986834f9e84f7d90b862 Mon Sep 17 00:00:00 2001 From: Junghoon Park Date: Tue, 30 Jan 2018 18:44:39 +0900 Subject: [PATCH] Make generated APIs thread-safe Change-Id: I63c7998e99ec90ffc24cd52a77c946590b0a7391 Signed-off-by: Junghoon Park --- idlc/cs_gen/cs_proxy_gen.cc | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/idlc/cs_gen/cs_proxy_gen.cc b/idlc/cs_gen/cs_proxy_gen.cc index aa621d4..482ee1d 100644 --- a/idlc/cs_gen/cs_proxy_gen.cc +++ b/idlc/cs_gen/cs_proxy_gen.cc @@ -72,6 +72,7 @@ void CsProxyGen::GenInterface(std::ofstream& stream, const Interface& iface) { "private IntPtr _port;\n" \ "private bool _online = false;\n" \ "private string _appId;\n" \ + "private Object _lock = new Object();\n" \ "private List _delegateList = new List();\n" \ "private Interop.LibRPCPort.Proxy.ConnectedEventCallback _connectedEventCallback;\n" \ "private Interop.LibRPCPort.Proxy.DisconnectedEventCallback _disconnectedEventCallback;\n" \ @@ -113,8 +114,12 @@ void CsProxyGen::GenInterface(std::ofstream& stream, const Interface& iface) { "\n" \ "private void OnReceivedEvent(string endPoint, string port_name, IntPtr data)\n" \ "{\n" \ - " if (Interop.LibRPCPort.Parcel.CreateFromPort(out IntPtr parcel_received, _port) != 0)\n" \ - " return;\n" \ + " IntPtr parcel_received;\n" \ + " lock (_lock)\n" \ + " {\n" \ + " if (Interop.LibRPCPort.Parcel.CreateFromPort(out parcel_received, _port) != 0)\n" \ + " return;\n" \ + " }\n" \ "\n" \ " Interop.LibRPCPort.Parcel.ReadInt32(parcel_received, out int cmd);\n" \ " if (cmd != (int)MethodId.Callback)\n" \ @@ -228,8 +233,7 @@ void CsProxyGen::GenInvocation(std::ofstream& stream, const Declaration& decl) { const char* mid = "// Send\n" \ - "Interop.LibRPCPort.Parcel.Send(p, _port);\n" \ - "Interop.LibRPCPort.Parcel.Destroy(p);\n"; + "Interop.LibRPCPort.Parcel.Send(p, _port);\n"; stream << AddIndent(TAB_SIZE * 4, pre); @@ -238,25 +242,40 @@ void CsProxyGen::GenInvocation(std::ofstream& stream, const Declaration& decl) { << "Interop.LibRPCPort.Parcel.WriteInt32(p, (int)MethodId." << decl.GetID() << ");" << NLine(1); std::string m; + std::string l; for (auto& i : decl.GetParameters().GetParams()) { auto& pt = i->GetParameterType(); if (pt.GetDirection() == ParameterType::Direction::OUT) continue; m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p"); if (IsDelegateType(pt.GetBaseType().ToString())) - m += "_delegateList.Add(" + i->GetID() + ");\n"; + l += "_delegateList.Add(" + i->GetID() + ");\n"; } - stream << AddIndent(TAB_SIZE * 4, m) << NLine(1); - stream << AddIndent(TAB_SIZE * 4, mid) << NLine(1); + + if (decl.GetMethodType() == Declaration::MethodType::SYNC) + stream << Tab(4) << "IntPtr parcel_received;" << NLine(1); + stream << Tab(4) << "lock (_lock)" << NLine(1); + GenBrace(stream, TAB_SIZE * 4, [&]() { + if (!l.empty()) + stream << AddIndent(TAB_SIZE * 5, l) << NLine(1); + stream << AddIndent(TAB_SIZE * 5, mid) << NLine(1); + if (decl.GetMethodType() == Declaration::MethodType::SYNC) { + stream << Tab(5) << "// Receive" << NLine(1); + stream << Tab(5) + << "ConsumeCommand(out parcel_received, _port);" << NLine(1); + } + }); + stream << NLine(1); // Deserialize - if (decl.GetMethodType() == Declaration::MethodType::ASYNC) + if (decl.GetMethodType() == Declaration::MethodType::ASYNC) { + stream << Tab(4) << "Interop.LibRPCPort.Parcel.Destroy(p);" + << NLine(1); return; + } const char* receive_block = - "// Receive\n" \ - "ConsumeCommand(out IntPtr parcel_received, _port);\n" \ "if (parcel_received == IntPtr.Zero)\n" \ "{\n" \ " throw new InvalidOperationException(\"Can't receive data\");\n" \ @@ -281,6 +300,8 @@ void CsProxyGen::GenInvocation(std::ofstream& stream, const Declaration& decl) { "ret", "parcel_received")); } + stream << Tab(4) << "Interop.LibRPCPort.Parcel.Destroy(p);" + << NLine(1); stream << Tab(4) << "Interop.LibRPCPort.Parcel.Destroy(parcel_received);" << NLine(1); -- 2.7.4