From: Hwankyu Jhun Date: Tue, 22 Aug 2023 08:20:42 +0000 (+0900) Subject: Support Local Execution Mode for C++ Generator X-Git-Tag: accepted/tizen/8.0/unified/20231005.093116~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F54%2F297654%2F8;p=platform%2Fcore%2Fappfw%2Ftidl.git Support Local Execution Mode for C++ Generator This patch supports the local execution mode. If the stub is equal to the proxy, the local method will be invoked. Change-Id: I913865b82f079b95b9b5d6c4c28b12792089467e Signed-off-by: Hwankyu Jhun --- diff --git a/idlc/gen/version2/cpp_generator_base.cc b/idlc/gen/version2/cpp_generator_base.cc index 71a2ea4..6addc1e 100644 --- a/idlc/gen/version2/cpp_generator_base.cc +++ b/idlc/gen/version2/cpp_generator_base.cc @@ -148,6 +148,11 @@ void CppGeneratorBase::GenVersionDefinition(std::ofstream& stream) { stream << NLine(1); } +void CppGeneratorBase::GenExportAPI(std::ofstream& stream) { + stream << CB_EXPORT_API; + stream << NLine(1); +} + std::string CppGeneratorBase::GenExceptions() { std::string code = CB_HEADER_UNIT_MAP_DEF; code += std::string(CB_EXCEPTIONS); @@ -318,6 +323,17 @@ std::string CppGeneratorBase::GetParameters(const Parameters& params) { return code; } +std::string CppGeneratorBase::GenParameters(const Structure& st) { + std::string params; + if (st.GetBase() != nullptr) + params += GenParameters(*st.GetBase()); + + if (!params.empty()) + params += ", "; + + return params + GenParameters(st.GetElements()); +} + std::string CppGeneratorBase::GenStructuresForHeader(bool use_file) { std::string code(CB_HEADER_BUNDLE); code += NLine(1); @@ -338,7 +354,8 @@ std::string CppGeneratorBase::GenStructuresForHeader(bool use_file) { std::string CppGeneratorBase::GenStructureForHeader(const Structure& st) { std::string code; - if (st.GetElements().Empty()) { + std::string params = GenParameters(st); + if (params.empty()) { if (st.GetBase() == nullptr) { code = ReplaceAll(CB_HEADER_STRUCTURE_BASE_EMPTY) .Change("", st.GetID()) @@ -360,11 +377,6 @@ std::string CppGeneratorBase::GenStructureForHeader(const Structure& st) { .Change("\n", GenStructureMembersForHeader(st.GetElements())); } else { - std::string params = GenParameters(st.GetBase()->GetElements()); - if (!params.empty()) - params += ", "; - - params += GenParameters(st.GetElements()); code = ReplaceAll(CB_HEADER_INHERITED_STRUCTURE_BASE) .Change("", st.GetID()) .Change("", st.GetBase()->GetID()) @@ -514,8 +526,9 @@ std::string CppGeneratorBase::GenStructures(bool use_file) { } std::string CppGeneratorBase::GenStructure(const Structure& st) { + std::string params = GenParameters(st); std::string code; - if (st.GetElements().Empty()) { + if (params.empty()) { code = ReplaceAll(CB_BODY_STRUCTURE_BASE_EMPTY) .Change("", st.GetID()); } else { @@ -523,21 +536,15 @@ std::string CppGeneratorBase::GenStructure(const Structure& st) { code = ReplaceAll(CB_BODY_STRUCTURE_BASE) .Change("", st.GetID()) - .Change("", GenParameters(st.GetElements())) + .Change("", params) .Change("", GenStructureMemberInit(st.GetElements())) .Change("", GenStructureGetterSetter(st)); } else { - std::string params = GenParameters(st.GetBase()->GetElements()); - if (!params.empty()) - params += ", "; - - params += GenParameters(st.GetElements()); code = ReplaceAll(CB_BODY_INHERITED_STRUCTURE_BASE) .Change("", st.GetID()) .Change("", st.GetBase()->GetID()) - .Change("", - GenStructureBaseArgs(st.GetBase()->GetElements())) + .Change("", GenStructureBaseArgs(*st.GetBase())) .Change("", params) .Change("", GenStructureMemberInit(st.GetElements())) .Change("", GenStructureGetterSetter(st)); @@ -547,6 +554,17 @@ std::string CppGeneratorBase::GenStructure(const Structure& st) { return code; } +std::string CppGeneratorBase::GenStructureBaseArgs(const Structure& st) { + std::string code; + if (st.GetBase() != nullptr) + code += GenStructureBaseArgs(*st.GetBase()); + + if (!code.empty()) + code += ", "; + + return code + GenStructureBaseArgs(st.GetElements()); +} + std::string CppGeneratorBase::GenStructureBaseArgs(const Elements& elms) { std::string code; for (auto& elm : elms) { @@ -613,10 +631,10 @@ void CppGeneratorBase::InitUnitTypes(bool use_file) { } for (const auto& decl : iface.GetDeclarations()) { + AddUnitType("delegate", + BaseType(iface.GetID() + "::CallbackBase", "", true), + iface.GetID()); if (decl->GetMethodType() == Declaration::MethodType::DELEGATE) { - AddUnitType("delegate", - BaseType(iface.GetID() + "::CallbackBase", "", true), - iface.GetID()); AddUnitType(decl->GetID(), BaseType(decl->GetID(), "", true), iface.GetID()); } else if (decl->GetMethodType() == Declaration::MethodType::SYNC) { diff --git a/idlc/gen/version2/cpp_generator_base.hh b/idlc/gen/version2/cpp_generator_base.hh index d752739..4f5677a 100644 --- a/idlc/gen/version2/cpp_generator_base.hh +++ b/idlc/gen/version2/cpp_generator_base.hh @@ -39,6 +39,7 @@ class CppGeneratorBase : public tidl::Generator { void GenLogTag(std::ofstream& stream, const std::string& log_tag); void GenLogDefinition(std::ofstream& stream); void GenVersionDefinition(std::ofstream& stream); + void GenExportAPI(std::ofstream& stream); std::string GenExceptions(); std::string GenStructuresForHeader(bool use_file = true); @@ -66,10 +67,12 @@ class CppGeneratorBase : public tidl::Generator { private: void AddTypeName(const Structure& st); + std::string GenParameters(const Structure& st); std::string GenStructureForHeader(const Structure& st); std::string GenStructureGetterSetterForHeader(const Elements& elms); std::string GenStructureMembersForHeader(const Elements& elms); std::string GenStructure(const Structure& st); + std::string GenStructureBaseArgs(const Structure& st); std::string GenStructureBaseArgs(const Elements& elms); std::string GenStructureMemberInit(const Elements& elms); std::string GenStructureGetterSetter(const Structure& st); diff --git a/idlc/gen/version2/cpp_generator_base_cb.hh b/idlc/gen/version2/cpp_generator_base_cb.hh index 9cef83c..aaeda07 100644 --- a/idlc/gen/version2/cpp_generator_base_cb.hh +++ b/idlc/gen/version2/cpp_generator_base_cb.hh @@ -32,14 +32,17 @@ R"__cpp_cb( constexpr const char CB_BODY_HEADER[] = R"__cpp_cb( +#include #include #include #include #include #include #include +#include #include #include +#include #include #include @@ -69,6 +72,7 @@ R"__cpp_cb( #include #include #include +#include )__cpp_cb"; /** @@ -1010,6 +1014,9 @@ R"__cpp_cb( .Share(port_); )__cpp_cb"; +/** + * The parameter name. + */ constexpr const char CB_PRIVATE_SHARING_ARRAY[] = R"__cpp_cb( { @@ -1021,6 +1028,12 @@ R"__cpp_cb( } )__cpp_cb"; +constexpr const char CB_EXPORT_API[] = +R"__cpp_cb( +#undef EXPORT_API +#define EXPORT_API extern "C" __attribute__ ((visibility("default"))) +)__cpp_cb"; + } // namespace version2 } // namespace tidl diff --git a/idlc/gen/version2/cpp_proxy_body_generator.cc b/idlc/gen/version2/cpp_proxy_body_generator.cc index c8e8947..8b1e29d 100644 --- a/idlc/gen/version2/cpp_proxy_body_generator.cc +++ b/idlc/gen/version2/cpp_proxy_body_generator.cc @@ -16,6 +16,8 @@ #include "idlc/gen/version2/cpp_proxy_body_generator.hh" +#include + #include #include "idlc/gen/version2/cpp_generator_base_cb.hh" @@ -24,8 +26,9 @@ namespace tidl { namespace version2 { -CppProxyBodyGenerator::CppProxyBodyGenerator(std::shared_ptr doc) - : CppGeneratorBase(std::move(doc)) {} +CppProxyBodyGenerator::CppProxyBodyGenerator(std::shared_ptr doc, + std::shared_ptr options) + : CppGeneratorBase(std::move(doc)), options_(std::move(options)) {} void CppProxyBodyGenerator::OnInitGen(std::ofstream& stream) { GenVersion(stream); @@ -34,7 +37,10 @@ void CppProxyBodyGenerator::OnInitGen(std::ofstream& stream) { GenLogTag(stream, "RPC_PORT_PROXY"); GenLogDefinition(stream); GenVersionDefinition(stream); + GenExportAPI(stream); + GenLemAnonymousNamespace(stream); GenNamespace(stream); + GenLemAPI(stream); } void CppProxyBodyGenerator::OnFiniGen(std::ofstream& stream) {} @@ -55,13 +61,46 @@ void CppProxyBodyGenerator::GenIncludeProxyBodyHeader(std::ofstream& stream) { void CppProxyBodyGenerator::GenNamespace(std::ofstream& stream) { ReplaceAll(CB_NAMESPACE_PROXY) .ChangeToLower("", GetFileNamespace()) - .Change("", GenStructures()) + .Change("", GenLemBaseWithStructures()) .Change("", GenBaseImpl()) .Change("", GenInterfaces()) .Transform([&](std::string str) { return SmartIndent(str); }) .Out(stream); } +void CppProxyBodyGenerator::GenLemAnonymousNamespace(std::ofstream& stream) { + stream << SmartIndent(CB_LEM_ANONYMOUS_NAMESPACE); +} + +void CppProxyBodyGenerator::GenLemAPI(std::ofstream& stream) { + std::string input = basename(const_cast(options_->GetInput().c_str())); + input = input.substr(0, input.find_last_of(".")); + std::string code = NLine(1); + for (const auto& block : GetDocument().GetBlocks()) { + if (block->GetType() != Block::TYPE_INTERFACE) + continue; + + auto& iface = static_cast(*block); + code += ReplaceAll(CB_LEM_API) + .Change("", iface.GetID()) + .ChangeToLower("", GetFileNamespace()) + .ChangeToLower("", input); + code += NLine(1); + } + + stream << SmartIndent(code); +} + +std::string CppProxyBodyGenerator::GenLemBaseWithStructures() { + std::string input = basename(const_cast(options_->GetInput().c_str())); + input = input.substr(0, input.find_last_of(".")); + std::string code; + code += ReplaceAll(CB_LEM_BASE).ChangeToLower("", input); + code += NLine(1); + code += GenStructures(); + return code; +} + std::string CppProxyBodyGenerator::GenBaseImpl() { std::string code = GenRemoteException(); code += GenUnitMap(); @@ -93,16 +132,13 @@ std::string CppProxyBodyGenerator::GenInterface(const Interface& iface) { std::string CppProxyBodyGenerator::GenInterfaceCallbacks( const Interface& iface) { std::string code; + code += ReplaceAll(CB_INTERFACE_CALKBACBASE_BASE) + .Change("", iface.GetID()); + code += NLine(1); for (const auto& decl : iface.GetDeclarations()) { if (decl->GetMethodType() != Declaration::MethodType::DELEGATE) continue; - if (code.empty()) { - code += ReplaceAll(CB_INTERFACE_CALKBACBASE_BASE) - .Change("", iface.GetID()); - code += NLine(1); - } - code += ReplaceAll(CB_INTERFACE_CALLBACK) .Change("", iface.GetID()) .Change("", decl->GetID()) diff --git a/idlc/gen/version2/cpp_proxy_body_generator.hh b/idlc/gen/version2/cpp_proxy_body_generator.hh index b9384bd..d4c2099 100644 --- a/idlc/gen/version2/cpp_proxy_body_generator.hh +++ b/idlc/gen/version2/cpp_proxy_body_generator.hh @@ -21,13 +21,15 @@ #include #include "idlc/gen/version2/cpp_generator_base.hh" +#include "idlc/options.h" namespace tidl { namespace version2 { class CppProxyBodyGenerator : public CppGeneratorBase { public: - explicit CppProxyBodyGenerator(std::shared_ptr doc); + explicit CppProxyBodyGenerator(std::shared_ptr doc, + std::shared_ptr options); virtual ~CppProxyBodyGenerator() = default; void OnInitGen(std::ofstream& stream) override; @@ -36,6 +38,9 @@ class CppProxyBodyGenerator : public CppGeneratorBase { private: void GenIncludeProxyBodyHeader(std::ofstream& stream); void GenNamespace(std::ofstream& stream); + void GenLemAnonymousNamespace(std::ofstream& stream); + void GenLemAPI(std::ofstream& stream); + std::string GenLemBaseWithStructures(); std::string GenBaseImpl(); std::string GenInterfaces(); std::string GenInterface(const Interface& iface); @@ -46,6 +51,9 @@ class CppProxyBodyGenerator : public CppGeneratorBase { const Declaration& decl); std::string GenInterfaceMethodSerialize(const Declaration& decl); std::string GenInterfaceMethodDeserialize(const Declaration& decl); + + private: + std::shared_ptr options_; }; } // namespace version2 diff --git a/idlc/gen/version2/cpp_proxy_body_generator_cb.hh b/idlc/gen/version2/cpp_proxy_body_generator_cb.hh index 55235f7..6074dbf 100644 --- a/idlc/gen/version2/cpp_proxy_body_generator_cb.hh +++ b/idlc/gen/version2/cpp_proxy_body_generator_cb.hh @@ -127,6 +127,11 @@ R"__cpp_cb( rpc_port_proxy_add_disconnected_event_cb(proxy_, OnDisconnectedCb, this); rpc_port_proxy_add_rejected_event_cb(proxy_, OnRejectedCb, this); rpc_port_proxy_add_received_event_cb(proxy_, OnReceivedCb, this); + + if (GetAppId() == target_appid_) { + local_execution_ = std::make_unique("", this); + local_execution_->LoadSymbols(); + } } ::~() { @@ -136,6 +141,11 @@ R"__cpp_cb( } void ::Connect(bool sync) { + if (local_execution_.get() != nullptr && local_execution_->LoadSymbols()) { + if (local_execution_->Connect()) + return; + } + int ret; if (sync) ret = rpc_port_proxy_connect_sync(proxy_, target_appid_.c_str(), ""); @@ -159,6 +169,11 @@ void ::Connect(bool sync) { } void ::Disconnect() { + if (local_execution_.get() != nullptr && local_execution_->IsConnected()) { + local_execution_->Disconnect(); + return; + } + int ret = rpc_port_disconnect(port_); if (ret != RPC_PORT_ERROR_NONE) { _E("Failed to disconnect from . error(%d)", ret); @@ -180,6 +195,20 @@ void ::DisposeCallback(const std::string& tag) { +void ::OnLocalConnected() { + listener_->OnConnected(); +} + +void ::OnLocalDisconnected() { + listener_->OnDisconnected(); +} + +void ::OnLocalReceived(rpc_port_parcel_h parcel) { + UnitMap map; + map.Deserialize(parcel); + ProcessReceivedEvent(map); +} + void ::ProcessReceivedEvent(const UnitMap& unit_map) { CallbackBase callback; unit_map.Read("delegate", callback); @@ -284,7 +313,7 @@ void ::OnReceivedCb(const char* endpoint, const char* port_name, void* constexpr const char CB_INTERFACE_METHOD_ASYNC_BASE[] = R"__cpp_cb( void ::() { - if (port_ == nullptr) { + if (port_ == nullptr && (local_execution_.get() == nullptr || !local_execution_->IsConnected())) { _E("Not connected"); throw NotConnectedSocketException(); } @@ -302,7 +331,12 @@ void ::() { map_.Serialize(parcel_);; std::lock_guard lock(mutex_); - int ret_ = rpc_port_parcel_send(parcel_, port_); + int ret_; + if (local_execution_.get() != nullptr && local_execution_->IsConnected()) + ret_ = local_execution_->Send(parcel_, nullptr); + else + ret_ = rpc_port_parcel_send(parcel_, port_); + rpc_port_parcel_destroy(parcel_); if (ret_ != RPC_PORT_ERROR_NONE) { _E("Failed to send parcel. error(%d)", ret_); @@ -323,7 +357,7 @@ void ::() { constexpr const char CB_INTERFACE_METHOD_BASE[] = R"__cpp_cb( ::() { - if (port_ == nullptr) { + if (port_ == nullptr && (local_execution_.get() == nullptr || !local_execution_->IsConnected())) { _E("Not connected"); throw NotConnectedSocketException(); } @@ -344,7 +378,13 @@ R"__cpp_cb( map_.Serialize(parcel_); std::lock_guard lock(mutex_); - int ret_ = rpc_port_parcel_send(parcel_, port_); + int ret_; + rpc_port_parcel_h result_parcel_ = nullptr; + if (local_execution_.get() != nullptr && local_execution_->IsConnected()) + ret_ = local_execution_->Send(parcel_, &result_parcel_); + else + ret_ = rpc_port_parcel_send(parcel_, port_); + rpc_port_parcel_destroy(parcel_); if (ret_ != RPC_PORT_ERROR_NONE) { _E("Failed to send parcel. error(%d)", ret_); @@ -353,7 +393,13 @@ R"__cpp_cb( result_; UnitMap received_map_; - ConsumeCommand(port_, seq_num_, received_map_); + if (local_execution_.get() != nullptr && local_execution_->IsConnected()) { + received_map_.Deserialize(result_parcel_); + rpc_port_parcel_destroy(result_parcel_); + } else { + ConsumeCommand(port_, seq_num_, received_map_); + } + if (received_map_.GetSize() == 0) { _E("received map size is zero"); } @@ -395,6 +441,253 @@ R"__cpp_cb( received_map_.Read("", ); )__cpp_cb"; +constexpr const char CB_LEM_ANONYMOUS_NAMESPACE[] = +R"__cpp_cb( +namespace { + +std::atomic seq_ { 0 }; +std::string appid_; + +const std::string& GetAppId() { + if (getuid() < 5000) + return appid_; + + if (appid_.empty()) { + char* id = nullptr; + app_get_id(&id); + if (id == nullptr) { + _E("Failed to get app id"); + return appid_; + } + + appid_ = std::string(id); + free(id); + } + + return appid_; +} + +rpc_port_parcel_h Clone(rpc_port_parcel_h parcel) { + void* raw = nullptr; + unsigned int size = 0; + if (rpc_port_parcel_get_raw(parcel, &raw, &size) != RPC_PORT_ERROR_NONE) { + _E("Failed to get raw"); + return nullptr; + } + + rpc_port_parcel_h handle = nullptr; + rpc_port_parcel_create_from_raw(&handle, raw, size); + return handle; +} + +} // namespace +)__cpp_cb"; + +/** + * The input file name. + */ +constexpr const char CB_LEM_BASE[] = +R"__cpp_cb( +LocalExecution::LocalExecution(std::string port_name, LocalExecution::IEvent* listener) : port_name_(std::move(port_name)), listener_(listener) { + instance_ = GetAppId() + "::" + std::to_string(seq_++); +} + +LocalExecution::~LocalExecution() { + while (!result_queue_.empty()) { + auto parcel = result_queue_.front(); + result_queue_.pop(); + rpc_port_parcel_destroy(parcel); + } + + while (!request_queue_.empty()) { + auto parcel = request_queue_.front(); + request_queue_.pop(); + rpc_port_parcel_destroy(parcel); + } +} + +bool LocalExecution::Connect() { + if (connect_func_) { + if (connect_func_(this, GetAppId().c_str(), instance_.c_str()) != RPC_PORT_ERROR_NONE) + return false; + } + + return true; +} + +void LocalExecution::Disconnect() { + if (disconnect_func_) + disconnect_func_(this, GetAppId().c_str(), instance_.c_str()); +} + +int LocalExecution::Send(rpc_port_parcel_h request, rpc_port_parcel_h* result) { + if (send_func_) { + int ret = send_func_(this, request); + if (result != nullptr) { + int count = 0; + while (ResultQueueEmpty() && count++ < 100) + usleep(100 * 1000); + + if (ResultQueueEmpty()) { + _E("Failed to get result from server"); + return RPC_PORT_ERROR_IO_ERROR; + } + + *result = ResultQueuePop(); + } + + return ret; + } + + return RPC_PORT_ERROR_NONE; +} + +void LocalExecution::OnConnected() { + connected_ = true; + if (listener_ != nullptr) + listener_->OnLocalConnected(); +} + +void LocalExecution::OnDisconnected() { + connected_ = false; + if (listener_ != nullptr) + listener_->OnLocalDisconnected(); +} + +void LocalExecution::OnReceived(rpc_port_parcel_h parcel) { + if (listener_ != nullptr) + listener_->OnLocalReceived(parcel); +} + +bool LocalExecution::LoadSymbols() { + if (loaded_) + return true; + + if (connect_func_ == nullptr) { + std::string symbol = "rpc_port_stub__lem_" + port_name_ + "_connect"; + connect_func_ = reinterpret_cast(dlsym(RTLD_DEFAULT, symbol.c_str())); + if (connect_func_ == nullptr) { + _E("Failed to find symbol(%s)", symbol.c_str()); + return false; + } + } + + if (disconnect_func_ == nullptr) { + std::string symbol = "rpc_port_stub__lem_" + port_name_ + "_disconnect"; + disconnect_func_ = reinterpret_cast(dlsym(RTLD_DEFAULT, symbol.c_str())); + if (disconnect_func_ == nullptr) { + _E("Failed to find symbol(%s)", symbol.c_str()); + return false; + } + } + + if (send_func_ == nullptr) { + std::string symbol = "rpc_port_stub__lem_" + port_name_ + "_send"; + send_func_ = reinterpret_cast(dlsym(RTLD_DEFAULT, symbol.c_str())); + if (send_func_ == nullptr) { + _E("Failed to find symbol(%s)", symbol.c_str()); + return false; + } + } + + loaded_ = true; + return true; +} + +void LocalExecution::ResultQueuePush(rpc_port_parcel_h parcel) { + std::lock_guard lock(mutex_); + result_queue_.push(parcel); +} + +rpc_port_parcel_h LocalExecution::ResultQueuePop() { + std::lock_guard lock(mutex_); + auto parcel = result_queue_.front(); + result_queue_.pop(); + return parcel; +} + +bool LocalExecution::ResultQueueEmpty() const { + std::lock_guard lock(mutex_); + return result_queue_.empty(); +} + +void LocalExecution::RequestQueuePush(rpc_port_parcel_h parcel) { + std::lock_guard lock(mutex_); + request_queue_.push(parcel); +} + +rpc_port_parcel_h LocalExecution::RequestQueuePop() { + std::lock_guard lock(mutex_); + auto parcel = request_queue_.front(); + request_queue_.pop(); + return parcel; +} +)__cpp_cb"; + +/** + * The interface name. + * The input file name. + * The file namespace. + */ +constexpr const char CB_LEM_API[] = +R"__cpp_cb( +EXPORT_API int rpc_port_proxy__lem__connect(void* h) { + auto* handle = static_cast::LocalExecution*>(h); + auto* ptr = new std::weak_ptr::LocalExecution>(handle->shared_from_this()); + g_idle_add([](gpointer user_data) { + auto* wp = static_cast::LocalExecution>*>(user_data); + auto p = wp->lock(); + if (p != nullptr) + p->OnConnected(); + + delete wp; + return G_SOURCE_REMOVE; + }, ptr); + return RPC_PORT_ERROR_NONE; +} + +EXPORT_API int rpc_port_proxy__lem__disconnect(void* h) { + auto* handle = static_cast::LocalExecution*>(h); + auto* ptr = new std::weak_ptr::LocalExecution>(handle->shared_from_this()); + g_idle_add([](gpointer user_data) { + auto* wp = static_cast::LocalExecution>*>(user_data); + auto p = wp->lock(); + if (p != nullptr) + p->OnDisconnected(); + + delete wp; + return G_SOURCE_REMOVE; + }, ptr); + return RPC_PORT_ERROR_NONE; +} + +EXPORT_API int rpc_port_proxy__lem__invoke_callback(void* h, rpc_port_parcel_h parcel) { + auto* handle = static_cast::LocalExecution*>(h); + auto* ptr = new std::weak_ptr::LocalExecution>(handle->shared_from_this()); + rpc_port_parcel_h cloned_parcel = ::Clone(parcel); + handle->RequestQueuePush(cloned_parcel); + g_idle_add([](gpointer user_data) { + auto* wp = static_cast::LocalExecution>*>(user_data); + auto p = wp->lock(); + if (p != nullptr) { + rpc_port_parcel_h request = p->RequestQueuePop(); + p->OnReceived(request); + rpc_port_parcel_destroy(request); + } + + delete wp; + return G_SOURCE_REMOVE; + }, ptr); + return RPC_PORT_ERROR_NONE; +} + +EXPORT_API int rpc_port_proxy__lem__send_result(void* h, rpc_port_parcel_h parcel) { + auto* handle = static_cast::LocalExecution*>(h); + rpc_port_parcel_h cloned_parcel = ::Clone(parcel); + handle->ResultQueuePush(cloned_parcel); + return RPC_PORT_ERROR_NONE; +} +)__cpp_cb"; } // namespace version2 } // namespace tidl diff --git a/idlc/gen/version2/cpp_proxy_header_generator.cc b/idlc/gen/version2/cpp_proxy_header_generator.cc index b715871..ce81dac 100644 --- a/idlc/gen/version2/cpp_proxy_header_generator.cc +++ b/idlc/gen/version2/cpp_proxy_header_generator.cc @@ -24,8 +24,9 @@ namespace tidl { namespace version2 { -CppProxyHeaderGenerator::CppProxyHeaderGenerator(std::shared_ptr doc) - : CppGeneratorBase(std::move(doc)) {} +CppProxyHeaderGenerator::CppProxyHeaderGenerator( + std::shared_ptr doc, std::shared_ptr options) + : CppGeneratorBase(std::move(doc)), options_(std::move(options)) {} void CppProxyHeaderGenerator::OnInitGen(std::ofstream& stream) { GenVersion(stream); @@ -38,13 +39,20 @@ void CppProxyHeaderGenerator::OnFiniGen(std::ofstream& stream) {} void CppProxyHeaderGenerator::GenNamespace(std::ofstream& stream) { ReplaceAll(CB_NAMESPACE_PROXY) .ChangeToLower("", GetFileNamespace()) - .Change("", GenStructuresForHeader()) + .Change("", GenLemBaseWithStructures()) .Change("", GenBaseImpl()) .Change("", GenInterfaces()) .Transform([&](std::string str) { return SmartIndent(str); }) .Out(stream); } +std::string CppProxyHeaderGenerator::GenLemBaseWithStructures() { + std::string code = CB_LEM_BASE; + code += NLine(1); + code += GenStructuresForHeader(); + return code; +} + std::string CppProxyHeaderGenerator::GenBaseImpl() { std::string code = GenExceptions(); code += GenRemoteExceptionForHeader(); @@ -78,16 +86,13 @@ std::string CppProxyHeaderGenerator::GenInterface(const Interface& iface) { std::string CppProxyHeaderGenerator::GenInterfaceCallbacks( const Interface& iface) { std::string code; + code += ReplaceAll(CB_INTERFACE_CALLBACK_BASE) + .Change("", iface.GetID()); + code += NLine(1); for (const auto& decl : iface.GetDeclarations()) { if (decl->GetMethodType() != Declaration::MethodType::DELEGATE) continue; - if (code.empty()) { - code += ReplaceAll(CB_INTERFACE_CALLBACK_BASE) - .Change("", iface.GetID()); - code += NLine(1); - } - code += ReplaceAll(CB_INTERFACE_CALLBACK) .Change("", decl->GetID()) .Change("", GetParameters(decl->GetParameters())); diff --git a/idlc/gen/version2/cpp_proxy_header_generator.hh b/idlc/gen/version2/cpp_proxy_header_generator.hh index 72ba768..13b147e 100644 --- a/idlc/gen/version2/cpp_proxy_header_generator.hh +++ b/idlc/gen/version2/cpp_proxy_header_generator.hh @@ -21,13 +21,15 @@ #include #include "idlc/gen/version2/cpp_generator_base.hh" +#include "idlc/options.h" namespace tidl { namespace version2 { class CppProxyHeaderGenerator : public CppGeneratorBase { public: - explicit CppProxyHeaderGenerator(std::shared_ptr doc); + explicit CppProxyHeaderGenerator(std::shared_ptr doc, + std::shared_ptr options); virtual ~CppProxyHeaderGenerator() = default; void OnInitGen(std::ofstream& stream) override; @@ -35,11 +37,15 @@ class CppProxyHeaderGenerator : public CppGeneratorBase { private: void GenNamespace(std::ofstream& stream); + std::string GenLemBaseWithStructures(); std::string GenBaseImpl(); std::string GenInterfaces(); std::string GenInterface(const Interface& iface); std::string GenInterfaceCallbacks(const Interface& iface); std::string GenInterfaceMethods(const Interface& iface); + + private: + std::shared_ptr options_; }; } // namespace version2 diff --git a/idlc/gen/version2/cpp_proxy_header_generator_cb.hh b/idlc/gen/version2/cpp_proxy_header_generator_cb.hh index 6c3953f..c02b013 100644 --- a/idlc/gen/version2/cpp_proxy_header_generator_cb.hh +++ b/idlc/gen/version2/cpp_proxy_header_generator_cb.hh @@ -77,7 +77,7 @@ class : public CallbackBase { */ constexpr const char CB_INTERFACE_BASE[] = R"__cpp_cb( -class { +class : public LocalExecution::IEvent { public: @@ -155,6 +155,10 @@ class { static void OnRejectedCb(const char* endpoint, const char* port_name, void* user_data); static void OnReceivedCb(const char* endpoint, const char* port_name, void* user_data); + void OnLocalConnected() override; + void OnLocalDisconnected() override; + void OnLocalReceived(rpc_port_parcel_h parcel) override; + private: rpc_port_h port_ = nullptr; rpc_port_h callback_port_ = nullptr; @@ -163,6 +167,7 @@ class { std::recursive_mutex mutex_; std::list> delegate_list_; std::string target_appid_; + std::shared_ptr local_execution_; }; )__cpp_cb"; @@ -176,6 +181,61 @@ R"__cpp_cb( (); )__cpp_cb"; +constexpr const char CB_LEM_BASE[] = +R"__cpp_cb( +class LocalExecution : public std::enable_shared_from_this { + public: + class IEvent { + public: + virtual ~IEvent() = default; + virtual void OnLocalConnected() = 0; + virtual void OnLocalDisconnected() = 0; + virtual void OnLocalReceived(rpc_port_parcel_h parcel) = 0; + }; + + LocalExecution(std::string port_name, IEvent* listener); + virtual ~LocalExecution(); + + bool Connect(); + void Disconnect(); + int Send(rpc_port_parcel_h request, rpc_port_parcel_h* result); + + bool IsConnected() const { return connected_; } + + void OnConnected(); + void OnDisconnected(); + void OnReceived(rpc_port_parcel_h parcel); + + bool LoadSymbols(); + + void ResultQueuePush(rpc_port_parcel_h parcel); + rpc_port_parcel_h ResultQueuePop(); + bool ResultQueueEmpty() const; + + void RequestQueuePush(rpc_port_parcel_h parcel); + rpc_port_parcel_h RequestQueuePop(); + + + private: + using StubConnectFunc = int (*)(void*, const char*, const char*); + using StubDisconnectFunc = void (*)(void*, const char*, const char*); + using StubSendFunc = int (*)(void*, rpc_port_parcel_h); + + private: + std::string port_name_; + IEvent* listener_; + std::string instance_; + bool connected_ = false; + bool loaded_ = false; + StubConnectFunc connect_func_ = nullptr; + StubDisconnectFunc disconnect_func_ = nullptr; + StubSendFunc send_func_ = nullptr; + std::queue result_queue_; + std::queue request_queue_; + mutable std::recursive_mutex mutex_; +}; +)__cpp_cb"; + } // namespace version2 } // namespace tidl diff --git a/idlc/gen/version2/cpp_stub_body_generator.cc b/idlc/gen/version2/cpp_stub_body_generator.cc index 78de08d..255fbb8 100644 --- a/idlc/gen/version2/cpp_stub_body_generator.cc +++ b/idlc/gen/version2/cpp_stub_body_generator.cc @@ -16,6 +16,8 @@ #include "idlc/gen/version2/cpp_stub_body_generator.hh" +#include + #include #include "idlc/gen/version2/cpp_generator_base_cb.hh" @@ -35,7 +37,10 @@ void CppStubBodyGenerator::OnInitGen(std::ofstream& stream) { GenLogTag(stream, "RPC_PORT_STUB"); GenLogDefinition(stream); GenVersionDefinition(stream); + GenExportAPI(stream); + GenLemAnonymousNamespace(stream); GenNamespace(stream); + GenLemAPI(stream); } void CppStubBodyGenerator::OnFiniGen(std::ofstream& stream) {} @@ -56,13 +61,63 @@ void CppStubBodyGenerator::GenIncludeStubBodyHeader(std::ofstream& stream) { void CppStubBodyGenerator::GenNamespace(std::ofstream& stream) { ReplaceAll(CB_NAMESPACE_STUB) .ChangeToLower("", GetFileNamespace()) - .Change("", GenStructures()) + .Change("", GenLemBaseWithStructures()) .Change("", GenBaseImpl()) .Change("", GenInterfaces()) .Transform([&](std::string str) { return SmartIndent(str); }) .Out(stream); } +void CppStubBodyGenerator::GenLemAnonymousNamespace(std::ofstream& stream) { + ReplaceAll(CB_LEM_ANONYMOUS_NAMESPACE) + .Change("", GenLemContext()) + .Transform([&](std::string code) { return SmartIndent(code); }) + .Out(stream); +} + +std::string CppStubBodyGenerator::GenLemContext() { + std::string code; + for (const auto& block : GetDocument().GetBlocks()) { + if (block->GetType() != Block::TYPE_INTERFACE) + continue; + + auto& iface = static_cast(*block); + code += ReplaceAll(CB_LEM_CONTEXT) + .Change("", iface.GetID()) + .ChangeToLower("", GetFileNamespace()); + } + + return RemoveLine(code); +} + +void CppStubBodyGenerator::GenLemAPI(std::ofstream& stream) { + std::string input = basename(const_cast(options_->GetInput().c_str())); + input = input.substr(0, input.find_last_of(".")); + std::string code = NLine(1); + for (const auto& block : GetDocument().GetBlocks()) { + if (block->GetType() != Block::TYPE_INTERFACE) + continue; + + auto& iface = static_cast(*block); + code += ReplaceAll(CB_LEM_API) + .Change("", iface.GetID()) + .ChangeToLower("", input); + code += NLine(1); + } + + stream << SmartIndent(code); +} + +std::string CppStubBodyGenerator::GenLemBaseWithStructures() { + std::string input = basename(const_cast(options_->GetInput().c_str())); + input = input.substr(0, input.find_last_of(".")); + std::string code; + code += ReplaceAll(CB_LEM_BASE).ChangeToLower("", input); + code += NLine(1); + code += GenStructures(); + return code; +} + std::string CppStubBodyGenerator::GenBaseImpl() { std::string code = GenRemoteException(); code += GenUnitMap(); @@ -102,16 +157,13 @@ std::string CppStubBodyGenerator::GenInterface(const Interface& iface) { std::string CppStubBodyGenerator::GenInterfaceCallbacks( const Interface& iface) { std::string code; + code += ReplaceAll(CB_INTERFACE_CALKBACBASE_BASE) + .Change("", iface.GetID()); + code += NLine(1); for (const auto& decl : iface.GetDeclarations()) { if (decl->GetMethodType() != Declaration::MethodType::DELEGATE) continue; - if (code.empty()) { - code += ReplaceAll(CB_INTERFACE_CALKBACBASE_BASE) - .Change("", iface.GetID()); - code += NLine(1); - } - code += ReplaceAll(CB_INTERFACE_CALLBACK) .Change("", iface.GetID()) .Change("", decl->GetID()) diff --git a/idlc/gen/version2/cpp_stub_body_generator.hh b/idlc/gen/version2/cpp_stub_body_generator.hh index ba3a54e..90a7353 100644 --- a/idlc/gen/version2/cpp_stub_body_generator.hh +++ b/idlc/gen/version2/cpp_stub_body_generator.hh @@ -37,7 +37,11 @@ class CppStubBodyGenerator : public CppGeneratorBase { private: void GenIncludeStubBodyHeader(std::ofstream& stream); + void GenLemAnonymousNamespace(std::ofstream& stream); + std::string GenLemContext(); + void GenLemAPI(std::ofstream& stream); void GenNamespace(std::ofstream& stream); + std::string GenLemBaseWithStructures(); std::string GenBaseImpl(); std::string GenInterfaces(); std::string GenInterface(const Interface& iface); diff --git a/idlc/gen/version2/cpp_stub_body_generator_cb.hh b/idlc/gen/version2/cpp_stub_body_generator_cb.hh index b0c375b..7571959 100644 --- a/idlc/gen/version2/cpp_stub_body_generator_cb.hh +++ b/idlc/gen/version2/cpp_stub_body_generator_cb.hh @@ -72,6 +72,14 @@ void ::CallbackBase::SetOnce(bool once) { std::string ::CallbackBase::GetTag() const { return std::to_string(id_) + "::" + std::to_string(seq_id_); } + +void ::CallbackBase::SetContext(void* context) { + context_ = context; +} + +void* ::CallbackBase::GetContext() const { + return context_; +} )__cpp_cb"; /** @@ -82,7 +90,7 @@ std::string ::CallbackBase::GetTag() const { constexpr const char CB_INTERFACE_CALLBACK[] = R"__cpp_cb( void ::::Invoke() { - if (callback_port_ == nullptr) + if (callback_port_ == nullptr && GetContext() == nullptr) throw NotConnectedSocketException(); if (service_.lock().get() == nullptr) @@ -100,7 +108,13 @@ void ::::Invoke() { rpc_port_parcel_create(&parcel_); unit_map_.Serialize(parcel_); - set_last_result(rpc_port_parcel_send(parcel_, callback_port_)); + if (GetContext() != nullptr) { + _context_->InvokeCallback(GetContext(), parcel_); + set_last_result(RPC_PORT_ERROR_NONE); + } else { + set_last_result(rpc_port_parcel_send(parcel_, callback_port_)); + } + rpc_port_parcel_destroy(parcel_); valid_ = false; } @@ -254,6 +268,14 @@ bool ::ServiceBase::CheckPrivileges(int method_id) { +void ::ServiceBase::SetContext(void* context) { + context_ = context; +} + +void* ::ServiceBase::GetContext() const { + return context_; +} + ::() { _W(" ctor"); int ret = rpc_port_stub_create(&stub_, ""); @@ -265,10 +287,13 @@ bool ::ServiceBase::CheckPrivileges(int method_id) { rpc_port_stub_add_connected_event_cb(stub_, OnConnectedCb, this); rpc_port_stub_add_disconnected_event_cb(stub_, OnDisconnectedCb, this); rpc_port_stub_add_received_event_cb(stub_, OnReceivedCb, this); + + _context_ = std::make_unique("", this); } ::~() { _W(" dtor"); + _context_.reset(); for (auto& service : services_) service->OnTerminate(); @@ -284,6 +309,8 @@ void ::Listen(std::shared_ptr<::ServiceBase::Factory> servic if (ret == RPC_PORT_ERROR_INVALID_PARAMETER || ret == RPC_PORT_ERROR_IO_ERROR) throw InvalidIOException(); } + + _context_->SetListening(true); } void ::OnConnectedCb(const char* sender, const char* instance, void* user_data) { @@ -348,6 +375,47 @@ int ::OnReceivedCb(const char* sender, const char* instance, rpc_port_ service->Dispatch(port, callback_port, parcel, service); return ret; } + +void ::OnLocalConnected(void* context, const std::string& sender, const std::string& instance) { + auto service = service_factory_->CreateService(sender, instance); + service->SetContext(context); + service->OnCreate(); + services_.emplace_back(std::move(service)); + _context_->Connect(context); +} + +void ::OnLocalDisconnected(void* context, const std::string& sender, const std::string& instance) { + auto iter = services_.begin(); + while (iter != services_.end()) { + if ((*iter)->GetInstance() == instance) { + (*iter)->OnTerminate(); + iter = services_.erase(iter); + break; + } + + iter++; + } + + _context_->Disconnect(context); +} + +void ::OnLocalReceived(void* context, rpc_port_parcel_h parcel) { + std::shared_ptr service; + for (auto& iter : services_) { + if (iter->GetContext() == context) { + service = iter; + break; + } + } + + if (service.get() == nullptr) { + _E("Failed to find context. context(%p)", context); + return; + } + + rpc_port_parcel_h p = Clone(parcel); + service->Dispatch(nullptr, nullptr, p, service); +} )__cpp_cb"; /** @@ -431,7 +499,10 @@ void ::ServiceBase::Dispatch(rpc_port_h port, rpc_port_h callb rpc_port_parcel_header_set_seq_num(header_, seq_num); map_.Serialize(parcel_); - rpc_port_parcel_send(parcel_, port); + if (GetContext() != nullptr) + _context_->SendResult(GetContext(), parcel_); + else + rpc_port_parcel_send(parcel_, port); rpc_port_parcel_destroy(parcel_); } )__cpp_cb"; @@ -461,6 +532,7 @@ R"__cpp_cb( constexpr const char CB_INTERFACE_SERVICE_BASE_PARAM_DELEGATE[] = R"__cpp_cb( (new (callback_port, std::weak_ptr(this->shared_from_this()))); +->SetContext(GetContext()); )__cpp_cb"; /** @@ -485,6 +557,163 @@ R"__cpp_cb( } )__cpp_cb"; +/** + * The context of the local execution of the interface. + */ +constexpr const char CB_LEM_ANONYMOUS_NAMESPACE[] = +R"__cpp_cb( +namespace { + +rpc_port_parcel_h Clone(rpc_port_parcel_h parcel) { + void* raw = nullptr; + unsigned int size = 0; + rpc_port_parcel_get_raw(parcel, &raw, &size); + + rpc_port_parcel_h handle = nullptr; + rpc_port_parcel_create_from_raw(&handle, raw, size); + return handle; +} + + + +} // namespace +)__cpp_cb"; + +/** + * The file namespace. + * The interface name. + */ +constexpr const char CB_LEM_CONTEXT[] = +R"__cpp_cb( +std::shared_ptr::LocalExecution> _context_; +)__cpp_cb"; + +/** + * The file namespace. + */ +constexpr const char CB_LEM_BASE[] = +R"__cpp_cb( +LocalExecution::LocalExecution(std::string port_name, LocalExecution::IEvent* listener) : port_name_(std::move(port_name)), listener_(listener) { + LoadSymbols(); +} + +void LocalExecution::Connect(void* context) { + if (connect_func_ != nullptr) + connect_func_(context); +} + +void LocalExecution::Disconnect(void* context) { + if (disconnect_func_ != nullptr) + disconnect_func_(context); +} + +void LocalExecution::SendResult(void* context, rpc_port_parcel_h parcel) { + if (send_result_func_ != nullptr) + send_result_func_(context, parcel); +} + +void LocalExecution::InvokeCallback(void* context, rpc_port_parcel_h parcel) { + if (invoke_callback_func_ != nullptr) + invoke_callback_func_(context, parcel); +} + +void LocalExecution::OnConnected(void* context, const std::string& sender, const std::string& instance) { + if (listener_ != nullptr) + listener_->OnLocalConnected(context, sender, instance); +} + +void LocalExecution::OnDisconnected(void* context, const std::string& sender, const std::string& instance) { + if (listener_ != nullptr) + listener_->OnLocalDisconnected(context, sender, instance); +} + +void LocalExecution::OnReceived(void* context, rpc_port_parcel_h parcel) { + if (listener_ != nullptr) + listener_->OnLocalReceived(context, parcel); +} + +bool LocalExecution::LoadSymbols() { + if (loaded_) + return true; + + std::string symbol = "rpc_port_proxy__lem_" + port_name_ + "_connect"; + connect_func_ = reinterpret_cast(dlsym(RTLD_DEFAULT, symbol.c_str())); + if (connect_func_ == nullptr) { + _E("Failed to find symbol"); + return false; + } + + symbol = "rpc_port_proxy__lem_" + port_name_ + "_disconnect"; + disconnect_func_ = reinterpret_cast(dlsym(RTLD_DEFAULT, symbol.c_str())); + if (disconnect_func_ == nullptr) { + _E("Failed to find symbol"); + return false; + } + + symbol = "rpc_port_proxy__lem_" + port_name_ + "_send_result"; + send_result_func_ = reinterpret_cast(dlsym(RTLD_DEFAULT, symbol.c_str())); + if (send_result_func_ == nullptr) { + _E("Failed to find symbol"); + return false; + } + + symbol = "rpc_port_proxy__lem_" + port_name_ + "_invoke_callback"; + invoke_callback_func_ = reinterpret_cast(dlsym(RTLD_DEFAULT, symbol.c_str())); + if (invoke_callback_func_ == nullptr) { + _E("Failed to find symbol"); + return false; + } + + loaded_ = true; + return true; +} + +void LocalExecution::SetListening(bool listening) { + listening_ = listening; +} + +bool LocalExecution::IsListening() const { + return listening_; +} +)__cpp_cb"; + +/** + * The input file name. + * The interface name. + */ +constexpr const char CB_LEM_API[] = +R"__cpp_cb( +EXPORT_API int rpc_port_stub__lem__connect(void* context, const char* sender, const char* instance) { + if (_context_.get() == nullptr || !_context_->IsListening()) { + _E("Server is not ready"); + return RPC_PORT_ERROR_IO_ERROR; + } + + _context_->OnConnected(context, sender, instance); + return RPC_PORT_ERROR_NONE; +} + +EXPORT_API int rpc_port_stub__lem__disconnect(void* context, const char* sender, const char* instance) { + if (_context_.get() == nullptr || !_context_->IsListening()) { + _E("Server is not ready"); + return RPC_PORT_ERROR_IO_ERROR; + } + + _context_->OnDisconnected(context, sender, instance); + return RPC_PORT_ERROR_NONE; +} + +EXPORT_API int rpc_port_stub__lem__send(void* context, rpc_port_parcel_h parcel) { + if (_context_.get() == nullptr || !_context_->IsListening()) { + _E("Server is not ready"); + return RPC_PORT_ERROR_IO_ERROR; + } + + _context_->OnReceived(context, parcel); + return RPC_PORT_ERROR_NONE; +} +)__cpp_cb"; + } // namespace version2 } // namespace tidl diff --git a/idlc/gen/version2/cpp_stub_header_generator.cc b/idlc/gen/version2/cpp_stub_header_generator.cc index 4ba607a..9453b42 100644 --- a/idlc/gen/version2/cpp_stub_header_generator.cc +++ b/idlc/gen/version2/cpp_stub_header_generator.cc @@ -39,13 +39,20 @@ void CppStubHeaderGenerator::OnFiniGen(std::ofstream& stream) {} void CppStubHeaderGenerator::GenNamespace(std::ofstream& stream) { ReplaceAll(CB_NAMESPACE_STUB) .ChangeToLower("", GetFileNamespace()) - .Change("", GenStructuresForHeader()) + .Change("", GenLemBaseWithStructures()) .Change("", GenBaseImpl()) .Change("", GenInterfaces()) .Transform([&](std::string str) { return SmartIndent(str); }) .Out(stream); } +std::string CppStubHeaderGenerator::GenLemBaseWithStructures() { + std::string code = CB_LEM_BASE; + code += NLine(1); + code += GenStructuresForHeader(); + return code; +} + std::string CppStubHeaderGenerator::GenBaseImpl() { std::string code = GenExceptions(); code += GenRemoteExceptionForHeader(); @@ -87,16 +94,13 @@ std::string CppStubHeaderGenerator::GenInterface(const Interface& iface) { std::string CppStubHeaderGenerator::GenInterfaceCallbacks( const Interface& iface) { std::string code; + code += ReplaceAll(CB_INTERFACE_CALLBACK_BASE) + .Change("", iface.GetID()); + code += NLine(1); for (const auto& decl : iface.GetDeclarations()) { if (decl->GetMethodType() != Declaration::MethodType::DELEGATE) continue; - if (code.empty()) { - code += ReplaceAll(CB_INTERFACE_CALLBACK_BASE) - .Change("", iface.GetID()); - code += NLine(1); - } - code += ReplaceAll(CB_INTERFACE_CALLBACK) .Change("", decl->GetID()) .Change("", GetParameters(decl->GetParameters())); diff --git a/idlc/gen/version2/cpp_stub_header_generator.hh b/idlc/gen/version2/cpp_stub_header_generator.hh index 46935b1..e124fc7 100644 --- a/idlc/gen/version2/cpp_stub_header_generator.hh +++ b/idlc/gen/version2/cpp_stub_header_generator.hh @@ -37,6 +37,7 @@ class CppStubHeaderGenerator : public CppGeneratorBase { private: void GenNamespace(std::ofstream& stream); + std::string GenLemBaseWithStructures(); std::string GenBaseImpl(); std::string GenInterfaces(); std::string GenInterface(const Interface& iface); diff --git a/idlc/gen/version2/cpp_stub_header_generator_cb.hh b/idlc/gen/version2/cpp_stub_header_generator_cb.hh index ee4b63b..51db84f 100644 --- a/idlc/gen/version2/cpp_stub_header_generator_cb.hh +++ b/idlc/gen/version2/cpp_stub_header_generator_cb.hh @@ -183,11 +183,15 @@ class CallbackBase { std::string GetTag() const; + void SetContext(void* context); + void* GetContext() const; + private: static std::atomic seq_num_; int id_ = 0; int seq_id_ = 0; bool once_ = false; + void* context_ = nullptr; }; )__cpp_cb"; @@ -240,7 +244,7 @@ class PendingJob : public Job, Job::IEvent { */ constexpr const char CB_INTERFACE_BASE[] = R"__cpp_cb( -class { +class : public LocalExecution::IEvent { public: @@ -298,6 +302,8 @@ class { /// virtual void OnTerminate() = 0; + void SetContext(void* context); + void* GetContext() const; void Dispatch(rpc_port_h port, rpc_port_h callback_port, rpc_port_parcel_h parcel, std::shared_ptr service); void Dispatch(rpc_port_h port, rpc_port_h callback_port, rpc_port_parcel_h parcel); @@ -324,6 +330,7 @@ class { std::unordered_map dispatch_funcs_; std::unordered_map> privilege_map_; std::unordered_set privileges_; + void* context_ = nullptr; }; (); @@ -354,6 +361,10 @@ class { static void OnDisconnectedCb(const char* sender, const char* instance, void* user_data); static int OnReceivedCb(const char* sender, const char* instance, rpc_port_h port, void* user_data); + void OnLocalConnected(void* context, const std::string& sender, const std::string& instance) override; + void OnLocalDisconnected(void* context, const std::string& sender, const std::string& instance) override; + void OnLocalReceived(void* context, rpc_port_parcel_h parcel) override; + private: rpc_port_stub_h stub_ = nullptr; std::shared_ptr service_factory_; @@ -384,6 +395,53 @@ R"__cpp_cb( std::unique_ptr active_object_; )__cpp_cb"; +constexpr const char CB_LEM_BASE[] = +R"__cpp_cb( +class LocalExecution { + public: + class IEvent { + public: + virtual ~IEvent() = default; + virtual void OnLocalConnected(void* context, const std::string& sender, const std::string& instance) = 0; + virtual void OnLocalDisconnected(void* context, const std::string& sender, const std::string& instance) = 0; + virtual void OnLocalReceived(void* context, rpc_port_parcel_h parcel) = 0; + }; + + LocalExecution(std::string port_name, IEvent* listener); + virtual ~LocalExecution() = default; + + void Connect(void* context); + void Disconnect(void* context); + void SendResult(void* context, rpc_port_parcel_h parcel); + void InvokeCallback(void* context, rpc_port_parcel_h parcel); + + void OnConnected(void* context, const std::string& sender, const std::string& instance); + void OnDisconnected(void* context, const std::string& sender, const std::string& instance); + void OnReceived(void* context, rpc_port_parcel_h parcel); + + void SetListening(bool listening); + bool IsListening() const; + + bool LoadSymbols(); + + private: + using ProxyConnectFunc = int (*)(void*); + using ProxyDisconnectFunc = int (*)(void*); + using ProxySendResultFunc = int (*)(void*, rpc_port_parcel_h); + using ProxyInvokeCallbackFunc = int (*)(void*, rpc_port_parcel_h); + + private: + std::string port_name_; + IEvent* listener_; + bool listening_ = false; + bool loaded_ = false; + ProxyConnectFunc connect_func_ = nullptr; + ProxyDisconnectFunc disconnect_func_ = nullptr; + ProxySendResultFunc send_result_func_ = nullptr; + ProxyInvokeCallbackFunc invoke_callback_func_ = nullptr; +}; +)__cpp_cb"; + } // namespace version2 } // namespace tidl diff --git a/idlc/version2_default_generator.cc b/idlc/version2_default_generator.cc index af5e199..2c52c58 100644 --- a/idlc/version2_default_generator.cc +++ b/idlc/version2_default_generator.cc @@ -137,10 +137,10 @@ void DefaultGenerator::GenCProxyCode(std::shared_ptr options, void DefaultGenerator::GenCppProxyCode(std::shared_ptr options, const Parser& ps) { - CppProxyHeaderGenerator proxy_header(ps.GetDoc()); + CppProxyHeaderGenerator proxy_header(ps.GetDoc(), options); proxy_header.Run(options->GetOutput() + ".h"); - CppProxyBodyGenerator proxy_body(ps.GetDoc()); + CppProxyBodyGenerator proxy_body(ps.GetDoc(), options); proxy_body.Run(options->GetOutput() + ".cc"); } diff --git a/tests/build_tests/CMakeLists.txt b/tests/build_tests/CMakeLists.txt index 58899b4..8d9fe6a 100644 --- a/tests/build_tests/CMakeLists.txt +++ b/tests/build_tests/CMakeLists.txt @@ -97,8 +97,6 @@ SET(TIDL_GEN_SRCS FooPubsubCionGroupC.c Message_v2ProxyC.c Message_v2StubC.c - Message_v2testProxyCpp.cc - Message_v2testStubCpp.cc Buffer_v2ProxyC.c Buffer_v2StubC.c Ex_v2ProxyC.c @@ -109,6 +107,18 @@ SET(TIDL_GEN_SRCS Foo_v2StubC.c Import_v2ProxyC.c Import_v2StubC.c + Message_v2Proxy.cc + Message_v2Stub.cc + Buffer_v2Proxy.cc + Buffer_v2Stub.cc + Ex_v2Proxy.cc + Ex_v2Stub.cc + DataPort_v2Proxy.cc + DataPort_v2Stub.cc + Foo_v2Proxy.cc + Foo_v2Stub.cc + Import_v2Proxy.cc + Import_v2Stub.cc ) ADD_CUSTOM_COMMAND(OUTPUT ${TIDL_GEN_SRCS} PRE_BUILD diff --git a/tests/build_tests/prebuild.sh b/tests/build_tests/prebuild.sh index 76e2476..4ad11e4 100755 --- a/tests/build_tests/prebuild.sh +++ b/tests/build_tests/prebuild.sh @@ -58,15 +58,14 @@ GenerateTIDL() { OUTPUT="${FILES_V2[index]}StubC" ${TIDLC} -s -n -l C -i ${SCRIPT_DIR}/tidl/${INPUT} -o ${TARGET_DIR}/${OUTPUT} - done - INPUT="${FILES_V2[0]}test.tidl" + OUTPUT="${FILES_V2[index]}Proxy" + ${TIDLC} -p -n -l C++ -i ${SCRIPT_DIR}/tidl/${INPUT} -o ${TARGET_DIR}/${OUTPUT} - OUTPUT="${FILES_V2[0]}testProxyCpp" - ${TIDLC} -p -n -l C++ -i ${SCRIPT_DIR}/tidl/${INPUT} -o ${TARGET_DIR}/${OUTPUT} + OUTPUT="${FILES_V2[index]}Stub" + ${TIDLC} -s -n -l C++ -i ${SCRIPT_DIR}/tidl/${INPUT} -o ${TARGET_DIR}/${OUTPUT} - OUTPUT="${FILES_V2[0]}testStubCpp" - ${TIDLC} -s -n -l C++ -i ${SCRIPT_DIR}/tidl/${INPUT} -o ${TARGET_DIR}/${OUTPUT} + done for index in ${!FILES_FOR_GROUP[*]}; do echo "Generate ${FILES_FOR_GROUP[index]}"