summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHwankyu Jhun <h.jhun@samsung.com>2021-08-26 15:41:09 +0900
committerHwanKyu Jhun <h.jhun@samsung.com>2021-09-10 04:49:32 +0000
commit84d060938354347c77e6db179beecec97bb255d6 (patch)
tree5af8206b4df3dc91ce0afc76b7091bfda40dc80b
parentb999c7c02e24f48104dee1a2c8352ce9ecacaa99 (diff)
downloadtidl-84d060938354347c77e6db179beecec97bb255d6.tar.gz
tidl-84d060938354347c77e6db179beecec97bb255d6.tar.bz2
tidl-84d060938354347c77e6db179beecec97bb255d6.zip
Check sequence number
When getting the result from the stub, the proxy checks whether the tag exists or not. If it's existed, the proxy checks the sequence number. If the sequence number is not matched, the proxy tries to get the parcel from the port again. Change-Id: I02b962cc54871ad31aadd74552c63255f8b7aa14 Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
-rw-r--r--idlc/gen/c_body_gen_base.cc4
-rw-r--r--idlc/gen/c_body_gen_base.h1
-rw-r--r--idlc/gen/c_body_gen_base_cb.h10
-rw-r--r--idlc/gen/c_proxy_body_gen.cc1
-rw-r--r--idlc/gen/c_proxy_body_gen_cb.h34
-rw-r--r--idlc/gen/c_stub_body_gen.cc1
-rw-r--r--idlc/gen/c_stub_body_gen_cb.h10
-rw-r--r--idlc/gen/cpp_gen_base.cc4
-rw-r--r--idlc/gen/cpp_gen_base.h1
-rw-r--r--idlc/gen/cpp_gen_base_cb.h10
-rw-r--r--idlc/gen/cpp_proxy_body_gen.cc65
-rw-r--r--idlc/gen/cpp_proxy_body_gen_cb.h58
-rw-r--r--idlc/gen/cpp_stub_body_gen.cc11
-rw-r--r--idlc/gen/cpp_stub_body_gen_cb.h17
-rw-r--r--idlc/gen/cs_proxy_gen.cc24
-rw-r--r--idlc/gen/cs_proxy_gen_cb.h39
-rw-r--r--idlc/gen/cs_stub_gen.cc4
-rw-r--r--idlc/gen/cs_stub_gen_cb.h13
18 files changed, 232 insertions, 75 deletions
diff --git a/idlc/gen/c_body_gen_base.cc b/idlc/gen/c_body_gen_base.cc
index 4784797..e1c3cf7 100644
--- a/idlc/gen/c_body_gen_base.cc
+++ b/idlc/gen/c_body_gen_base.cc
@@ -82,6 +82,10 @@ void CBodyGeneratorBase::GenLogDefinition(std::ofstream& stream) {
stream << SmartIndent(CB_LOG_DEF);
}
+void CBodyGeneratorBase::GenVersionDefinition(std::ofstream& stream) {
+ stream << ReplaceAll(CB_VERSION_DEF, "<VERSION>", FULLVER);
+}
+
void CBodyGeneratorBase::GenBaseDefinition(std::ofstream& stream) {
stream << SmartIndent(CB_BASE_DEF);
}
diff --git a/idlc/gen/c_body_gen_base.h b/idlc/gen/c_body_gen_base.h
index c2e7ffa..24bfeac 100644
--- a/idlc/gen/c_body_gen_base.h
+++ b/idlc/gen/c_body_gen_base.h
@@ -35,6 +35,7 @@ class CBodyGeneratorBase : public CGeneratorBase {
void GenIncludeHeader(std::ofstream& stream);
void GenLogTag(std::ofstream& stream, const std::string& log_tag);
void GenLogDefinition(std::ofstream& stream);
+ void GenVersionDefinition(std::ofstream& stream);
void GenBaseDefinition(std::ofstream& stream);
const std::string& GetParcelType(const BaseType& type);
diff --git a/idlc/gen/c_body_gen_base_cb.h b/idlc/gen/c_body_gen_base_cb.h
index a8f9a67..4cb55d6 100644
--- a/idlc/gen/c_body_gen_base_cb.h
+++ b/idlc/gen/c_body_gen_base_cb.h
@@ -41,6 +41,16 @@ R"__c_cb(
#define _D(fmt, ...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
)__c_cb";
+/**
+ * <VERSION> Version of TIDL Compiler.
+ */
+constexpr const char CB_VERSION_DEF[] =
+R"__c_cb(
+#ifndef TIDL_VERSION
+#define TIDL_VERSION "<VERSION>"
+#endif
+)__c_cb";
+
constexpr const char CB_BASE_DEF[] =
R"__c_cb(
#ifndef nullptr
diff --git a/idlc/gen/c_proxy_body_gen.cc b/idlc/gen/c_proxy_body_gen.cc
index 5d15665..d24488d 100644
--- a/idlc/gen/c_proxy_body_gen.cc
+++ b/idlc/gen/c_proxy_body_gen.cc
@@ -33,6 +33,7 @@ void CProxyBodyGen::OnInitGen(std::ofstream& stream) {
GenIncludeHeader(stream);
GenLogTag(stream, std::string("RPC_PORT_PROXY"));
GenLogDefinition(stream);
+ GenVersionDefinition(stream);
GenBaseDefinition(stream);
GenInterfaceDelegateCallback(stream);
GenStructureDefs(stream);
diff --git a/idlc/gen/c_proxy_body_gen_cb.h b/idlc/gen/c_proxy_body_gen_cb.h
index 3052175..fd10328 100644
--- a/idlc/gen/c_proxy_body_gen_cb.h
+++ b/idlc/gen/c_proxy_body_gen_cb.h
@@ -735,6 +735,8 @@ R"__c_cb(
void <PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>)
{
rpc_port_parcel_h parcel_;
+ rpc_port_parcel_header_h header_;
+ int seq_num_ = -1;
int res_;
if (h == nullptr<METHOD_PARAMS_CHECK>) {
@@ -759,6 +761,11 @@ void <PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>)
return;
}
+ rpc_port_parcel_get_header(parcel_, &header_);
+ rpc_port_parcel_header_set_tag(header_, TIDL_VERSION);
+ rpc_port_parcel_header_get_seq_num(header_, &seq_num_);
+ _W("[Version] \"%d\", [Sequence] %d", TIDL_VERSION, seq_num_);
+
rpc_port_parcel_write_int32(parcel_, <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>);
<METHOD_PARCEL_WRITE>
@@ -795,6 +802,11 @@ R"__c_cb(
<RETURN_TYPE><PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>)
{
rpc_port_parcel_h parcel_;
+ rpc_port_parcel_header_h header_;
+ int seq_num_ = -1;
+ int recv_seq_num_ = -1;
+ char *tag_ = nullptr;
+ bool done_ = false;
int res_;
<RETURN_TYPE>ret_ = <ERROR_VALUE>;
<METHOD_ARGS>
@@ -821,6 +833,11 @@ R"__c_cb(
return ret_;
}
+ rpc_port_parcel_get_header(parcel_, &header_);
+ rpc_port_parcel_header_set_tag(header_, TIDL_VERSION);
+ rpc_port_parcel_header_get_seq_num(header_, &seq_num_);
+ _W("[Version] \"%s\", [Sequence] %d", TIDL_VERSION, seq_num_);
+
rpc_port_parcel_write_int32(parcel_, <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>);
<METHOD_PARCEL_WRITE>
@@ -844,9 +861,24 @@ R"__c_cb(
break;
}
+ rpc_port_parcel_get_header(parcel_, &header_);
+ rpc_port_parcel_header_get_tag(header_, &tag_);
+ if (tag_ && tag_[0] != '\0') {
+ _W("[Version] %s", tag_);
+ rpc_port_parcel_header_get_seq_num(header_, &recv_seq_num_);
+ if (recv_seq_num_ != seq_num_) {
+ _E("Invalid protocol. %d", recv_seq_num_);
+ free(tag_);
+ rpc_port_parcel_destroy(parcel_);
+ continue;
+ }
+ }
+ done_ = true;
+ free(tag_);
+
<METHOD_PARCEL_READ>
rpc_port_parcel_destroy(parcel_);
- } while (0);
+ } while (!done_);
g_rec_mutex_unlock(&h->mutex);
set_last_result(res_);
diff --git a/idlc/gen/c_stub_body_gen.cc b/idlc/gen/c_stub_body_gen.cc
index c0d6826..03a29b3 100644
--- a/idlc/gen/c_stub_body_gen.cc
+++ b/idlc/gen/c_stub_body_gen.cc
@@ -33,6 +33,7 @@ void CStubBodyGen::OnInitGen(std::ofstream& stream) {
GenIncludeHeader(stream);
GenLogTag(stream, std::string("RPC_PORT_STUB"));
GenLogDefinition(stream);
+ GenVersionDefinition(stream);
GenBaseDefinition(stream);
GenThreadEnableDefinition(stream);
GenInterfaceMethodHandlerType(stream);
diff --git a/idlc/gen/c_stub_body_gen_cb.h b/idlc/gen/c_stub_body_gen_cb.h
index a75a68b..4d25311 100644
--- a/idlc/gen/c_stub_body_gen_cb.h
+++ b/idlc/gen/c_stub_body_gen_cb.h
@@ -702,6 +702,8 @@ R"__c_cb(
static int __<PREFIX>_<NAME>_method_<METHOD_NAME>_handler(rpc_port_h port, rpc_port_parcel_h parcel, void *user_data)
{
<PREFIX>_<NAME>_context_h context_ = user_data;
+ rpc_port_parcel_header_h header_;
+ int seq_num_ = -1;
rpc_port_h callback_port_;
int ret_;
<METHOD_HANDLER_ARGS_DECL>
@@ -712,6 +714,10 @@ static int __<PREFIX>_<NAME>_method_<METHOD_NAME>_handler(rpc_port_h port, rpc_p
goto out;
}
+ rpc_port_parcel_get_header(parcel, &header_);
+ rpc_port_parcel_header_get_seq_num(header_, &seq_num_);
+ _W("[Sequence] %d", seq_num_);
+
<METHOD_HANDLER_PARCEL_READ>
<METHOD_HANDLER_CALLBACK_INVOKE>
<METHOD_HANDLER_PARCEL_WRITE>
@@ -823,6 +829,10 @@ if (ret_ != RPC_PORT_ERROR_NONE) {
goto out;
}
+rpc_port_parcel_get_header(parcel_, &header_);
+rpc_port_parcel_header_set_tag(header_, TIDL_VERSION);
+rpc_port_parcel_header_set_seq_num(header_, seq_num_);
+
rpc_port_parcel_write_int32(parcel_, RPC_PORT_STUB_<UPPERCASE_NAME>_METHOD_RESULT_);
)__c_cb";
diff --git a/idlc/gen/cpp_gen_base.cc b/idlc/gen/cpp_gen_base.cc
index f901eaf..83aaf1e 100644
--- a/idlc/gen/cpp_gen_base.cc
+++ b/idlc/gen/cpp_gen_base.cc
@@ -747,4 +747,8 @@ void CppGeneratorBase::GenLogDefinition(std::ofstream& stream) {
stream << CB_LOG_DEF;
}
+void CppGeneratorBase::GenVersionDefinition(std::ofstream& stream) {
+ stream << ReplaceAll(CB_VERSION_DEF, "[VERSION]", FULLVER);
+}
+
} // namespace tidl
diff --git a/idlc/gen/cpp_gen_base.h b/idlc/gen/cpp_gen_base.h
index fce6c56..4b575fc 100644
--- a/idlc/gen/cpp_gen_base.h
+++ b/idlc/gen/cpp_gen_base.h
@@ -60,6 +60,7 @@ class CppGeneratorBase : public Generator {
std::string GetParameters(const Parameters& ps);
void GenLogTag(std::ofstream& stream, std::string id);
void GenLogDefinition(std::ofstream& stream);
+ void GenVersionDefinition(std::ofstream& stream);
private:
void GenSetter(std::ofstream& stream, const Element& ele);
diff --git a/idlc/gen/cpp_gen_base_cb.h b/idlc/gen/cpp_gen_base_cb.h
index 46f58b2..84ef269 100644
--- a/idlc/gen/cpp_gen_base_cb.h
+++ b/idlc/gen/cpp_gen_base_cb.h
@@ -261,4 +261,14 @@ R"__cpp_cb(
#define _D(fmt, ...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
)__cpp_cb";
+/**
+ * [VERSION] Version of TIDL Compiler.
+ */
+constexpr const char CB_VERSION_DEF[] =
+R"__cpp_cb(
+#ifndef TIDL_VERSION
+#define TIDL_VERSION "[VERSION]"
+#endif
+)__cpp_cb";
+
#endif // IDLC_CPP_GEN_CPP_GEN_BASE_CB_H_
diff --git a/idlc/gen/cpp_proxy_body_gen.cc b/idlc/gen/cpp_proxy_body_gen.cc
index 06a739d..7df3e8b 100644
--- a/idlc/gen/cpp_proxy_body_gen.cc
+++ b/idlc/gen/cpp_proxy_body_gen.cc
@@ -42,6 +42,7 @@ void CppProxyBodyGen::OnInitGen(std::ofstream& stream) {
<< "#include \"" << header_file << "\"" << NLine(2);
GenLogTag(stream, "RPC_PORT_PROXY");
GenLogDefinition(stream);
+ GenVersionDefinition(stream);
stream << NLine(1);
GenNamespace(stream);
}
@@ -155,22 +156,13 @@ void CppProxyBodyGen::GenInvocation(std::ofstream& stream,
}
stream << AddIndent(TAB_SIZE, m) << NLine(1);
- if (decl.GetMethodType() == Declaration::MethodType::SYNC)
- stream << Tab(1) << "rpc_port_parcel_h parcel_received;" << NLine(1);
- stream << Tab(1) << "do ";
- GenBrace(stream, TAB_SIZE, [&]() {
- stream << Tab(2) << "std::lock_guard<std::recursive_mutex> lock(mutex_);"
- << NLine(2);
- if (!l.empty())
- stream << AddIndent(TAB_SIZE * 2, l);
- stream << CB_INVOCATION_MID << NLine(1);
- if (decl.GetMethodType() == Declaration::MethodType::SYNC) {
- stream << Tab(2) << "// Receive" << NLine(1);
- stream << Tab(2)
- << "ConsumeCommand(&parcel_received, port_);" << NLine(1);
- }
- }, false, false);
- stream << " while (false);" << NLine(1);
+ stream << Tab(1) << "std::lock_guard<std::recursive_mutex> lock(mutex_);"
+ << NLine(1);
+
+ if (!l.empty())
+ stream << AddIndent(TAB_SIZE, l);
+
+ stream << CB_INVOCATION_MID;
// Deserialize
if (decl.GetMethodType() == Declaration::MethodType::ASYNC) {
@@ -179,24 +171,29 @@ void CppProxyBodyGen::GenInvocation(std::ofstream& stream,
return;
}
- stream << CB_INVOCATION_RECEIVE << NLine(1);
- for (auto& i : decl.GetParameters().GetParams()) {
- if (i->GetParameterType().GetDirection() == ParameterType::Direction::IN) {
- continue;
- }
-
- std::string c = ConvertTypeToDeserializer(
- i->GetParameterType().GetBaseType(),
- i->GetID(), "parcel_received", false);
- if (c != "")
- stream << AddIndent(TAB_SIZE, c);
- }
-
- if (decl.GetType().ToString() != "void") {
- stream << AddIndent(TAB_SIZE,
- ConvertTypeToDeserializer(decl.GetType(),
- "ret", "parcel_received"));
- }
+ auto parcel_read = [&]() -> std::string {
+ std::string code;
+ for (auto& i : decl.GetParameters().GetParams()) {
+ if (i->GetParameterType().GetDirection() ==
+ ParameterType::Direction::IN)
+ continue;
+
+ std::string c = ConvertTypeToDeserializer(
+ i->GetParameterType().GetBaseType(), i->GetID(),
+ "parcel_received", false);
+ if (c != "")
+ code += AddIndent(TAB_SIZE * 2, c);
+ }
+
+ if (decl.GetType().ToString() != "void") {
+ code += AddIndent(TAB_SIZE * 2,
+ ConvertTypeToDeserializer(decl.GetType(), "ret",
+ "parcel_received"));
+ }
+
+ return code;
+ };
+ stream << ReplaceAll(CB_INVOCATION_RECEIVE, "[PARCEL_READ]", parcel_read());
stream << CB_INVOCATION_END;
}
diff --git a/idlc/gen/cpp_proxy_body_gen_cb.h b/idlc/gen/cpp_proxy_body_gen_cb.h
index 83a9f08..96ba708 100644
--- a/idlc/gen/cpp_proxy_body_gen_cb.h
+++ b/idlc/gen/cpp_proxy_body_gen_cb.h
@@ -33,31 +33,65 @@ R"__cpp_cb( if (port_ == nullptr) {
rpc_port_parcel_h p;
rpc_port_parcel_create(&p);
+
+ rpc_port_parcel_header_h header_;
+ rpc_port_parcel_get_header(p, &header_);
+ rpc_port_parcel_header_set_tag(header_, TIDL_VERSION);
+ int seq_num_ = -1;
+ rpc_port_parcel_header_get_seq_num(header_, &seq_num_);
+ _W("[Version] \"%s\", [Sequence] %d", TIDL_VERSION, seq_num_);
)__cpp_cb";
const char CB_INVOCATION_MID[] =
R"__cpp_cb(
- // Send
- int r = rpc_port_parcel_send(p, port_);
- if (r != RPC_PORT_ERROR_NONE) {
- _E("Failed to send parcel. result(%d)", r);
- rpc_port_parcel_destroy(p);
- throw InvalidIOException();
- }
+ // Send
+ int r = rpc_port_parcel_send(p, port_);
+ if (r != RPC_PORT_ERROR_NONE) {
+ _E("Failed to send parcel. result(%d)", r);
+ rpc_port_parcel_destroy(p);
+ throw InvalidIOException();
+ }
)__cpp_cb";
+/**
+ * [PARCEL_READ] The implementation to read the data from the parcel.
+ */
const char CB_INVOCATION_RECEIVE[] =
R"__cpp_cb(
- if (parcel_received == nullptr) {
- _E("Invalid protocol");
- throw InvalidProtocolException();
- }
+ bool done_ = false;
+ do {
+ rpc_port_parcel_h parcel_received = nullptr;
+ // Receive
+ ConsumeCommand(&parcel_received, port_);
+ if (parcel_received == nullptr) {
+ _E("Invalid protocol");
+ throw InvalidProtocolException();
+ }
+
+ rpc_port_parcel_get_header(parcel_received, &header_);
+ char* tag_ = nullptr;
+ rpc_port_parcel_header_get_tag(header_, &tag_);
+ std::unique_ptr<char, decltype(std::free)*> tag_auto_(tag_, std::free);
+ if (tag_ && tag_[0] != '\0') {
+ _W("[Version] %s", tag_);
+ int seq_num_received_ = -1;
+ rpc_port_parcel_header_get_seq_num(header_, &seq_num_received_);
+ if (seq_num_received_ != seq_num_) {
+ _E("Invalid protocol. %d", seq_num_received_);
+ rpc_port_parcel_destroy(parcel_received);
+ continue;
+ }
+ }
+ done_ = true;
+
+[PARCEL_READ]
+ rpc_port_parcel_destroy(parcel_received);
+ } while (!done_);
)__cpp_cb";
const char CB_INVOCATION_END[] =
R"__cpp_cb(
rpc_port_parcel_destroy(p);
- rpc_port_parcel_destroy(parcel_received);
return ret;
)__cpp_cb";
diff --git a/idlc/gen/cpp_stub_body_gen.cc b/idlc/gen/cpp_stub_body_gen.cc
index 3c840b7..e460964 100644
--- a/idlc/gen/cpp_stub_body_gen.cc
+++ b/idlc/gen/cpp_stub_body_gen.cc
@@ -44,6 +44,7 @@ void CppStubBodyGen::OnInitGen(std::ofstream& stream) {
<< "#include \"" << header_file << "\"" << NLine(2);
GenLogTag(stream, "RPC_PORT_STUB");
GenLogDefinition(stream);
+ GenVersionDefinition(stream);
stream << NLine(1);
GenNamespace(stream);
}
@@ -132,13 +133,9 @@ void CppStubBodyGen::GenReceivedEvent(std::ofstream& stream,
return iface.GetID();
});
} else {
- GenTemplate(CB_ON_RECEIVED_CB_FRONT, stream,
- [&]()->std::string {
- return iface.GetID();
- },
- [&]()->std::string {
- return iface.GetID();
- });
+ std::string code = ReplaceAll(CB_ON_RECEIVED_CB_FRONT, "[NAME]",
+ iface.GetID());
+ stream << code;
}
for (auto& i : iface.GetDeclarations().GetDecls()) {
diff --git a/idlc/gen/cpp_stub_body_gen_cb.h b/idlc/gen/cpp_stub_body_gen_cb.h
index 709ea4d..deea256 100644
--- a/idlc/gen/cpp_stub_body_gen_cb.h
+++ b/idlc/gen/cpp_stub_body_gen_cb.h
@@ -101,13 +101,18 @@ void ##::ServiceBase::Dispatch(rpc_port_h port,
)__cpp_cb";
+/**
+ * [NAME] The name of the interface.
+ */
const char CB_ON_RECEIVED_CB_FRONT[] =
R"__cpp_cb(
-int $$::OnReceivedCB(const char* sender, const char* instance, rpc_port_h port, void *data)
+int [NAME]::OnReceivedCB(const char* sender, const char* instance, rpc_port_h port, void *data)
{
- auto* cxt = static_cast<$$*>(data);
+ auto* cxt = static_cast<[NAME]*>(data);
rpc_port_parcel_h p;
rpc_port_parcel_h result;
+ rpc_port_parcel_h header;
+ int seq_num = -1;
int cmd;
int ret;
std::shared_ptr<ServiceBase> b;
@@ -137,7 +142,15 @@ int $$::OnReceivedCB(const char* sender, const char* instance, rpc_port_h port,
return ret;
}
+ rpc_port_parcel_get_header(p, &header);
+ rpc_port_parcel_header_get_seq_num(header, &seq_num);
+ _W("[Sequence] %d", seq_num);
+
rpc_port_parcel_create(&result);
+ rpc_port_parcel_get_header(result, &header);
+ rpc_port_parcel_header_set_tag(header, TIDL_VERSION);
+ rpc_port_parcel_header_set_seq_num(header, seq_num);
+
rpc_port_parcel_read_int32(p, &cmd);
switch (cmd) {
diff --git a/idlc/gen/cs_proxy_gen.cc b/idlc/gen/cs_proxy_gen.cc
index 51def89..8d8d88c 100644
--- a/idlc/gen/cs_proxy_gen.cc
+++ b/idlc/gen/cs_proxy_gen.cc
@@ -66,7 +66,7 @@ void CsProxyGen::GenInterface(std::ofstream& stream, const Interface& iface) {
stream << Tab(2) << "public class " << iface.GetID()
<< " : ProxyBase" << NLine(1);
GenBrace(stream, TAB_SIZE * 2, [&]() {
- stream << CB_DATA_MEMBERS;
+ stream << ReplaceAll(CB_DATA_MEMBERS, "<VERSION>", FULLVER);
GenCallbacks(stream, iface, true);
GenDelegateId(stream, iface);
GenMethodId(stream, iface);
@@ -157,18 +157,12 @@ void CsProxyGen::GenInvocation(std::ofstream& stream, const Declaration& decl) {
st += AddIndent(TAB_SIZE * 5, m) + NLine(1);
- if (decl.GetMethodType() == Declaration::MethodType::SYNC)
- st += Tab(5) + "Parcel parcelReceived;" + NLine(1);
st += Tab(5) + "lock (_lock)" + NLine(1);
st += Tab(5) + "{" + NLine(1);
- if (!l.empty())
- st += AddIndent(TAB_SIZE * 6, l) + NLine(1);
- st += CB_INVOCATION_MID + NLine(1);
- if (decl.GetMethodType() == Declaration::MethodType::SYNC) {
- st += Tab(6) + "// Receive" + NLine(1);
- st += Tab(6)
- + "ConsumeCommand(out parcelReceived, Port);" + NLine(1);
- }
+ if (!l.empty())
+ st += AddIndent(TAB_SIZE * 6, l) + NLine(1);
+
+ st += CB_INVOCATION_MID + NLine(1);
st += Tab(5) + "}";
// Deserialize
@@ -176,12 +170,8 @@ void CsProxyGen::GenInvocation(std::ofstream& stream, const Declaration& decl) {
return st;
}
- const char* receive_block =
- "if (parcelReceived == null)\n" \
- "{\n" \
- " throw new InvalidProtocolException();\n" \
- "}\n";
- st += NLine(1) + AddIndent(TAB_SIZE * 5, receive_block) + NLine(1);
+ st += NLine(1) + AddIndent(TAB_SIZE * 5, CB_INVOCATION_RECEIVE);
+ st += NLine(1);
for (auto& i : decl.GetParameters().GetParams()) {
if (i->GetParameterType().GetDirection() ==
diff --git a/idlc/gen/cs_proxy_gen_cb.h b/idlc/gen/cs_proxy_gen_cb.h
index 21e25b9..b416f6b 100644
--- a/idlc/gen/cs_proxy_gen_cb.h
+++ b/idlc/gen/cs_proxy_gen_cb.h
@@ -17,11 +17,15 @@
#ifndef IDLC_CS_GEN_CS_PROXY_GEN_CB_H_
#define IDLC_CS_GEN_CS_PROXY_GEN_CB_H_
+/**
+ * <VERSION> Version of TIDL Compiler.
+ */
const char CB_DATA_MEMBERS[] =
R"__cs_cb( public event EventHandler Connected;
public event EventHandler Disconnected;
public event EventHandler Rejected;
+ private static readonly string _tidlVersion = "<VERSION>";
private bool _online = false;
private string _appId;
private Object _lock = new Object();
@@ -167,6 +171,8 @@ R"__cs_cb( if (!_online)
using (Parcel p = new Parcel())
{
+ ParcelHeader header = p.GetHeader();
+ header.SetTag(_tidlVersion);
$$
}
)__cs_cb";
@@ -189,4 +195,37 @@ R"__cs_cb( // Send
p.Send(Port);
)__cs_cb";
+const char CB_INVOCATION_RECEIVE[] =
+R"__cs_cb(
+Parcel parcelReceived;
+bool done = false;
+do
+{
+ lock (_lock)
+ {
+ // Receive
+ ConsumeCommand(out parcelReceived, Port);
+ }
+
+ if (parcelReceived == null)
+ {
+ throw new InvalidProtocolException();
+ }
+
+ ParcelHeader headerReceived = parcelReceived.GetHeader();
+ if (!string.IsNullOrEmpty(headerReceived.GetTag()))
+ {
+ if (headerReceived.GetSequenceNumber() != header.GetSequenceNumber())
+ {
+ parcelReceived.Dispose();
+ parcelReceived = null;
+ }
+ }
+
+ if (parcelReceived != null)
+ done = true;
+}
+while (!done);
+)__cs_cb";
+
#endif // IDLC_CS_GEN_CS_PROXY_GEN_CB_H_
diff --git a/idlc/gen/cs_stub_gen.cc b/idlc/gen/cs_stub_gen.cc
index 04b68b3..5cf40fd 100644
--- a/idlc/gen/cs_stub_gen.cc
+++ b/idlc/gen/cs_stub_gen.cc
@@ -65,7 +65,7 @@ void CsStubGen::GenInterface(std::ofstream& stream, const Interface& iface) {
stream << Tab(2) << "public sealed class " << iface.GetID()
<< " : StubBase" << NLine(1);
GenBrace(stream, TAB_SIZE * 2, [&]() {
- stream << CB_DATA_MEMBERS;
+ stream << ReplaceAll(CB_DATA_MEMBERS, "<VERSION>", FULLVER);
GenServiceBase(stream, iface);
GenCallbacks(stream, iface, false);
GenDelegateId(stream, iface);
@@ -168,7 +168,7 @@ void CsStubGen::GenInvocation(std::ofstream& stream, const Declaration& decl) {
return;
cnt = 0;
- m = "result.WriteInt((int)MethodId.__Result);\n";
+ m = CB_INVOCATION_RESULT_PRE;
for (auto& i : decl.GetParameters().GetParams()) {
auto& pt = i->GetParameterType();
cnt++;
diff --git a/idlc/gen/cs_stub_gen_cb.h b/idlc/gen/cs_stub_gen_cb.h
index 3be382a..1eeb36e 100644
--- a/idlc/gen/cs_stub_gen_cb.h
+++ b/idlc/gen/cs_stub_gen_cb.h
@@ -17,9 +17,13 @@
#ifndef IDLC_CS_GEN_CS_STUB_GEN_CB_H_
#define IDLC_CS_GEN_CS_STUB_GEN_CB_H_
+/**
+ * <VERSION> Version of TIDL Compiler.
+ */
const char CB_DATA_MEMBERS[] =
R"__cs_cb( private List<ServiceBase> _services = new List<ServiceBase>();
private Type _serviceType;
+ private static readonly string _tidlVersion = "<VERSION>";
)__cs_cb";
const char CB_SERVICE_BASE_FRONT[] =
@@ -184,4 +188,13 @@ R"__cs_cb(
}
)__cs_cb";
+constexpr const char CB_INVOCATION_RESULT_PRE[] =
+R"__cs_cb(
+ParcelHeader header = p.GetHeader();
+ParcelHeader resultHeader = result.GetHeader();
+resultHeader.SetTag(_tidlVersion);
+resultHeader.SetSequenceNumber(header.GetSequenceNumber());
+result.WriteInt((int)MethodId.__Result);
+)__cs_cb";
+
#endif // IDLC_CS_GEN_CS_STUB_GEN_CB_H_