Modify implementation of poll fd 11/306611/6
authorHwankyu Jhun <h.jhun@samsung.com>
Fri, 23 Feb 2024 06:26:15 +0000 (15:26 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Mon, 26 Feb 2024 01:22:27 +0000 (10:22 +0900)
If the use count of the poll fd is less than 3, the tizen_core_source_remove_poll()
returns TIZEN_CORE_ERROR_INVALID_CONTEXT.
If the poll fd is already added, the tizen_core_source_add_poll()
returns TIZEN_CORE_ERROR_INVALID_CONTEXT.
The tizen_core_source_get_poll_fds() function is removed.

Change-Id: I91254d94ad07eb64695c8d85f8cea1cdad0e6daf
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
tizen_base/interface_source.h
tizen_base/poll_fd.cc
tizen_base/poll_fd.h
tizen_base/source.cc
tizen_base/source.h
tizen_base/stub.cc

index d06295e1c82c7b8ba77c17b544278662f041630e..d15d7be39ca26a1e8c5cbc840a2ac70cdf030822 100644 (file)
@@ -26,11 +26,14 @@ namespace tizen_base {
 namespace tizen_core {
 
 class Context;
+class PollFd;
 
 class EXPORT_API ISource {
  public:
   virtual ~ISource() = default;
   virtual void Attach(const std::shared_ptr<Context>& context) = 0;
+  virtual void AddPoll(std::shared_ptr<PollFd> poll_fd) = 0;
+  virtual void RemovePoll(const std::shared_ptr<PollFd>& poll_fd) = 0;
   virtual void RefSelf() = 0;
   virtual void UnrefSelf() = 0;
 };
index 3bbf0ad54b1759ddcd2974027786c4ff40f2de6f..3f8ce03638404abcdb641312d72ff70f46f59236 100644 (file)
@@ -41,7 +41,20 @@ const GPollFD* PollFd::GetGPollFD() const { return &gpollfd_; }
 
 void PollFd::RefSelf() { self_ = shared_from_this(); }
 
-void PollFd::UnrefSelf() { self_.reset(); }
+void PollFd::UnrefSelf() {
+  if (!self_) return;
+
+  if (source_ != nullptr) {
+    source_->RemovePoll(self_);
+    source_ = nullptr;
+  }
+
+  self_.reset();
+}
+
+void PollFd::SetSource(ISource* source) { source_ = source; }
+
+ISource* PollFd::GetSource() const { return source_; }
 
 }  // namespace tizen_core
 }  // namespace tizen_base
index bc28d6e169a63d166f66f94e4f9db194bee5e4f8..f2a5a34769d75b5dcfb338a2efa3ff7017446181 100644 (file)
@@ -21,6 +21,8 @@
 
 #include <memory>
 
+#include "tizen_base/interface_source.h"
+
 #undef EXPORT_API
 #define EXPORT_API __attribute__((visibility("default")))
 
@@ -46,9 +48,13 @@ class EXPORT_API PollFd : public std::enable_shared_from_this<PollFd> {
   void RefSelf();
   void UnrefSelf();
 
+  void SetSource(ISource* source);
+  ISource* GetSource() const;
+
  private:
   GPollFD gpollfd_ = { -1, 0, 0 };
   std::shared_ptr<PollFd> self_;
+  ISource* source_ = nullptr;
 };
 
 }  // namespace tizen_core
index 8f90920fd1e947af272e0c3759dadf73c6a64f30..b10155032a064336dbd611fb7611398af06e9307 100644 (file)
@@ -80,12 +80,13 @@ Source::Source() {
 
 Source::~Source() {
   if (handle_ != nullptr) {
-    GSList* iter = handle_->poll_fds;
-    while (iter != nullptr) {
-      auto* poll_fd = static_cast<GPollFD*>(iter->data);
-      iter = iter->next;
-      g_source_remove_poll(handle_, poll_fd);
-      g_free(poll_fd);
+    auto iter = poll_fds_.begin();
+    while (iter != poll_fds_.end()) {
+      auto& poll_fd = *iter;
+      poll_fd->SetSource(nullptr);
+      g_source_remove_poll(handle_,
+                           const_cast<GPollFD*>(poll_fd->GetGPollFD()));
+      iter = poll_fds_.erase(iter);
     }
 
     if (!g_source_is_destroyed(handle_))
@@ -95,15 +96,17 @@ Source::~Source() {
   }
 }
 
-void Source::AddPoll(PollFd* poll_fd) {
-  _D("AddPoll(). PollFd=%p", poll_fd);
+void Source::AddPoll(std::shared_ptr<PollFd> poll_fd) {
+  _D("AddPoll(). PollFd=%p", poll_fd.get());
   g_source_add_poll(handle_, const_cast<GPollFD*>(poll_fd->GetGPollFD()));
+  poll_fd->SetSource(this);
   g_source_set_callback(handle_, nullptr, this, nullptr);
-  poll_fds_.push_back(poll_fd);
+  poll_fds_.push_back(std::move(poll_fd));
 }
 
-void Source::RemovePoll(PollFd* poll_fd) {
-  _D("RemovePoll(). PollFd=%p", poll_fd);
+void Source::RemovePoll(const std::shared_ptr<PollFd>& poll_fd) {
+  _D("RemovePoll(). PollFd=%p", poll_fd.get());
+  poll_fd->SetSource(nullptr);
   g_source_remove_poll(handle_, const_cast<GPollFD*>(poll_fd->GetGPollFD()));
   auto found = std::find(poll_fds_.begin(), poll_fds_.end(), poll_fd);
   if (found == poll_fds_.end()) return;
@@ -134,10 +137,6 @@ void Source::SetPriority(int priority) {
   g_source_set_priority(handle_, priority);
 }
 
-const std::vector<PollFd*>& Source::GetPollFds() const {
-  return poll_fds_;
-}
-
 bool Source::OnSourcePrepare(int* timeout) { return false; }
 
 bool Source::OnSourceCheck() { return false; }
index dde9d7c654924f9c4838ee6c1814eddc0c299db0..aa27536ca1dae210947645fef48a5a96070ef7ec 100644 (file)
@@ -39,15 +39,14 @@ class EXPORT_API Source : public ISource,
   explicit Source(GSource* handle);
   virtual ~Source();
 
-  void AddPoll(PollFd* poll_fd);
-  void RemovePoll(PollFd* poll_fd);
+  void AddPoll(std::shared_ptr<PollFd> poll_fd) override;
+  void RemovePoll(const std::shared_ptr<PollFd>& poll_fd) override;
   void Attach(const std::shared_ptr<Context>& context) override;
   bool IsAttached() const;
   GSource* GetHandle() const;
   void RefSelf() override;
   void UnrefSelf() override;
   void SetPriority(int priority);
-  const std::vector<PollFd*>& GetPollFds() const;
 
   virtual bool OnSourcePrepare(int* timeout);
   virtual bool OnSourceCheck();
@@ -65,7 +64,7 @@ class EXPORT_API Source : public ISource,
   GSource* handle_ = nullptr;
   bool attached_ = false;
   std::shared_ptr<Source> self_;
-  std::vector<PollFd*> poll_fds_;
+  std::vector<std::shared_ptr<PollFd>> poll_fds_;
 };
 
 }  // namespace tizen_core
index 7a1c5e43d809c6ed8732236e1c428e80199c986e..252935ea8e35f860e4e041bfc4d7d8b1fd5e0c90 100644 (file)
@@ -431,7 +431,13 @@ API int tizen_core_source_add_poll(tizen_core_source_h h,
   }
 
   auto* source = static_cast<SourceExt*>(h);
-  source->AddPoll(static_cast<tizen_base::tizen_core::PollFd*>(poll_fd));
+  auto* pollfd = static_cast<tizen_base::tizen_core::PollFd*>(poll_fd);
+  if (pollfd->GetSource() != nullptr) {
+    _E("Invalid context");
+    return TIZEN_CORE_ERROR_INVALID_CONTEXT;
+  }
+
+  source->AddPoll(pollfd->shared_from_this());
   return TIZEN_CORE_ERROR_NONE;
 }
 
@@ -443,7 +449,14 @@ API int tizen_core_source_remove_poll(tizen_core_source_h h,
   }
 
   auto* source = static_cast<SourceExt*>(h);
-  source->RemovePoll(static_cast<tizen_base::tizen_core::PollFd*>(poll_fd));
+  auto* pollfd = static_cast<tizen_base::tizen_core::PollFd*>(poll_fd);
+  if (pollfd->GetSource() == nullptr) {
+    _E("Invalid context");
+    return TIZEN_CORE_ERROR_INVALID_CONTEXT;
+  }
+
+  auto pollfd_ptr = pollfd->shared_from_this();
+  source->RemovePoll(pollfd_ptr);
   return TIZEN_CORE_ERROR_NONE;
 }
 
@@ -523,22 +536,6 @@ API int tizen_core_source_set_priority(tizen_core_source_h h,
   return TIZEN_CORE_ERROR_NONE;
 }
 
-API int tizen_core_source_get_poll_fds(tizen_core_source_h h,
-                                       tizen_core_poll_fd_h* poll_fds,
-                                       unsigned int* length) {
-  if (h == nullptr || poll_fds == nullptr || length == nullptr) {
-    _E("Invalid parameter");
-    return TIZEN_CORE_ERROR_INVALID_PARAMETER;
-  }
-
-  auto* source = static_cast<SourceExt*>(h);
-  auto& fds = source->GetPollFds();
-  *poll_fds = static_cast<tizen_core_poll_fd_h>(
-      const_cast<tizen_base::tizen_core::PollFd**>(fds.data()));
-  *length = fds.size();
-  return TIZEN_CORE_ERROR_NONE;
-}
-
 API int tizen_core_poll_fd_create(tizen_core_poll_fd_h* h) {
   if (h == nullptr) {
     _E("Invalid parameter");