Use delegate port to improve concurrency 17/182017/5
authorJunghoon Park <jh9216.park@samsung.com>
Wed, 20 Jun 2018 01:07:19 +0000 (10:07 +0900)
committerJunghoon Park <jh9216.park@samsung.com>
Thu, 21 Jun 2018 04:59:16 +0000 (13:59 +0900)
require:
 - https://review.tizen.org/gerrit/#/c/182016/

Change-Id: I867e7e4795c0d0731cd12ed1aa3fa07a7efd218d
Signed-off-by: Junghoon Park <jh9216.park@samsung.com>
12 files changed:
idlc/c_gen/c_proxy_body_gen_cb.h
idlc/c_gen/c_stub_body_gen.cc
idlc/c_gen/c_stub_body_gen.h
idlc/c_gen/c_stub_body_gen_cb.h
idlc/cpp_gen/cpp_gen_base.cc
idlc/cpp_gen/cpp_proxy_body_gen_cb.h
idlc/cpp_gen/cpp_proxy_header_gen_cb.h
idlc/cpp_gen/cpp_stub_body_gen_cb.h
idlc/cs_gen/cs_cb_interop.h
idlc/cs_gen/cs_cb_rpc_port.h
idlc/cs_gen/cs_gen_base.cc
idlc/cs_gen/cs_proxy_gen_cb.h

index 7ff8448..fd75454 100644 (file)
@@ -23,6 +23,7 @@ struct ##_s {
     char *stub_appid;
     rpc_port_proxy_h proxy;
     rpc_port_h port;
+    rpc_port_h callback_port;
     rpc_port_proxy_##_callback_s callback;
     void *user_data;
     GList *delegates;
@@ -197,7 +198,6 @@ static rpc_port_parcel_h __##_consume_command(rpc_port_proxy_##_h h)
         if (cmd == ##_METHOD_Result)
             return parcel;
 
-        __##_process_received_event(&h->delegates, parcel);
         rpc_port_parcel_destroy(parcel);
         parcel = NULL;
     } while (true);
@@ -213,6 +213,7 @@ static void __##_on_connected(const char *endpoint, const char *port_name, rpc_p
     rpc_port_proxy_##_h handle = data;
 
     handle->port = port;
+    rpc_port_proxy_get_port(handle->proxy, RPC_PORT_PORT_CALLBACK, &handle->callback_port);
     if (handle->callback.connected)
         handle->callback.connected(handle, handle->user_data);
     _I("[__RPC_PORT__] endpoint(%s), port_name(%s)", endpoint, port_name);
@@ -253,24 +254,17 @@ static void __##_on_received(const char *endpoint, const char *port_name, void *
     rpc_port_parcel_h parcel_received;
     int cmd = -1;
 
-    if (g_rec_mutex_trylock(&handle->mutex) == FALSE) {
-        _W("Failed to try to lock the mutex");
-        return;
-    }
-
-    rpc_port_parcel_create_from_port(&parcel_received, handle->port);
+    rpc_port_parcel_create_from_port(&parcel_received, handle->callback_port);
     rpc_port_parcel_read_int32(parcel_received, &cmd);
     if (cmd != ##_METHOD_Callback) {
         _E("Invalid protocol");
         rpc_port_parcel_destroy(parcel_received);
-        g_rec_mutex_unlock(&handle->mutex);
         return;
     }
 
     __##_process_received_event(&handle->delegates, parcel_received);
     rpc_port_parcel_destroy(parcel_received);
     _I("[__RPC_PORT__] endpoint(%s), port_name(%s)", endpoint, port_name);
-    g_rec_mutex_unlock(&handle->mutex);
 }
 )__c_cb";
 
index a11c157..d340aef 100644 (file)
@@ -81,6 +81,9 @@ void CStubBodyGen::GenInterfaceMethods(std::ofstream& stream,
             return GetInterfaceIdWithNamespace(inf);
           },
           [&]()->std::string {
+            return GetInterfaceIdWithNamespace(inf);
+          },
+          [&]()->std::string {
             return GetMethodString(inf, *i);
           }));
   }
@@ -160,7 +163,7 @@ void CStubBodyGen::GenInterfaceGlobalVariables(std::ofstream& stream,
 std::string CStubBodyGen::GetMethodString(const Interface& inf,
                                           const Declaration& decl) {
   std::string str;
-  const char port_setter[] = "rpc_port_$$_set_port($$, port);\n";
+  const char port_setter[] = "rpc_port_$$_set_port($$, callback_port);\n";
   const char setter[] = "$$($$, $$);\n";
   const char do_while_block[] =
       "do {\n" \
@@ -440,9 +443,6 @@ void CStubBodyGen::GenInterfaceDelegatorInvoker(std::ofstream& stream,
           return id;
         },
         [&]()->std::string {
-          return id;
-        },
-        [&]()->std::string {
           std::string str;
           for (auto& i : decl.GetParameters().GetParams()) {
             str += GenTemplateString(parcel,
@@ -480,7 +480,6 @@ void CStubBodyGen::GenInterfaceContext(std::ofstream& stream,
   GenInterfaceContextTagSetter(stream, inf);
   GenInterfaceContextTagGetter(stream, inf);
   GenInterfaceContextSenderGetter(stream, inf);
-  GenInterfaceContextPortExist(stream, inf);
 }
 
 void CStubBodyGen::GenInterfaceContextDeclaration(std::ofstream& stream,
@@ -525,15 +524,6 @@ void CStubBodyGen::GenInterfaceContextSenderGetter(std::ofstream& stream,
       CB_INTERFACE_CONTEXT_GET_SENDER, "##", GetInterfaceIdWithNamespace(inf)));
 }
 
-void CStubBodyGen::GenInterfaceContextPortExist(std::ofstream& stream,
-                                                const Interface& inf) {
-  if (!HasDelegate(inf))
-    return;
-
-  stream << SmartIndent(ReplaceAll(
-      CB_INTERFACE_CONTEXT_PORT_EXIST, "##", GetInterfaceIdWithNamespace(inf)));
-}
-
 void CStubBodyGen::GenTypedefStubMethod(std::ofstream& stream) {
   stream << CB_STUB_METHOD_TYPE;
 }
index 76ac25d..76f55c7 100644 (file)
@@ -66,8 +66,6 @@ class CStubBodyGen : public CBodyGeneratorBase {
                                     const Interface& inf);
   void GenInterfaceContextSenderGetter(std::ofstream& stream,
                                        const Interface& inf);
-  void GenInterfaceContextPortExist(std::ofstream& stream,
-                                    const Interface& inf);
 
  private:
   void GenInterfaceDelegator(std::ofstream& stream, const std::string& id,
index 51455f8..0316e9a 100644 (file)
@@ -22,6 +22,13 @@ R"__c_cb(
 static int __$$_method_$$(rpc_port_h port, rpc_port_parcel_h parcel, void *data)
 {
     rpc_port_stub_$$_context_h context = data;
+    rpc_port_h callback_port;
+    int r = rpc_port_stub_get_port(__$$_stub, RPC_PORT_PORT_CALLBACK,
+            context->instance, &callback_port);
+
+    if (r != 0) {
+      _E("Failed to get callback port");
+    }
 $$
     return 0;
 }
@@ -86,8 +93,8 @@ static int __##_on_received(const char *sender, const char *instance, rpc_port_h
         _E("Failed to find ## context(%s)", instance);
         return -1;
     }
-    context->port = port;
 
+    context->port = port;
     r = rpc_port_parcel_create_from_port(&parcel, port);
     if (r != 0) {
         _E("Failed to create parcel from port");
@@ -339,11 +346,6 @@ int rpc_port_$$_invoke($$)
         return -1;
     }
 
-    if (!__$$_context_port_exist(h->port)) {
-        _E("Port doesn't exist");
-        return -1;
-    }
-
     if (h->once && !h->valid) {
         _E("Invalid callback");
         return -1;
@@ -512,25 +514,6 @@ int rpc_port_stub_##_context_get_sender(rpc_port_stub_##_context_h ctx, char **s
 }
 )__c_cb";
 
-const char CB_INTERFACE_CONTEXT_PORT_EXIST[] =
-R"__c_cb(
-static bool __##_context_port_exist(rpc_port_h port)
-{
-    struct ##_context_s *handle;
-    GList *iter;
-
-    iter = __##_contexts;
-    while (iter) {
-        handle = (struct ##_context_s *)iter->data;
-        if (handle->port == port)
-            return true;
-        iter = g_list_next(iter);
-    }
-
-    return false;
-}
-)__c_cb";
-
 const char CB_STUB_METHOD_TYPE[] =
 R"__c_cb(
 typedef int (*stub_method)(rpc_port_h, rpc_port_parcel_h, void *data);
index 92a4c68..20c69d0 100644 (file)
@@ -546,7 +546,7 @@ std::string CppGeneratorBase::ConvertTypeToDeserializer(
       ret += n + " ";
       if (IsDelegateType(type)) {
         ret += id + "(new " + type.ToString()
-            + "(port, std::weak_ptr<ServiceBase>(b)));\n";
+            + "(callback_port, std::weak_ptr<ServiceBase>(b)));\n";
       } else {
         ret += id + ";\n";
       }
index be77dd5..3d39081 100644 (file)
@@ -118,7 +118,6 @@ void ##::ConsumeCommand(rpc_port_parcel_h* parcel, rpc_port_h port) {
       return;
     }
 
-    ProcessReceivedEvent(p);
     rpc_port_parcel_destroy(p);
     *parcel = nullptr;
   } while (true);
@@ -127,7 +126,11 @@ void ##::ConsumeCommand(rpc_port_parcel_h* parcel, rpc_port_h port) {
 
 void ##::OnConnectedCB(const char *ep, const char *port_name, rpc_port_h port, void *data) {
   ##* l = static_cast<##*>(data);
+  rpc_port_h cb_port;
+
   l->port_ = port;
+  rpc_port_proxy_get_port(l->proxy_, RPC_PORT_PORT_CALLBACK, &cb_port);
+  l->callback_port_ = cb_port;
   l->listener_->OnConnected();
 }
 
@@ -147,18 +150,11 @@ void ##::OnReceivedCB(const char *ep, const char *port_name, void *data) {
   int cmd;
   rpc_port_parcel_h parcel_received;
 
-  if (!l->mutex_.try_lock()) {
-    _W("Failed to try to lock the mutex");
-    return;
-  }
-
-  if (rpc_port_parcel_create_from_port(&parcel_received, l->port_) != 0) {
+  if (rpc_port_parcel_create_from_port(&parcel_received, l->callback_port_) != 0) {
     _E("Failed to create parcel from port");
-    l->mutex_.unlock();
     return;
   }
 
-  l->mutex_.unlock();
   rpc_port_parcel_read_int32(parcel_received, &cmd);
   if (cmd != static_cast<int>(MethodId::__Callback)) {
     rpc_port_parcel_destroy(parcel_received);
index 292b7db..0bf19ee 100644 (file)
@@ -96,6 +96,7 @@ R"__cpp_cb(  void ProcessReceivedEvent(rpc_port_parcel_h parcel);
   static void OnReceivedCB(const char *ep, const char *port_name, void *data);
 
   rpc_port_h port_;
+  rpc_port_h callback_port_;
   rpc_port_proxy_h proxy_;
   IEventListener* listener_;
   std::recursive_mutex mutex_;
index 86d3498..3ca0cc1 100644 (file)
@@ -85,6 +85,7 @@ int $$::OnReceivedCB(const char* sender, const char* instance, rpc_port_h port,
   int cmd;
   int ret;
   std::shared_ptr<ServiceBase> b;
+  rpc_port_h callback_port;
 
   for (auto& i : cxt->services_) {
     if (i->GetInstance() == instance) {
@@ -98,6 +99,12 @@ int $$::OnReceivedCB(const char* sender, const char* instance, rpc_port_h port,
     return -1;
   }
 
+  ret = rpc_port_stub_get_port(cxt->stub_, RPC_PORT_PORT_CALLBACK, instance,
+      &callback_port);
+  if (ret != 0) {
+    _E("Failed to get callback port");
+  }
+
   ret = rpc_port_parcel_create_from_port(&p, port);
   if (ret != 0) {
     _E("Failed to create parcel from port");
index b2a5eaa..4e6cf90 100644 (file)
@@ -37,6 +37,12 @@ internal static partial class Interop
             IoError = Tizen.Internals.Errors.ErrorCode.IoError,
         }
 
+        internal enum PortType
+        {
+            Main,
+            Callback
+        }
+
         internal static partial class Parcel
         {
             //int rpc_port_parcel_create(rpc_port_parcel_h *h);
@@ -189,6 +195,10 @@ internal static partial class Interop
             //int rpc_port_proxy_add_received_event_cb(rpc_port_proxy_h h, rpc_port_proxy_received_event_cb cb, void* data);
             [DllImport(Libraries.RpcPort, EntryPoint = "rpc_port_proxy_add_received_event_cb")]
             internal static extern ErrorCode AddReceivedEventCb(IntPtr handle, ReceivedEventCallback cb, IntPtr data);
+
+            //int rpc_port_proxy_get_port(rpc_port_proxy_h h, rpc_port_port_type_e type, rpc_port_h* port);
+            [DllImport(Libraries.RpcPort, EntryPoint = "rpc_port_proxy_get_port")]
+            internal static extern ErrorCode GetPort(IntPtr handle, PortType t, out IntPtr port);
         }
 
         internal static partial class Stub
@@ -236,6 +246,10 @@ internal static partial class Interop
             //int rpc_port_stub_set_trusted(rpc_port_stub_h h, const bool trusted);
             [DllImport(Libraries.RpcPort, EntryPoint = "rpc_port_stub_set_trusted")]
             internal static extern ErrorCode SetTrusted(IntPtr handle, bool trusted);
+
+            //int rpc_port_stub_get_port(rpc_port_stub_h h, rpc_port_port_type_e type, const char* instance, rpc_port_h *port);
+            [DllImport(Libraries.RpcPort, EntryPoint = "rpc_port_stub_get_port")]
+            internal static extern ErrorCode GetPort(IntPtr handle, PortType t, string instance, out IntPtr port);
         }
     }
 }
index 89dae42..a2b52d1 100644 (file)
@@ -30,6 +30,12 @@ namespace Tizen.Applications.RPCPort
 
     public class Port
     {
+        public enum Type
+        {
+            Main,
+            Callback
+        }
+
         internal IntPtr Handle { get; set; }
         internal Port() { }
     }
@@ -219,6 +225,7 @@ namespace Tizen.Applications.RPCPort
         private IntPtr _proxy;
 
         protected Port Port { get; private set; }
+        protected Port CallbackPort { get; private set; }
 
         public ProxyBase()
         {
@@ -248,6 +255,20 @@ namespace Tizen.Applications.RPCPort
             }
         }
 
+        protected Port GetPort(Port.Type t)
+        {
+            var err = Interop.LibRPCPort.Proxy.GetPort(_proxy,
+                (Interop.LibRPCPort.PortType)t, out IntPtr port);
+            switch (err)
+            {
+                case Interop.LibRPCPort.ErrorCode.InvalidParameter:
+                case Interop.LibRPCPort.ErrorCode.IoError:
+                    throw new InvalidIOException();
+            }
+
+            return new Port() { Handle = port };
+        }
+
         protected abstract void OnConnectedEvent(string endPoint, string portName, Port port);
         protected abstract void OnDisconnectedEvent(string endPoint, string portName);
         protected abstract void OnReceivedEvent(string endPoint, string portName);
@@ -256,12 +277,14 @@ namespace Tizen.Applications.RPCPort
         private void OnConnectedEvent(string endPoint, string portName, IntPtr port, IntPtr data)
         {
             Port = new Port() { Handle = port };
+            CallbackPort = GetPort(Port.Type.Callback);
             OnConnectedEvent(endPoint, portName, Port);
         }
 
         private void OnDisconnectedEvent(string endPoint, string portName, IntPtr data)
         {
             Port = null;
+            CallbackPort = null;
             OnDisconnectedEvent(endPoint, portName);
         }
 
@@ -359,6 +382,21 @@ namespace Tizen.Applications.RPCPort
             }
         }
 
+        protected Port GetPort(Port.Type t, string instance)
+        {
+            var err = Interop.LibRPCPort.Stub.GetPort(_stub,
+                (Interop.LibRPCPort.PortType)t, instance, out IntPtr port);
+            switch (err)
+            {
+                case Interop.LibRPCPort.ErrorCode.InvalidParameter:
+                    throw new InvalidIDException();
+                case Interop.LibRPCPort.ErrorCode.IoError:
+                    throw new InvalidIOException();
+            }
+
+            return new Port() { Handle = port };
+        }
+
         protected abstract void OnConnectedEvent(string sender, string instance);
 
         protected abstract void OnDisconnectedEvent(string sender, string instance);
index f196212..a9d8c1c 100644 (file)
@@ -260,7 +260,8 @@ std::string CsGeneratorBase::ConvertTypeToDeserializer(
       ret = n + " ";
 
     if (IsDelegateType(type)) {
-      ret += id + " = new " + n +"(port, new WeakReference(b));\n";
+      ret += id + " = new " + n
+          + "(GetPort(Port.Type.Callback, instance), new WeakReference(b));\n";
       ret += "CallbackBase.";
     } else {
       ret += id + " = new " + n +"();\n";
index 1ad799d..a9f51ff 100644 (file)
@@ -68,11 +68,8 @@ R"__cs_cb(
             protected override void OnReceivedEvent(string endPoint, string portName)
             {
                 Parcel parcelReceived;
-                if (!Monitor.TryEnter(_lock))
-                  return;
 
-                parcelReceived = new Parcel(Port);
-                Monitor.Exit(_lock);
+                parcelReceived = new Parcel(CallbackPort);
 
                 using (parcelReceived)
                 {
@@ -99,7 +96,6 @@ R"__cs_cb(
                         return;
                     }
 
-                    ProcessReceivedEvent(p);
                     p.Dispose();
                     parcel = null;
                 } while (true);