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>
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;
};
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
#include <memory>
+#include "tizen_base/interface_source.h"
+
#undef EXPORT_API
#define EXPORT_API __attribute__((visibility("default")))
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
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_))
}
}
-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;
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; }
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();
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
}
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;
}
}
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;
}
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");