From 9654db9d10de18160afc91bea33d10bbd2ccb67e Mon Sep 17 00:00:00 2001 From: jusung son Date: Wed, 13 Sep 2023 16:16:47 +0900 Subject: [PATCH] Support Local Execution Mode for C# Generator Change-Id: I334e779f472e3a6b0fe7c128db69c3eed21b8621 Signed-off-by: jusung son --- idlc/gen/version2/cs_generator_base.cc | 10 +- idlc/gen/version2/cs_generator_base.h | 8 +- idlc/gen/version2/cs_generator_base_cb.h | 44 +++-- idlc/gen/version2/cs_proxy_generator.cc | 18 +- idlc/gen/version2/cs_proxy_generator.h | 1 + idlc/gen/version2/cs_proxy_generator_cb.h | 270 +++++++++++++++++++++++++++--- idlc/gen/version2/cs_stub_generator.cc | 21 ++- idlc/gen/version2/cs_stub_generator.h | 1 + idlc/gen/version2/cs_stub_generator_cb.h | 169 +++++++++++++++++-- 9 files changed, 470 insertions(+), 72 deletions(-) diff --git a/idlc/gen/version2/cs_generator_base.cc b/idlc/gen/version2/cs_generator_base.cc index 17dadfe..8c7aa5d 100644 --- a/idlc/gen/version2/cs_generator_base.cc +++ b/idlc/gen/version2/cs_generator_base.cc @@ -385,11 +385,9 @@ std::string CsGeneratorBase::ConvertTypeToDeserializer( ret += map + ".Read(" + "\"" + param_id + "\", out "; if (IsDelegateType(type)) { ret += "CallbackBase del_" + gen_id + ");\n"; - ret += - new_type + " " + gen_id + " = new " + new_type + - "(GetPort(Port.Type.Callback, instance), new WeakReference(b), del_" + - gen_id + ");\n"; - + ret += ReplaceAll(CB_DLELGATGE_CREATE) + .Change("", new_type) + .Change("", gen_id); } else { if (make_new_type) { ret += new_type + " " + gen_id + ");\n"; @@ -855,7 +853,7 @@ void CsGeneratorBase::GenInvokeMethod(std::ofstream& stream, for (const auto& i : decl.GetParameters()) { m += ConvertTypeToSerializer(i->GetID(), i->GetID(), "map"); } - return AddIndent(TAB_SIZE * 6, m); + return AddIndent(TAB_SIZE * 5, m); }); } diff --git a/idlc/gen/version2/cs_generator_base.h b/idlc/gen/version2/cs_generator_base.h index f177206..39ffa75 100644 --- a/idlc/gen/version2/cs_generator_base.h +++ b/idlc/gen/version2/cs_generator_base.h @@ -106,10 +106,10 @@ class CsGeneratorBase : public Generator { std::string GenUnitMapParamInit(const Interface& iface, const BaseType& base_type, const std::string& type_str); - std::string GetStructureSerialize(const Structure& st); - std::string GetStructureDeserialize(const Structure& st); - std::string GetStructTypeString(const BaseType& base_type); - std::string GetStructTypeString(const Structure& st); + std::string GetStructureSerialize(const Structure& st); + std::string GetStructureDeserialize(const Structure& st); + std::string GetStructTypeString(const BaseType& base_type); + std::string GetStructTypeString(const Structure& st); private: std::map type_map_; diff --git a/idlc/gen/version2/cs_generator_base_cb.h b/idlc/gen/version2/cs_generator_base_cb.h index 638438f..60aae64 100644 --- a/idlc/gen/version2/cs_generator_base_cb.h +++ b/idlc/gen/version2/cs_generator_base_cb.h @@ -21,12 +21,14 @@ const char CB_USING_NAMESPACE[] = R"__cs_cb( using System; using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Threading; +using System.Reflection; using Tizen.Applications; using Tizen.Applications.RPCPort; )__cs_cb"; - const char CB_REMOTE_EXCEPTION_BASE[] = R"__cs_cb( public class RemoteException : Exception @@ -253,33 +255,40 @@ const char CB_CALLBACK_STUB_MEMBERS[] = R"__cs_cb( private Port _port; private WeakReference _service; private bool _valid = true; - + internal LocalExecution _lem; )__cs_cb"; const char CB_CALLBACK_INVOKE_METHOD[] = R"__cs_cb( public void Invoke($$) { - if (_port == null) + if (_port == null && _lem == null) throw new NotConnectedSocketException(); if (!_service.IsAlive) throw new InvalidProtocolException(); if (Once && !_valid) throw new InvalidCallbackException(); + if (_lem != null && _lem._online == false) + throw new NotConnectedSocketException(); - using (var p = new Parcel()) - { - UnitMap map = new UnitMap(); + var p = new Parcel(); + UnitMap map = new UnitMap(); - map.Write("[METHOD]", (int)MethodId.__Callback); - map.Write("delegate", this); + map.Write("[METHOD]", (int)MethodId.__Callback); + map.Write("delegate", this); $$ - map.Serialize(p); + map.Serialize(p); + + if (_lem != null) + { + _lem.SendRequest(p); + } else + { // Send p.Send(_port); - _valid = false; } + _valid = false; } )__cs_cb"; @@ -293,6 +302,21 @@ $$ } )__cs_cb"; +const char CB_DLELGATGE_CREATE[] = +R"__cs_cb( +Port cb_port; +if (b._lem != null) + cb_port = null; +else + cb_port = GetPort(Port.Type.Callback, instance); + + = new (cb_port, new WeakReference(b), del_); + +if (b._lem != null) + param3._lem = b._lem; +)__cs_cb"; + + const char CB_WRITE_BUNDLE[] = R"__cs_cb( if (param.$$ != null) diff --git a/idlc/gen/version2/cs_proxy_generator.cc b/idlc/gen/version2/cs_proxy_generator.cc index bf8e5bd..8218a32 100644 --- a/idlc/gen/version2/cs_proxy_generator.cc +++ b/idlc/gen/version2/cs_proxy_generator.cc @@ -39,6 +39,7 @@ void CsProxyGen::GenNamespace(std::ofstream& stream) { GenBrace(stream, 0, [&]() { stream << "namespace " << GetFileNamespace() << NLine(1); GenBrace(stream, 0, [&]() { + GenLemBase(stream); GenRemoteException(stream); GenStructures(stream); stream << Tab(1) << "namespace Proxy" << NLine(1); @@ -49,6 +50,10 @@ void CsProxyGen::GenNamespace(std::ofstream& stream) { }); } +void CsProxyGen::GenLemBase(std::ofstream& stream) { + stream << CB_LEM_BASE; +} + void CsProxyGen::GenInterfaces(std::ofstream& stream) { for (auto& i : GetDocument().GetBlocks()) { if (i->GetType() != Block::TYPE_INTERFACE) continue; @@ -97,11 +102,9 @@ void CsProxyGen::GenEventMethod(std::ofstream& stream, const Interface& iface) { } void CsProxyGen::GenCtor(std::ofstream& stream, const Interface& iface) { - const char* m = "public $$(string appId) => _appId = appId;\n"; - - stream << NLine(1); - GenTemplate(AddIndent(TAB_SIZE * 3, m), stream, - [&]() -> std::string { return iface.GetID(); }); + ReplaceAll(CB_CONSTRUCTOR_METHOD) + .Change("", iface.GetID()) + .Out(stream); } void CsProxyGen::GenConnectMethod(std::ofstream& stream, @@ -179,12 +182,15 @@ void CsProxyGen::GenInvocation(std::ofstream& stream, const Declaration& decl) { st += Tab(5) + "{" + NLine(1); if (!l.empty()) st += AddIndent(TAB_SIZE * 6, l) + NLine(1); - st += CB_INVOCATION_MID + NLine(1); + // Deserialize if (decl.GetMethodType() == Declaration::MethodType::ASYNC) { + st += CB_INVOCATION_ASYNC_MID + NLine(1); st += Tab(5) + "}"; return st; + } else { + st += CB_INVOCATION_SYNC_MID + NLine(1); } st += NLine(1) + AddIndent(TAB_SIZE * 5, CB_INVOCATION_RECEIVE); diff --git a/idlc/gen/version2/cs_proxy_generator.h b/idlc/gen/version2/cs_proxy_generator.h index 03850f1..a929041 100644 --- a/idlc/gen/version2/cs_proxy_generator.h +++ b/idlc/gen/version2/cs_proxy_generator.h @@ -43,6 +43,7 @@ class CsProxyGen : public CsGeneratorBase { void GenInvocation(std::ofstream& stream, const Declaration& decl); void GenEventMethod(std::ofstream& stream, const Interface& iface); void GenMemberData(std::ofstream& stream, const Interface& iface); + void GenLemBase(std::ofstream& stream); }; } // namespace version2 diff --git a/idlc/gen/version2/cs_proxy_generator_cb.h b/idlc/gen/version2/cs_proxy_generator_cb.h index 81d4955..4901392 100644 --- a/idlc/gen/version2/cs_proxy_generator_cb.h +++ b/idlc/gen/version2/cs_proxy_generator_cb.h @@ -29,17 +29,154 @@ R"__cs_cb( public event EventHandler Connected; private bool _online = false; private string _appId; private Object _lock = new Object(); + private bool _connecting = false; + private LocalExecution _lem; + private SynchronizationContext _async_context = TizenSynchronizationContext.Current; )__cs_cb"; + +const char CB_LEM_BASE[] = +R"__cs_cb( internal class LocalExecution + { + internal bool IsListen = false; + object _instance = null; + string _instance_id = null; + string _appId = null; + static int _seq = 0; + MethodInfo _send = null; + MethodInfo _connect = null; + MethodInfo _disconnect = null; + ConcurrentQueue _result = new ConcurrentQueue(); + + internal LocalExecution(string appId, string interfaceName) + { + string current_appid = Application.Current.ApplicationInfo.ApplicationId; + + if (current_appid != appId) + return; + + _seq++; + _instance_id = appId + "::" + _seq.ToString(); + _appId = appId; + + Assembly assembly = Assembly.GetExecutingAssembly(); + Type type = null; + + foreach (Type t in assembly.GetTypes()) + { + if (t.Name != interfaceName) + continue; + + string[] name = t.FullName?.Split('.'); + + if (name == null || name.Length != 4) + continue; + + if (name[0] == "RPCPort" && name[2] == "Stub") + { + if (type == null) + { + type = t; + } + else + { + type = null; + break; + } + } + } + + if (type == null) + return; + + MethodInfo getInstance = type.GetMethod("GetInstance", BindingFlags.Static | BindingFlags.NonPublic); + if (getInstance == null) { return; } + + _instance = getInstance.Invoke(null, null); + if (_instance == null) { return; } + + _send = type.GetMethod("OnLemReceivedEvent", BindingFlags.NonPublic | BindingFlags.Instance); + if (_send == null) { return; } + + _connect = type.GetMethod("OnLemConnectedEvent", BindingFlags.NonPublic | BindingFlags.Instance); + if (_connect == null) { return; } + + _disconnect = type.GetMethod("OnLemDisconnectedEvent", BindingFlags.NonPublic | BindingFlags.Instance); + if (_disconnect == null) { return; } + + MethodInfo getListen = type.GetMethod("GetListenStatus", BindingFlags.NonPublic | BindingFlags.Instance); + if (getListen == null) { return; } + + object ret = getListen.Invoke(_instance, null); + if (ret == null) { return; } + IsListen = (bool)ret; + } + + internal void Connect(object proxy_instance) + { + _connect.Invoke(_instance, new object[] { proxy_instance, _appId, _instance_id }); + } + + internal void Disconnect() + { + _disconnect.Invoke(_instance, new object[] { _appId, _instance_id }); + } + + internal void Send(Parcel p) + { + _send.Invoke(_instance, new object[] { _instance_id, p}); + } + + internal void Send(Parcel p, ref Parcel resutl) + { + Send(p); + + int count = 0; + while (_result.IsEmpty && count++ < 100) + Thread.Sleep(100); + + if (ResultQueuePop(out resutl)) + { + Tizen.Log.Error("RPC_PORT", "ResultQueuePop"); + return; + } + + Tizen.Log.Error("RPC_PORT_PROXY", "Failed to get result from server"); + throw new InvalidIOException(); + } + + internal void ResultQueuePush(Parcel p) + { + _result.Enqueue(p); + } + + internal bool ResultQueuePop(out Parcel p) + { + return _result.TryDequeue(out p); + } + } +)__cs_cb"; + const char CB_DATA_CALLBACK_LIST[] = R"__cs_cb( private List _delegateList = new List(); )__cs_cb"; const char CB_EVENT_PROCESS_EVENT_BASE[] = R"__cs_cb( - private void ProcessReceivedEvent(UnitMap map) + private void ProcessReceivedEvent(Parcel parcelReceived) { + UnitMap map = new UnitMap(); + map.Deserialize(parcelReceived); + + int cmd; + map.Read("[METHOD]", out cmd); + + if (cmd != (int)MethodId.__Callback) + { + return; + } + CallbackBase cb; map.Read("delegate", out cb); @@ -54,6 +191,16 @@ R"__cs_cb( } } } + + internal void OnLemReceivedEvent(Parcel parcelReceived) + { + _async_context.Post((data) => + { + ProcessReceivedEvent(parcelReceived); + + }, null); + } + )__cs_cb"; const char CB_EVENT_RECEIVE_EVENT_BASE[] = @@ -70,18 +217,7 @@ R"__cs_cb( Parcel parcelReceived; using (parcelReceived) { - UnitMap map = new UnitMap(); - map.Deserialize(parcelReceived); - - int cmd; - map.Read("[METHOD]", out cmd); - - if (cmd != (int)MethodId.__Callback) - { - return; - } - - ProcessReceivedEvent(map); + ProcessReceivedEvent(parcelReceived); } )__cs_cb"; @@ -90,6 +226,7 @@ R"__cs_cb( protected override void OnConnectedEvent(string endPoint, string portName, Port port) { _online = true; + _connecting = false; Connected?.Invoke(this, null); } @@ -99,8 +236,24 @@ R"__cs_cb( Disconnected?.Invoke(this, null); } + internal void OnLemDisconnectedEvent() + { + _async_context.Post((data) => + { + OnDisconnectedEvent(null, null); + + }, null); + + } + + internal void OnLemResultEvent(Parcel result) + { + _lem.ResultQueuePush(result); + } + protected override void OnRejectedEvent(string endPoint, string portName) { + _connecting = false; Rejected?.Invoke(this, null); } @@ -163,6 +316,15 @@ R"__cs_cb( } )__cs_cb"; +const char CB_CONSTRUCTOR_METHOD[] = +R"__cs_cb( + public (string appId) + { + _appId = appId; + _lem = new LocalExecution(appId, ""); + } +)__cs_cb"; + const char CB_CONNECT_METHOD[] = R"__cs_cb( /// @@ -182,7 +344,23 @@ R"__cs_cb( /// If you want to use this method, you must add privileges. public void Connect() { - Connect(_appId, "$$"); + if (_lem.IsListen) + { + if (_online || _connecting) + throw new InvalidIDException(); + + _connecting = true; + _lem.Connect(this); + + _async_context.Post((data) => + { + OnConnectedEvent(null, null, null); + }, null); + } + else + { + Connect(_appId, "$$"); + } } /// @@ -193,7 +371,16 @@ R"__cs_cb( /// public void Disconnect() { - Port?.Disconnect(); + if (_lem.IsListen) + { + if (_online) + _lem.Disconnect(); + } + else + { + Port?.Disconnect(); + } + _online = false; } /// @@ -213,7 +400,19 @@ R"__cs_cb( /// If you want to use this method, you must add privileges. public void ConnectSync() { - ConnectSync(_appId, "$$"); + if (_lem.IsListen) + { + if (_online || _connecting) + throw new InvalidIDException(); + + _connecting = true; + _lem.Connect(this); + OnConnectedEvent(null, null, null); + } + else + { + ConnectSync(_appId, "$$"); + } } )__cs_cb"; @@ -242,17 +441,44 @@ $$ } )__cs_cb"; -const char CB_INVOCATION_MID[] = +const char CB_INVOCATION_ASYNC_MID[] = R"__cs_cb( // Send - p.Send(Port); + if (_lem.IsListen) + { + _lem.Send(p); + } + else + { + p.Send(Port); + } +)__cs_cb"; + +const char CB_INVOCATION_SYNC_MID[] = +R"__cs_cb( // Send + Parcel ret_parcel = new Parcel(); + // Send + if (_lem.IsListen) + { + _lem.Send(p, ref ret_parcel); + } + else + { + p.Send(Port); + } )__cs_cb"; const char CB_INVOCATION_RECEIVE[] = R"__cs_cb( UnitMap mapReceived; - - // Receive - ConsumeCommand(out mapReceived, Port, header); - + if (_lem.IsListen) + { + mapReceived = new UnitMap(); + mapReceived.Deserialize(ret_parcel); + } + else + { + // Receive + ConsumeCommand(out mapReceived, Port, header); + } if (mapReceived == null) { diff --git a/idlc/gen/version2/cs_stub_generator.cc b/idlc/gen/version2/cs_stub_generator.cc index 2e9aced..a74d651 100644 --- a/idlc/gen/version2/cs_stub_generator.cc +++ b/idlc/gen/version2/cs_stub_generator.cc @@ -39,6 +39,7 @@ void CsStubGen::GenNamespace(std::ofstream& stream) { GenBrace(stream, 0, [&]() { stream << "namespace " << GetFileNamespace() << NLine(1); GenBrace(stream, 0, [&]() { + GenLemBase(stream); GenRemoteException(stream); GenStructures(stream); stream << Tab(1) << "namespace Stub" << NLine(1); @@ -47,6 +48,10 @@ void CsStubGen::GenNamespace(std::ofstream& stream) { }); } +void CsStubGen::GenLemBase(std::ofstream& stream) { + stream << CB_LEM_BASE; +} + void CsStubGen::GenInterfaces(std::ofstream& stream) { for (auto& i : GetDocument().GetBlocks()) { if (i->GetType() != Block::TYPE_INTERFACE) continue; @@ -107,10 +112,10 @@ void CsStubGen::GenReceivedEvent(std::ofstream& stream, stream << CB_ON_RECEIVED_EVENT_FRONT; for (const auto& i : iface.GetDeclarations()) { if (i->GetMethodType() == Declaration::MethodType::DELEGATE) continue; - stream << Tab(7) << "case MethodId." << i->GetID() << ":" << NLine(1); - GenBrace(stream, TAB_SIZE * 8, [&]() { + stream << Tab(6) << "case MethodId." << i->GetID() << ":" << NLine(1); + GenBrace(stream, TAB_SIZE * 7, [&]() { GenInvocation(stream, *i); - stream << Tab(9) << "break;" << NLine(1); + stream << Tab(8) << "break;" << NLine(1); }); } stream << CB_ON_RECEIVED_EVENT_BACK; @@ -192,7 +197,7 @@ void CsStubGen::GenInvocation(std::ofstream& stream, const Declaration& decl) { std::string v = "param" + std::to_string(cnt); std::string c = ConvertTypeToDeserializer( i->GetParameterType().GetBaseType(), v, i->GetID(), "map"); - stream << AddIndent(TAB_SIZE * 9, c); + stream << AddIndent(TAB_SIZE * 8, c); cnt++; } @@ -205,17 +210,15 @@ void CsStubGen::GenInvocation(std::ofstream& stream, const Declaration& decl) { .Change("", AddIndent(TAB_SIZE, GetInvocationMethod(decl))); - stream << AddIndent(TAB_SIZE * 9, m); + stream << AddIndent(TAB_SIZE * 8, m); // Serialize if (decl.GetMethodType() == Declaration::MethodType::ASYNC) return; cnt = 0; - m = CB_INVOCATION_RESULT_PRE; - m += "result_map.Serialize(result);\n"; - m += "result.Send(port);\n"; - stream << AddIndent(TAB_SIZE * 9, m); + m = CB_INVOCATION_RESULT; + stream << AddIndent(TAB_SIZE * 8, m); } void CsStubGen::GenConnectedEvent(std::ofstream& stream) { diff --git a/idlc/gen/version2/cs_stub_generator.h b/idlc/gen/version2/cs_stub_generator.h index a04199a..a4e09ea 100644 --- a/idlc/gen/version2/cs_stub_generator.h +++ b/idlc/gen/version2/cs_stub_generator.h @@ -51,6 +51,7 @@ class CsStubGen : public CsGeneratorBase { std::string GetInvocationMethodParam(const Declaration& decl, bool hasRet); std::string GetInvocationMethod(const Declaration& decl); std::string GetWriteOutParam(const Declaration& decl); + void GenLemBase(std::ofstream& stream); }; } // namespace version2 diff --git a/idlc/gen/version2/cs_stub_generator_cb.h b/idlc/gen/version2/cs_stub_generator_cb.h index 3da305f..23866a7 100644 --- a/idlc/gen/version2/cs_stub_generator_cb.h +++ b/idlc/gen/version2/cs_stub_generator_cb.h @@ -25,6 +25,59 @@ R"__cs_cb( private List _services = new List> _privilege_map = new Dictionary>(); + private static Message _instance; + private bool _isListen = false; + private SynchronizationContext _async_context = TizenSynchronizationContext.Current; +)__cs_cb"; + +const char CB_LEM_BASE[] = +R"__cs_cb( internal class LocalExecution + { + object _instance = null; + MethodInfo _send_result = null; + MethodInfo _send_request = null; + MethodInfo _disconnect = null; + + internal bool _online = false; + + internal LocalExecution (object instance) + { + Type type = instance.GetType(); + + if (type == null) + return; + + _send_result = type.GetMethod("OnLemResultEvent", BindingFlags.NonPublic | BindingFlags.Instance); + if (_send_result == null) { return; } + + _send_request = type.GetMethod("OnLemReceivedEvent", BindingFlags.NonPublic | BindingFlags.Instance); + + _disconnect = type.GetMethod("OnLemDisconnectedEvent", BindingFlags.NonPublic | BindingFlags.Instance); + if (_disconnect == null) { return; } + + _instance = instance; + _online = true; + + } + + internal void SendResult(Parcel result) + { + _send_result.Invoke(_instance, new object[] {result}); + } + + internal void SendRequest(Parcel result) + { + if (_send_request != null) + _send_request.Invoke(_instance, new object[] { result }); + } + + internal void Disconnect() + { + if (_online) + _disconnect.Invoke(_instance, null); + _online = false; + } + } )__cs_cb"; const char CB_SERVICE_BASE_FRONT[] = @@ -33,6 +86,7 @@ R"__cs_cb( { internal bool _is_app = true; internal List _privileges; + internal LocalExecution _lem; /// /// The client app ID @@ -81,8 +135,15 @@ R"__cs_cb( /// public void Disconnect() { - Port?.Disconnect(); - Port = null; + if(_lem != null) + { + _lem.Disconnect(); + } + else + { + Port?.Disconnect(); + Port = null; + } } /// @@ -139,6 +200,26 @@ R"__cs_cb( return false; } + return OnReceivedEvent(instance, port, p); + } + + internal void OnLemReceivedEvent(string instance, Parcel p) + { + if (Thread.CurrentThread.ManagedThreadId != 1) + { + _async_context.Post((data) => + { + ((Message)data).OnReceivedEvent(instance, null, p); + }, this); + } + else + { + OnReceivedEvent(instance, null, p); + } + } + + internal bool OnReceivedEvent(string instance, Port port, Parcel p) + { try { ServiceBase b = null; @@ -157,23 +238,22 @@ R"__cs_cb( return false; } - using (var result = new Parcel()) - { - int cmd; - UnitMap map = new UnitMap(); - map.Deserialize(p); + var result = new Parcel(); - map.Read("[METHOD]", out cmd); + int cmd; + UnitMap map = new UnitMap(); + map.Deserialize(p); - switch ((MethodId)cmd) - { + map.Read("[METHOD]", out cmd); + + switch ((MethodId)cmd) + { )__cs_cb"; const char CB_ON_RECEIVED_EVENT_BACK[] = R"__cs_cb( - default: - return false; - } + default: + return false; } return true; @@ -198,8 +278,29 @@ R"__cs_cb( s.LoadPrivilege(); s.Instance = instance; s.Port = GetPort(Port.Type.Callback, instance); + _services.Add(s); s.OnCreate(); + } + + internal void OnLemConnectedEvent(object proxy_instance, string sender, string instance) + { + ServiceBase s = Activator.CreateInstance(_serviceType) as ServiceBase; + s.Sender = sender; + s.LoadPrivilege(); + s.Instance = instance; + s._lem = new LocalExecution(proxy_instance); _services.Add(s); + if (Thread.CurrentThread.ManagedThreadId != 1) + { + _async_context.Post((data) => + { + ((ServiceBase)data).OnCreate(); + }, s); + } + else + { + s.OnCreate(); + } } )__cs_cb"; @@ -211,18 +312,47 @@ R"__cs_cb( { if (i.Instance.Equals(instance)) { + if (i._lem != null) + i._lem._online = false; + i.OnTerminate(); _services.Remove(i); break; } } } + + internal void OnLemDisconnectedEvent(string sender, string instance) + { + if (Thread.CurrentThread.ManagedThreadId != 1) + { + _async_context.Post((data) => + { + ((Message)data).OnDisconnectedEvent(sender, instance); + }, this); + } + else + { + OnDisconnectedEvent(sender, instance); + } + } )__cs_cb"; const char CB_CTOR_FRONT[] = R"__cs_cb( + internal static Message GetInstance() + { + return _instance; + } + + internal bool GetListenStatus() + { + return _isListen; + } + public $$() : base("$$") { + _instance = this; )__cs_cb"; const char CB_COMMON_METHODS[] = @@ -243,6 +373,7 @@ R"__cs_cb( throw new ArgumentException("Invalid type"); _serviceType = serviceType; Listen(); + _isListen = true; } /// @@ -261,6 +392,8 @@ R"__cs_cb( { foreach (var i in _services) { + if (i._lem != null) + i._lem._online = false; i.OnTerminate(); } } @@ -288,14 +421,20 @@ R"__cs_cb(try result_map.Write("[REMOTE_EXCEPTION]", ex); })__cs_cb"; -constexpr const char CB_INVOCATION_RESULT_PRE[] = +constexpr const char CB_INVOCATION_RESULT[] = R"__cs_cb( ParcelHeader header = p.GetHeader(); ParcelHeader resultHeader = result.GetHeader(); resultHeader.SetTag(_tidlVersion); resultHeader.SetSequenceNumber(header.GetSequenceNumber()); - result_map.Write("[METHOD]", (int)MethodId.__Result); +result_map.Serialize(result); + +if (b._lem != null) + b._lem.SendResult(result); +else + result.Send(port); + )__cs_cb"; #endif // IDLC_CS_GEN_VERSION2_CS_STUB_GENRATOR_CB_H_ \ No newline at end of file -- 2.7.4