#include "debug-port-internal.hh"
+#include <aul_app_com.h>
#include <bundle_internal.h>
+#include <gio/gio.h>
+#include <glib.h>
#include <parcel.hh>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <time.h>
+#include <atomic>
+#include <list>
+#include <memory>
+#include <mutex>
+#include <thread>
#include <utility>
#include "log-private.hh"
-
-#undef RPC_DTOR
-#define RPC_DTOR __attribute__ ((destructor))
+#include "port-internal.hh"
+#include "shared-queue-internal.hh"
namespace rpc_port {
namespace internal {
-
namespace {
constexpr const char PATH_RPC_PORT_UTIL_SOCK[] =
constexpr const char ENDPOINT_RPC_PORT_DEBUG[] = "org.tizen.rpcport.debug";
constexpr const char KEY_PORT_NAME[] = "__K_PORT_NAME__";
-RPC_DTOR void DebugPortDtor() {
- DebugPort::GetInst()->Dispose(false);
-}
-
-} // namespace
+class Session {
+ public:
+ Session(std::string port_name, std::string destination,
+ int main_port, int delegate_port)
+ : port_name_(std::move(port_name)),
+ destination_(std::move(destination)),
+ main_port_(main_port),
+ delegate_port_(delegate_port) {
+ }
-std::atomic<DebugPort*> DebugPort::inst_;
-std::mutex DebugPort::mutex_;
+ const std::string& GetPortName() const {
+ return port_name_;
+ }
-DebugPort::~DebugPort() {
- Dispose();
-}
+ const std::string& GetDestination() const {
+ return destination_;
+ }
-DebugPort* DebugPort::GetInst() {
- DebugPort* inst = inst_.load(std::memory_order_acquire);
- if (inst == nullptr) {
- std::lock_guard<std::mutex> lock(mutex_);
- inst = inst_.load(std::memory_order_relaxed);
- if (inst == nullptr) {
- inst = new DebugPort();
- inst_.store(inst, std::memory_order_release);
- }
+ int GetMainPort() const {
+ return main_port_;
}
- std::lock_guard<std::recursive_mutex> rec_lock(inst->GetMutex());
- if (inst->disposed_)
- inst->Init();
+ int GetDelegatePort() const {
+ return delegate_port_;
+ }
- return inst;
+ private:
+ std::string port_name_;
+ std::string destination_;
+ int main_port_;
+ int delegate_port_;
+};
+
+class DebugPortImpl {
+ public:
+ DebugPortImpl() = default;
+ ~DebugPortImpl();
+
+ void Dispose();
+ bool IsConnected() const;
+ void AddSession(std::string port_name, std::string destination,
+ int main_port, int delegate_port);
+ void RemoveSession(int port);
+ int Send(int port, bool is_read, uint32_t seq,
+ const void* buf, unsigned int size);
+ void Init();
+
+ private:
+ int Connect();
+ int Watch(int fd);
+ void Unwatch();
+ void SetConnectionStatus(bool status);
+ void CreateThread();
+ void JoinThread();
+
+ std::recursive_mutex& GetMutex() const;
+ std::shared_ptr<Session> FindSession(int port);
+ std::shared_ptr<Session> FindSession(const std::string& port_name);
+
+ static gboolean OnDebugPortDisconnectedCb(GIOChannel* io,
+ GIOCondition cond, gpointer data);
+ static int AppComCb(const char* endpoint, aul_app_com_result_e result,
+ bundle* envelope, void* user_data);
+
+ private:
+ bool disposed_ = true;
+ std::atomic<bool> connected_;
+ std::unique_ptr<Port> port_;
+ GIOChannel* io_ = nullptr;
+ guint watch_tag_ = 0;
+ std::list<std::shared_ptr<Session>> sessions_;
+ std::thread thread_;
+ std::atomic<bool> is_running_;
+ SharedQueue<std::shared_ptr<tizen_base::Parcel>> queue_;
+ mutable std::recursive_mutex mutex_;
+ aul_app_com_connection_h conn_ = nullptr;
+};
+
+DebugPortImpl::~DebugPortImpl() {
+ Dispose();
}
-void DebugPort::Dispose(bool do_leave) {
+void DebugPortImpl::Dispose() {
std::lock_guard<std::recursive_mutex> lock(GetMutex());
if (disposed_)
return;
- if (do_leave && conn_) {
+ if (conn_) {
aul_app_com_leave(conn_);
conn_ = nullptr;
}
disposed_ = true;
}
-bool DebugPort::IsConnected() {
- std::lock_guard<std::recursive_mutex> lock(GetMutex());
+bool DebugPortImpl::IsConnected() const {
return connected_;
}
-void DebugPort::AddSession(std::string port_name, std::string destination,
+void DebugPortImpl::AddSession(std::string port_name, std::string destination,
int main_port, int delegate_port) {
std::lock_guard<std::recursive_mutex> lock(GetMutex());
sessions_.emplace_back(
- new DebugPort::Session(std::move(port_name), std::move(destination),
- main_port, delegate_port));
+ new Session(std::move(port_name), std::move(destination),
+ main_port, delegate_port));
}
-void DebugPort::RemoveSession(int port) {
+void DebugPortImpl::RemoveSession(int port) {
std::lock_guard<std::recursive_mutex> lock(GetMutex());
auto iter = std::find_if(sessions_.begin(), sessions_.end(),
- [port](std::shared_ptr<DebugPort::Session>& sess) -> bool {
+ [port](std::shared_ptr<Session>& sess) -> bool {
return sess->GetMainPort() == port || sess->GetDelegatePort() == port;
});
}
}
-std::shared_ptr<DebugPort::Session> DebugPort::FindSession(int port) {
+std::shared_ptr<Session> DebugPortImpl::FindSession(int port) {
std::lock_guard<std::recursive_mutex> lock(GetMutex());
for (auto& s : sessions_) {
if (s->GetMainPort() == port || s->GetDelegatePort() == port)
return nullptr;
}
-std::shared_ptr<DebugPort::Session> DebugPort::FindSession(
+std::shared_ptr<Session> DebugPortImpl::FindSession(
const std::string& port_name) {
std::lock_guard<std::recursive_mutex> lock(GetMutex());
for (auto& s : sessions_) {
return nullptr;
}
-int DebugPort::Send(int port, bool is_read, uint32_t seq,
+int DebugPortImpl::Send(int port, bool is_read, uint32_t seq,
const void* buf, unsigned int size) {
- std::lock_guard<std::recursive_mutex> lock(GetMutex());
if (!IsConnected())
return 0;
return 0;
}
-void DebugPort::Init() {
+void DebugPortImpl::Init() {
+ if (!disposed_)
+ return;
+
+ std::lock_guard<std::recursive_mutex> lock(GetMutex());
aul_app_com_create_async(ENDPOINT_RPC_PORT_DEBUG, nullptr, AppComCb, this,
&conn_);
if (conn_ == nullptr)
disposed_ = false;
}
-int DebugPort::Connect() {
+int DebugPortImpl::Connect() {
if (access(PATH_RPC_PORT_UTIL_SOCK, F_OK) != 0)
return -1;
return fd;
}
-int DebugPort::Watch(int fd) {
+int DebugPortImpl::Watch(int fd) {
GIOChannel* io = g_io_channel_unix_new(fd);
if (io == nullptr) {
_E("g_io_channel_unix_new() is failed");
return 0;
}
-void DebugPort::Unwatch() {
+void DebugPortImpl::Unwatch() {
if (io_) {
g_io_channel_unref(io_);
io_ = nullptr;
}
}
-gboolean DebugPort::OnDebugPortDisconnectedCb(GIOChannel* io,
+gboolean DebugPortImpl::OnDebugPortDisconnectedCb(GIOChannel* io,
GIOCondition cond, gpointer data) {
_W("cond(%d)", static_cast<int>(cond));
- auto* debug_port = static_cast<DebugPort*>(data);
+ auto* debug_port = static_cast<DebugPortImpl*>(data);
std::lock_guard<std::recursive_mutex> lock(debug_port->GetMutex());
debug_port->SetConnectionStatus(false);
debug_port->watch_tag_ = 0;
return G_SOURCE_REMOVE;
}
-void DebugPort::SetConnectionStatus(bool status) {
- std::lock_guard<std::recursive_mutex> lock(GetMutex());
- connected_ = status;
+void DebugPortImpl::SetConnectionStatus(bool status) {
+ connected_.exchange(status);
}
-void DebugPort::CreateThread() {
+void DebugPortImpl::CreateThread() {
if (is_running_)
return;
is_running_ = true;
}
-void DebugPort::JoinThread() {
+void DebugPortImpl::JoinThread() {
if (is_running_)
queue_.Push(std::shared_ptr<tizen_base::Parcel>(new tizen_base::Parcel()));
}
}
-int DebugPort::AppComCb(const char* endpoint, aul_app_com_result_e result,
+
+std::recursive_mutex& DebugPortImpl::GetMutex() const {
+ return mutex_;
+}
+
+int DebugPortImpl::AppComCb(const char* endpoint, aul_app_com_result_e result,
bundle* envelope, void* user_data) {
const char* val = bundle_get_val(envelope, KEY_PORT_NAME);
if (val == nullptr)
return -1;
- auto* handle = static_cast<DebugPort*>(user_data);
+ auto* handle = static_cast<DebugPortImpl*>(user_data);
std::string port_name(val);
if (port_name.empty() || handle->FindSession(port_name) != nullptr) {
- auto* handle = static_cast<DebugPort*>(user_data);
+ auto* handle = static_cast<DebugPortImpl*>(user_data);
int fd = handle->Connect();
if (fd < 0)
return -1;
return 0;
}
+DebugPortImpl impl;
+
+} // namespace
+
+bool DebugPort::IsConnected() {
+ impl.Init();
+ return impl.IsConnected();
+}
+
+void DebugPort::AddSession(std::string port_name, std::string destination,
+ int main_port, int delegate_port) {
+ impl.Init();
+ return impl.AddSession(std::move(port_name), std::move(destination),
+ main_port, delegate_port);
+}
+
+void DebugPort::RemoveSession(int port) {
+ impl.Init();
+ return impl.RemoveSession(port);
+}
+
+int DebugPort::Send(int port, bool is_read, uint32_t seq, const void* buf,
+ unsigned int size) {
+ impl.Init();
+ return impl.Send(port, is_read, seq, buf, size);
+}
+
} // namespace internal
} // namespace rpc_port
#ifndef DEBUG_PORT_INTERNAL_HH_
#define DEBUG_PORT_INTERNAL_HH_
-#include <aul_app_com.h>
-#include <gio/gio.h>
-#include <glib.h>
-#include <parcel.hh>
-
-#include <atomic>
-#include <list>
-#include <memory>
-#include <mutex>
#include <string>
-#include <thread>
-#include <utility>
-
-#include "port-internal.hh"
-#include "shared-queue-internal.hh"
namespace rpc_port {
namespace internal {
class DebugPort {
- private:
- DebugPort() = default;
- ~DebugPort();
-
public:
- class Session {
- public:
- Session(std::string port_name, std::string destination,
- int main_port, int delegate_port)
- : port_name_(std::move(port_name)),
- destination_(std::move(destination)),
- main_port_(main_port),
- delegate_port_(delegate_port) {
- }
- virtual ~Session() = default;
-
- const std::string& GetPortName() {
- return port_name_;
- }
-
- const std::string& GetDestination() {
- return destination_;
- }
-
- int GetMainPort() {
- return main_port_;
- }
-
- int GetDelegatePort() {
- return delegate_port_;
- }
-
- private:
- std::string port_name_;
- std::string destination_;
- int main_port_;
- int delegate_port_;
- };
-
- static DebugPort* GetInst();
-
- void Dispose(bool do_leave = true);
- bool IsConnected();
-
- void AddSession(std::string port_name, std::string destination,
+ static bool IsConnected();
+ static void AddSession(std::string port_name, std::string destination,
int main_port, int delegate_port);
- void RemoveSession(int port);
-
- int Send(int port, bool is_read, uint32_t seq,
+ static void RemoveSession(int port);
+ static int Send(int port, bool is_read, uint32_t seq,
const void* buf, unsigned int size);
-
- private:
- static std::atomic<DebugPort*> inst_;
- static std::mutex mutex_;
-
- std::recursive_mutex& GetMutex() const {
- return rec_mutex_;
- }
-
- void Init();
- int Connect();
- int Watch(int fd);
- void Unwatch();
- void SetConnectionStatus(bool status);
- void CreateThread();
- void JoinThread();
-
- std::shared_ptr<DebugPort::Session> FindSession(int port);
- std::shared_ptr<DebugPort::Session> FindSession(const std::string& port_name);
-
- static gboolean OnDebugPortDisconnectedCb(GIOChannel* io,
- GIOCondition cond, gpointer data);
- static int AppComCb(const char* endpoint, aul_app_com_result_e result,
- bundle* envelope, void* user_data);
-
- private:
- bool disposed_ = true;
- bool connected_ = false;
- std::unique_ptr<Port> port_;
- GIOChannel* io_ = nullptr;
- guint watch_tag_ = 0;
- std::list<std::shared_ptr<DebugPort::Session>> sessions_;
- std::thread thread_;
- std::atomic<bool> is_running_;
- SharedQueue<std::shared_ptr<tizen_base::Parcel>> queue_;
- mutable std::recursive_mutex rec_mutex_;
- aul_app_com_connection_h conn_ = nullptr;
};
} // namespace internal
std::lock_guard<std::recursive_mutex> lock(GetMutex());
_D("Proxy::~Proxy()");
if (main_port_.get() != nullptr)
- DebugPort::GetInst()->RemoveSession(main_port_->GetFd());
+ DebugPort::RemoveSession(main_port_->GetFd());
listener_ = nullptr;
UnsetIdler();
main_port_.reset(new ProxyPort(this, fds_[0], target_appid_, false));
delegate_port_.reset(new ProxyPort(this, fds_[1], target_appid_));
- DebugPort::GetInst()->AddSession(port_name, target_appid_, fds_[0], fds_[1]);
+ DebugPort::AddSession(port_name, target_appid_, fds_[0], fds_[1]);
listener_->OnConnected(target_appid_, main_port_.get());
return RPC_PORT_ERROR_NONE;
}
void Proxy::DisconnectPort() {
std::lock_guard<std::recursive_mutex> lock(GetMutex());
if (main_port_.get() != nullptr) {
- DebugPort::GetInst()->RemoveSession(main_port_->GetFd());
+ DebugPort::RemoveSession(main_port_->GetFd());
main_port_.reset();
}
}
proxy->delegate_port_.reset();
proxy->listener_ = nullptr;
listener->OnDisconnected(proxy->target_appid_);
- DebugPort::GetInst()->RemoveSession(fd);
+ DebugPort::RemoveSession(fd);
return G_SOURCE_REMOVE;;
}
proxy->listener_ = nullptr;
proxy->delegate_port_->SetSource(0);
if (proxy->main_port_.get() != nullptr) {
- DebugPort::GetInst()->RemoveSession(proxy->main_port_->GetFd());
+ DebugPort::RemoveSession(proxy->main_port_->GetFd());
proxy->main_port_.reset();
}
proxy->delegate_port_.reset();
proxy->fds_[1] = client_fd;
proxy->delegate_port_.reset(
new ProxyPort(proxy, proxy->fds_[1], proxy->target_appid_));
- DebugPort::GetInst()->AddSession(proxy->port_name_, proxy->target_appid_,
+ DebugPort::AddSession(proxy->port_name_, proxy->target_appid_,
proxy->fds_[0], proxy->fds_[1]);
listener->OnConnected(proxy->target_appid_, proxy->main_port_.get());
_W("target_appid(%s), port_name(%s), main_fd(%d), delegate_fd(%d)",