Use modified tizen_base::Parcel 96/281996/1
authorHwankyu Jhun <h.jhun@samsung.com>
Mon, 26 Sep 2022 05:20:37 +0000 (05:20 +0000)
committerHwankyu Jhun <h.jhun@samsung.com>
Mon, 26 Sep 2022 05:20:37 +0000 (05:20 +0000)
To improve the performance of the parcel creation, the implementation of
the Parcel is changed. It uses malloc() instead of std::vector.

Requires:
 - https://review.tizen.org/gerrit/#/c/platform/core/base/bundle/+/281779/

Change-Id: Ic3f317b4253116a8df37375d295ed63bf643b5ca
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
component_based/port/client.cc
component_based/port/client.hh
component_based/port/port.cc
component_based/port/port_implementation.hh
component_based/port/server.cc
component_based/port/server.hh
component_based/port/stub.cc

index 09f9f637d771d960268232aec0d81993c3b9e300..5ecd8e9c013c35cca7a9d22d96f07c6ebd3be8d4 100644 (file)
@@ -84,45 +84,29 @@ Client* Client::Create(const std::string& name, int timeout) {
   return new (std::nothrow) Client(fd);
 }
 
-int Client::Send(const std::vector<uint8_t>& data) {
-  size_t size = data.size();
-  auto* p = reinterpret_cast<void*>(&size);
-  int ret = Socket::Send(p, sizeof(size));
-  if (ret != 0) {
-    _E("Send() is failed. error(%d)", ret);
-    return ret;
-  }
-
-  auto* dp = reinterpret_cast<const void*>(&data[0]);
-  ret = Socket::Send(dp, data.size());
+int Client::Send(const void* data, size_t data_size) {
+  int ret = Socket::Send(data, data_size);
   if (ret != 0)
     _E("Send() is failed. error(%d)", ret);
 
-  if (getenv("PORT_DEBUG"))
-    Util::Hexdump("Send", data);
+  if (getenv("PORT_DEBUG")) {
+    auto* p = reinterpret_cast<const uint8_t*>(data);
+    Util::Hexdump("Send", std::vector<uint8_t>(p, p + data_size));
+  }
+
   return ret;
 }
 
-int Client::Recv(std::vector<uint8_t>& data) {
-  size_t size = 0;
-  auto* p = reinterpret_cast<void*>(&size);
-  int ret = Socket::Read(p, sizeof(size));
-  if (ret != 0) {
+int Client::Recv(void* data, size_t data_size) {
+  int ret = Socket::Read(data, data_size);
+  if (ret != 0)
     _E("Read() is failed. error(%d)", ret);
-    return ret;
-  }
 
-  std::vector<uint8_t> buf(size);
-  p = reinterpret_cast<void*>(&buf[0]);
-  ret = Socket::Read(p, size);
-  if (ret != 0) {
-    _E("Read() is failed. error(%d)", ret);
-    return ret;
+  if (getenv("PORT_DEBUG")) {
+    auto* p = reinterpret_cast<uint8_t*>(data);
+    Util::Hexdump("Recv", std::vector<uint8_t>(p, p + data_size));
   }
 
-  std::copy(buf.begin(), buf.end(), std::back_inserter(data));
-  if (getenv("PORT_DEBUG"))
-    Util::Hexdump("Recv", data);
   return ret;
 }
 
index cfbb0e7fefb040699bfa60259dacd8221801c3a5..2b46bb106fff257797889e304d3e708eea9908db 100644 (file)
@@ -34,8 +34,8 @@ class Client : public Socket {
 
   static Client* Create(const std::string& name, int timeout = 0);
 
-  int Send(const std::vector<uint8_t>& data);
-  int Recv(std::vector<uint8_t>& data);
+  int Send(const void* data, size_t data_size);
+  int Recv(void* data, size_t data_size);
 
   pid_t GetPid() const;
 
index caf712d97c45cb4171c9d12aa5bb7a89fc695085..a01b453c538ec91f7e07ef16af350609389ed9e9 100644 (file)
@@ -60,25 +60,18 @@ int Port::Impl::Send(const std::string& endpoint, int timeout,
     return -EIO;
   }
 
-  Request req(std::string(name_), false, request->GetRaw());
+  Request req(std::string(name_), false, request->ToRaw());
   tizen_base::Parcel req_parcel;
   req_parcel.WriteParcelable(req);
-  int ret = client->Send(req_parcel.GetRaw());
-  if (ret != 0) {
-    _E("Send() is failed. endpoint(%s), error(%d)", endpoint.c_str(), ret);
+  size_t data_size = 0;
+  uint8_t* data = nullptr;
+  int ret = SendAndReceive(client.get(), req_parcel.GetData(),
+      req_parcel.GetDataSize(), &data, &data_size);
+  if (ret != 0)
     return ret;
-  }
-
-  std::vector<uint8_t> data;
-  ret = client->Recv(data);
-  if (ret != 0) {
-    _E("Recv() is failed. endpoint(%s), error(%d)", endpoint.c_str(), ret);
-    return ret;
-  }
 
   Response res;
-  auto* p = reinterpret_cast<void*>(&data[0]);
-  tizen_base::Parcel res_parcel(p, data.size());
+  tizen_base::Parcel res_parcel(data, data_size, false);
   res_parcel.ReadParcelable(&res);
   return res.GetResult();
 }
@@ -92,25 +85,18 @@ int Port::Impl::SendSync(const std::string& endpoint, int timeout,
     return -EIO;
   }
 
-  Request req(std::string(name_), true, request->GetRaw());
+  Request req(std::string(name_), true, request->ToRaw());
   tizen_base::Parcel req_parcel;
   req_parcel.WriteParcelable(req);
-  int ret = client->Send(req_parcel.GetRaw());
-  if (ret != 0) {
-    _E("Send() is failed. endpoint(%s), error(%d)", endpoint.c_str(), ret);
+  size_t data_size = 0;
+  uint8_t* data = nullptr;
+  int ret = SendAndReceive(client.get(), req_parcel.GetData(),
+      req_parcel.GetDataSize(), &data, &data_size);
+  if (ret != 0)
     return ret;
-  }
-
-  std::vector<uint8_t> data;
-  ret = client->Recv(data);
-  if (ret != 0) {
-    _E("Recv() is failed. endpoint(%s), error(%d)", endpoint.c_str(), ret);
-    return ret;
-  }
 
   Response res;
-  auto* p = reinterpret_cast<void*>(&data[0]);
-  tizen_base::Parcel res_parcel(p, data.size());
+  tizen_base::Parcel res_parcel(data, data_size, false);
   res_parcel.ReadParcelable(&res);
   auto& res_data = res.GetData();
   if (res_data.size() > 0) {
@@ -121,6 +107,44 @@ int Port::Impl::SendSync(const std::string& endpoint, int timeout,
   return res.GetResult();
 }
 
+int Port::Impl::SendAndReceive(Client* client, const uint8_t* send_data,
+    size_t send_data_size, uint8_t** recv_data, size_t* recv_data_size) {
+  int ret = client->Send(&send_data_size, sizeof(send_data_size));
+  if (ret != 0) {
+    _E("Send() is failed. error(%d)", ret);
+    return ret;
+  }
+
+  ret = client->Send(send_data, send_data_size);
+  if (ret != 0) {
+    _E("Send() is failed. error(%d)", ret);
+    return ret;
+  }
+
+  size_t data_size = 0;
+  ret = client->Recv(&data_size, sizeof(data_size));
+  if (ret != 0) {
+    _E("Recv() is failed. error(%d)", ret);
+    return ret;
+  }
+
+  uint8_t* data = static_cast<uint8_t*>(malloc(data_size));
+  if (data == nullptr) {
+    _E("Out of memory");
+    return ret;
+  }
+
+  ret = client->Recv(data, data_size);
+  if (ret != 0) {
+    _E("Recv() is failed. error(%d)", ret);
+    return ret;
+  }
+
+  *recv_data = data;
+  *recv_data_size = data_size;
+  return ret;
+}
+
 void Port::Impl::OnSyncRequestReceived(const std::string& sender, pid_t pid,
     const std::vector<uint8_t>& request, std::vector<uint8_t>& response) {
   auto sender_info = std::make_shared<SenderInfo>(sender, pid);
@@ -131,8 +155,8 @@ void Port::Impl::OnSyncRequestReceived(const std::string& sender, pid_t pid,
   auto res = std::shared_ptr<tizen_base::Parcel>(
       new (std::nothrow) tizen_base::Parcel());
   listener_->OnSyncRequest(sender_info, req, res);
-  std::copy(res->GetRaw().begin(), res->GetRaw().end(),
-      std::back_inserter(response));
+  response.insert(response.end(), res->GetData(),
+      res->GetData() + res->GetDataSize());
 }
 
 void Port::Impl::OnRequestReceived(const std::string& sender, pid_t pid,
index 6029181bb65d07fc6d273d2d3172e92a08b97cf5..f85a0a33dd1197efe5b405f026bac5a895d31af3 100644 (file)
@@ -43,6 +43,8 @@ class Port::Impl : public Server::IEvent {
   friend class Port;
   explicit Impl(Port* parent, std::string name, Port::IEvent* listener);
 
+  int SendAndReceive(Client* client, const uint8_t* send_data,
+      size_t send_data_size, uint8_t** recv_data, size_t* recv_data_size);
   void OnSyncRequestReceived(const std::string& sender, pid_t pid,
       const std::vector<uint8_t>& request,
       std::vector<uint8_t>& response) override;
index c59d974a70163f9ef9ad7078c6cd48cb8424305d..9d59c7902ecfc8f64e037c549bed357e2e144421 100644 (file)
@@ -127,6 +127,32 @@ int Server::CheckPrivilege(int fd) {
   return checker_->Check(fd);
 }
 
+int Server::ReceiveData(Client* client, uint8_t** data, size_t* data_size) {
+  size_t size = 0;
+  int ret = client->Recv(&size, sizeof(size));
+  if (ret != 0) {
+    _E("Recv() is failed. error(%d)", ret);
+    return ret;
+  }
+
+  uint8_t* buf = static_cast<uint8_t*>(malloc(size));
+  if (buf == nullptr) {
+    _E("malloc() is failed");
+    return -ENOMEM;
+  }
+
+  ret = client->Recv(buf, size);
+  if (ret != 0) {
+    _E("Recv() is failed. error(%d)", ret);
+    std::free(buf);
+    return ret;
+  }
+
+  *data = buf;
+  *data_size = size;
+  return ret;
+}
+
 gboolean Server::GIOFunc(GIOChannel* source, GIOCondition cond, gpointer data) {
   if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
     _E("Error condition(%d)", static_cast<int>(cond));
@@ -141,23 +167,31 @@ gboolean Server::GIOFunc(GIOChannel* source, GIOCondition cond, gpointer data) {
   int ret = handle->CheckPrivilege(client->GetFd());
   if (ret != 0) {
     _E("Request is denied");
-    std::vector<uint8_t> buf;
-    client->Recv(buf);
+    size_t data_size = 0;
+    uint8_t* data = nullptr;
+    if (handle->ReceiveData(client.get(), &data, &data_size) != 0)
+      return G_SOURCE_CONTINUE;
+
+    std::free(data);
 
     std::vector<uint8_t> dummy;
     Response res(ret, dummy);
     tizen_base::Parcel res_parcel;
     res_parcel.WriteParcelable(res);
-    client->Send(res_parcel.GetRaw());
+    data_size = res_parcel.GetDataSize();
+    client->Send(&data_size, sizeof(data_size));
+    client->Send(res_parcel.GetData(), data_size);
     return G_SOURCE_CONTINUE;
   }
 
   auto* listener = handle->listener_;
   if (listener) {
-    std::vector<uint8_t> buf;
-    client->Recv(buf);
-    auto* p = reinterpret_cast<void*>(&buf[0]);
-    tizen_base::Parcel parcel(p, buf.size());
+    size_t data_size = 0;
+    uint8_t* data = nullptr;
+    if (handle->ReceiveData(client.get(), &data, &data_size) != 0)
+      return G_SOURCE_REMOVE;
+
+    tizen_base::Parcel parcel(data, data_size, false);
     Request req;
     parcel.ReadParcelable(&req);
     _W("Sender(%s), sync(%s)",
@@ -169,13 +203,17 @@ gboolean Server::GIOFunc(GIOChannel* source, GIOCondition cond, gpointer data) {
       Response res(0, res_data);
       tizen_base::Parcel res_parcel;
       res_parcel.WriteParcelable(res);
-      client->Send(res_parcel.GetRaw());
+      data_size = res_parcel.GetDataSize();
+      client->Send(&data_size, sizeof(data_size));
+      client->Send(res_parcel.GetData(), data_size);
     } else {
       std::vector<uint8_t> dummy;
       Response res(0, dummy);
       tizen_base::Parcel res_parcel;
       res_parcel.WriteParcelable(res);
-      client->Send(res_parcel.GetRaw());
+      data_size = res_parcel.GetDataSize();
+      client->Send(&data_size, sizeof(data_size));
+      client->Send(res_parcel.GetData(), data_size);
       listener->OnRequestReceived(req.GetSender(), client->GetPid(),
           req.GetData());
     }
index fc650c314209001ce27086892f6613d46e702f14..f8f182a9e066e0066cd0425dd400df5ee050fd0d 100644 (file)
@@ -50,6 +50,7 @@ class Server {
   static Server* Create(const std::string& name, IEvent* listener);
 
  private:
+  int ReceiveData(Client* client, uint8_t** data, size_t* data_size);
   static gboolean GIOFunc(GIOChannel* source, GIOCondition cond, gpointer data);
   Client* Accept();
   int CheckPrivilege(int fd);
index 1fd3e66220dd169c4ff977da819b484e1e604295..b6540fffb07f244fbd09f1d812ab1e82a04026f5 100644 (file)
@@ -330,9 +330,7 @@ extern "C" EXPORT_API int component_port_send_sync(component_port_h port,
 
   parcel_h res_parcel = nullptr;
   parcel_create(&res_parcel);
-  auto& res_data = res->GetRaw();
-  auto* res_p = reinterpret_cast<const void*>(&res_data[0]);
-  parcel_burst_write(res_parcel, res_p, res_data.size());
+  parcel_burst_write(res_parcel, res->GetData(), res->GetDataSize());
   *response = res_parcel;
   return COMPONENT_PORT_ERROR_NONE;
 }