Add timeout sequence for senddata sync calling
authorSukHyung, Kang <shine.kang@samsung.com>
Wed, 28 Apr 2021 08:11:03 +0000 (17:11 +0900)
committer강석형/Tizen Platform Lab(SR)/Engineer/삼성전자 <shine.kang@samsung.com>
Thu, 6 May 2021 07:44:59 +0000 (16:44 +0900)
Signed-off-by: SukHyung, Kang <shine.kang@samsung.com>
cion/channel/client_channel.cc
cion/channel/client_channel_implementation.hh
cion/channel/server_channel.cc
cion/channel/shared_queue.hh
cion/common/cion_error.hh
cion/common/exception.hh
cion/tizen-api/cion_client.cc
cion/vine/vine_dp.cc
cion/vine/vine_dp.hh

index 6a8a257824da6afcb00ddf70d7ca29e552570331..498be11ad0734f110af71063d77578b0e1f9e721 100644 (file)
@@ -163,15 +163,27 @@ void ClientChannel::Impl::OnReceived(
   unsigned int cmd;
   pl.ReadUInt32(&cmd);
   if (cmd == cmd::DataSyncReply) {
-    LOG(INFO) << "PayloadReceived from server";
     uint32_t size;
     pl.ReadUInt32(&size);
-    unsigned char* payload_data =
-        (unsigned char*)calloc(size, sizeof(unsigned char));
-    pl.Read(payload_data, size);
-    reply_queue_.Push(
-        std::vector<char>(payload_data, payload_data + size));
-    free(payload_data);
+    unsigned int sequence_id;
+    pl.ReadUInt32(&sequence_id);
+    LOG(INFO) << "OnReceived datasync reply seq id : " << sequence_id;
+
+    if (is_timeover_) {
+      LOG(INFO) << "OnReceived data sync reply timeover seq id : " << sequence_id;
+      return;
+    }
+
+    if (sequence_id == sequence_id_) {
+      unsigned char* payload_data =
+          (unsigned char*)calloc(size, sizeof(unsigned char));
+      pl.Read(payload_data, size);
+      reply_queue_.Push(
+          std::vector<char>(payload_data, payload_data + size));
+      free(payload_data);
+    } else {
+      LOG(INFO) << "OnReceived data sync sequence id not matched";
+    }
     return;
   }
 
@@ -375,11 +387,23 @@ void ClientChannel::Disconnect() {
 }
 
 std::vector<char> ClientChannel::SendData(std::vector<char> data, int timeout) {
-  LOG(WARNING) << "send data";
+  std::lock_guard<std::mutex> lock(impl_->mutex_);
+
   std::vector<char> ret;
-  auto *d = reinterpret_cast<std::vector<uint8_t>*>(&data);
+  impl_->sequence_id_ = IDGenerator::GetInst().GenSequenceId();
+  impl_->is_timeover_ = false;
+  LOG(WARNING) << "send data seq id : " << impl_->sequence_id_;
+
+       auto *d = reinterpret_cast<std::vector<uint8_t>*>(&data);
   impl_->Send(cmd::DataSync, *d);
-  impl_->reply_queue_.WaitAndPop(ret);
+  impl_->reply_queue_.WaitAndPopFor(ret, timeout);
+
+  if (ret.empty()) {
+    impl_->sequence_id_ = -1;
+    impl_->is_timeover_ = true;
+    THROW(error::CION_ERROR_SEND_DATA_TIME_OUT);
+  }
+
   return ret;
 }
 
@@ -424,10 +448,16 @@ void ClientChannel::Impl::Send(cmd::CionCmd cmd, std::vector<uint8_t> raw) {
   tizen_base::Parcel parcel;
   parcel.WriteUInt32(cmd);
   parcel.WriteUInt32(raw.size());
+
+  if (cmd == cmd::DataSync) {
+    parcel.WriteUInt32(sequence_id_);
+    LOG(INFO) << "send uint& seq id : " << sequence_id_;
+  }
+
   parcel.Write(raw.data(), raw.size());
 
   client_dp->SendDataAsync(parcel.GetRaw());
-  LOG(INFO) << "send " << parcel.GetRaw().size();
+  LOG(INFO) << "send uint& " << parcel.GetRaw().size();
 }
 
 std::shared_ptr<PeerInfo> ClientChannel::GetPeerInfo() {
index b23b184e323b821e334f819de1312518e5d4e667..fba89b0b1765ab02f19f3053e517766fc3234c23 100644 (file)
@@ -70,6 +70,10 @@ class ClientChannel::Impl : public IVineBrowser, IVineDpOpenedEventHandler,
   SharedQueue<std::vector<char>> reply_queue_;
   SharedQueue<VineDpPtr> terminated_dp_queue_;
   std::shared_ptr<VineDiscoverer> discoverer_ = nullptr;
+
+  bool is_timeover_ = false;
+  unsigned int sequence_id_ = 0;
+  mutable std::mutex mutex_;
 };
 
 }  // namespace channel
index 14f3a873984738ef4cf68ed84cbe9820374ad1d1..56af4ff7f686bc9ab8bfaf70cdf5d07e09bb4ddd 100644 (file)
@@ -182,7 +182,7 @@ void ServerChannel::Impl::ReceiveFile(std::shared_ptr<IPayload> payload,
 
 void ServerChannel::Impl::OnReceived(
     VineDpPtr dp, std::vector<unsigned char> data) {
-  LOG(INFO) << "OnReceived " << dp->GetRawDp();
+  LOG(INFO) << "server OnReceived " << dp->GetRawDp();
   ChannelJob<ServerChannel> job(parent_, std::make_shared<tizen_base::Parcel>(
     data.data(), data.size()), dp);
   queue_.Push(job);
@@ -247,8 +247,11 @@ void ServerChannel::Impl::OnReceived(
 
         case cmd::CionCmd::DataSync:
         {
-          LOG(INFO) << "DataSync from client";
           parcel->ReadUInt32(&size);
+          unsigned int sequence_id;
+          parcel->ReadUInt32(&sequence_id);
+          LOG(INFO) << "server DataSync from client seq id : " << sequence_id;
+
           unsigned char* sync_data =
               (unsigned char*)calloc(size, sizeof(unsigned char));
           parcel->Read(sync_data, size);
@@ -260,6 +263,7 @@ void ServerChannel::Impl::OnReceived(
               std::vector<char> result = channel->OnDataReceived(
                   std::vector<char>(sync_data, sync_data + size), peer);
               auto *r = reinterpret_cast<std::vector<uint8_t>*>(&result);
+              speer->GetClientDp()->SetSequenceId(sequence_id);
               channel->impl_->Send(cmd::CionCmd::DataSyncReply,
                   speer->GetClientDp(), *r);
               break;
@@ -332,10 +336,18 @@ void ServerChannel::Impl::Send(cmd::CionCmd cmd, VineDpPtr client_dp,
   tizen_base::Parcel parcel;
   parcel.WriteUInt32(cmd);
   parcel.WriteUInt32(raw.size());
+
+  if (cmd == cmd::CionCmd::DataSyncReply) {
+    unsigned int seq_id = client_dp->GetSequenceId();
+    LOG(WARNING) << "server send dp seq : " << seq_id;
+
+    parcel.WriteUInt32(seq_id);
+  }
+
   parcel.Write(raw.data(), raw.size());
 
   client_dp->SendDataAsync(parcel.GetRaw());
-  LOG(WARNING) << "send " << parcel.GetRaw().size();
+  LOG(WARNING) << "server send " << parcel.GetRaw().size();
 }
 
 void ServerChannel::Listen() {
index 347740efa328962fef7aa2c5779588fd489a737a..82b52301bb04b7c9ff1475daa8dba93e8405c8e3 100644 (file)
@@ -21,6 +21,9 @@
 #include <mutex>
 #include <queue>
 #include <thread>
+#include <chrono>
+
+#include "cion/common/util/logging.hh"
 
 namespace cion {
 
@@ -56,6 +59,23 @@ class SharedQueue {
     queue_.pop();
   }
 
+  void WaitAndPopFor(T& item, int timeout) {
+    std::unique_lock<std::mutex> lock(mutex_);
+
+    std::cv_status ret;
+
+    std::chrono::milliseconds duration(timeout);
+    ret = cond_var_.wait_for(lock, duration);
+
+    if (ret == std::cv_status::timeout) {
+      LOG(ERROR) << "WaitAndPopFor timeout";
+      return;
+    }
+
+    item = queue_.front();
+    queue_.pop();
+  }
+
   bool Empty() {
     std::lock_guard<std::mutex> lock(mutex_);
     return queue_.empty();
index 54dbe1b7915c4a46b2352cd3edc3450102ac5dc2..73fcf0ea1f4153802a5a7209a6864d55d86f1886 100644 (file)
@@ -93,6 +93,13 @@ namespace error {
        * Wi-Fi Interface is down
        */
       CION_ERROR_INTERFACE_DOWN = -ENETDOWN,
+      /**
+       * Interface down(100)
+       */
+      CION_ERROR_SEND_DATA_TIME_OUT = -ETIME,
+      /**
+       * Send data time out(62)
+       */
   };
 
 }
index fecd9fba4cbaadb3ad1d45b5ef95255b6fdc9bf4..3d89d46a4ce936191194a30ccc64c0d1cb44f56e 100644 (file)
@@ -81,6 +81,8 @@ class Exception : public std::exception {
       return ": CION_ERROR_REJECTED_BY_PEER";
     case cion::error::CION_ERROR_INTERFACE_DOWN:
       return ": CION_ERROR_INTERFACE_DOWN";
+    case cion::error::CION_ERROR_SEND_DATA_TIME_OUT:
+      return ": CION_ERROR_SEND_DATA_TIME_OUT";
     default:
       return "";
     }
index 51b2a304589888d604c4062798fc4f951c2c3226..8501738cdc7df0c8aef53d033c88cb14f3cecfed 100644 (file)
@@ -23,6 +23,7 @@
 #include "cion/tizen-api/cion_error.h"
 
 #include "cion/channel/client_channel.hh"
+#include "cion/common/exception.hh"
 
 #ifndef C_EXPORT
 #define C_EXPORT extern "C" __attribute__((visibility("default")))
@@ -223,7 +224,13 @@ C_EXPORT int cion_client_send_data(cion_client_h client, unsigned char* data,
 
   // std::vector<unsigned char> ??
   std::vector<char> v(data, data + data_size);
-  std::vector<char> r = (*c)->SendData(v, timeout);
+  std::vector<char> r;
+  try {
+    r = (*c)->SendData(v, timeout);
+  } catch (cion::Exception& e) {
+    return e.GetErrorCode();
+  }
+
   if (r.empty())
     return CION_ERROR_IO_ERROR;
 
index d779d482c93552a3e420a12e65c180a06245508d..3f39fbaf06dbba6a6a97cb0ceeb60702c0f8a7a8 100644 (file)
@@ -193,4 +193,12 @@ bool VineDp::SetVineDpReceivedCb() {
   return true;
 }
 
+void VineDp::SetSequenceId(unsigned int id) {
+  seq_id_ = id;
+}
+
+unsigned int VineDp::GetSequenceId() {
+  return seq_id_;
+}
+
 }  // namespace cion
index 79b710143ac0b3f796c3c6545019e5208203fbc8..d03c21a9466831d43d5a10dca1a1b1a8a1fb624f 100644 (file)
@@ -50,6 +50,9 @@ class VineDp {
   bool SetVineDpTerminatedCb();
   bool SetVineDpReceivedCb();
 
+  void SetSequenceId(unsigned int id);
+  unsigned int GetSequenceId();
+
  protected:
   explicit VineDp(std::shared_ptr<VineSession> session);
 
@@ -61,6 +64,8 @@ class VineDp {
   IVineDpOpenedEventHandler* opened_handler_ = nullptr;
   IVineDpReceivedEventHandler* received_handler_ = nullptr;
   bool is_owned_;
+
+  unsigned int seq_id_;
 };
 
 }  // namespace cion