The rpc-port was used the GDBusConnection to notify the presence of debug port.
After this patch is applied, the rpc-port library doesn't use the GDBusConnection.
The thread of the debug-port tries to connect to the debug port of the tool
automatically if it's not connected.
Change-Id: Ife29d7960360e9da21819b16993d406750a4d990
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
namespace {
const char PATH_RPC_PORT_UTIL_SOCK[] = "/run/aul/daemons/.rpc-port-util-sock";
-const char RPC_PORT_SIGNAL_PATH[] = "/Org/Tizen/RPC/Port/Signal";
-const char RPC_PORT_SIGNAL_INTERFACE[] = "org.tizen.rpc.port.signal";
-const char RPC_PORT_SIGNAL_DEBUG[] = "Debug";
-const char RPC_PORT_SIGNAL_NEW[] = "New";
} // namespace
std::atomic<DebugPort*> DebugPort::inst_;
void DebugPort::Dispose() {
Unwatch();
- Unsubscribe();
JoinThread();
disposed_ = true;
}
int DebugPort::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 -1;
-
auto session = FindSession(port);
if (session.get() == nullptr) {
_E("Failed to find session. port(%d)", port);
}
void DebugPort::Init() {
- Subscribe();
- EmitSignal(RPC_PORT_SIGNAL_NEW);
- is_running_ = false;
+ CreateThread();
disposed_ = false;
}
}
void DebugPort::Unwatch() {
- if (watch_tag_) {
- g_source_remove(watch_tag_);
- watch_tag_ = 0;
- }
-
if (io_) {
g_io_channel_unref(io_);
io_ = nullptr;
}
+
+ if (watch_tag_) {
+ g_source_remove(watch_tag_);
+ watch_tag_ = 0;
+ }
}
gboolean DebugPort::OnDebugPortDisconnectedCb(GIOChannel* io,
return G_SOURCE_REMOVE;
}
-GDBusConnection* DebugPort::GetConnection() {
- if (conn_)
- return conn_;
-
- GError* error = nullptr;
- conn_ = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &error);
- if (conn_ == nullptr) {
- _E("g_bus_get_sync() is failed. error(%s)",
- error ? error->message : "unknown");
- g_clear_error(&error);
- return nullptr;
- }
-
- return conn_;
-}
-
-void DebugPort::Subscribe() {
- GDBusConnection* conn = GetConnection();
- if (conn == nullptr)
- return;
-
- subs_tag_ = g_dbus_connection_signal_subscribe(conn,
- nullptr,
- RPC_PORT_SIGNAL_INTERFACE,
- RPC_PORT_SIGNAL_DEBUG,
- RPC_PORT_SIGNAL_PATH,
- nullptr,
- G_DBUS_SIGNAL_FLAGS_NONE,
- OnGDBusSignalCb,
- this,
- nullptr);
- if (subs_tag_ == 0) {
- _E("g_dbus_connection_signal_subscribe() is failed");
- return;
- }
-
- _D("tag(%u)", subs_tag_);
-}
-
-void DebugPort::Unsubscribe() {
- if (subs_tag_)
- g_dbus_connection_signal_unsubscribe(conn_, subs_tag_);
-
- if (conn_)
- g_object_unref(conn_);
-}
-
-void DebugPort::EmitSignal(std::string signal) {
- GDBusConnection* conn = GetConnection();
- if (conn == nullptr)
- return;
-
- GError* error = nullptr;
- gboolean ret = g_dbus_connection_emit_signal(conn,
- nullptr,
- RPC_PORT_SIGNAL_PATH,
- RPC_PORT_SIGNAL_INTERFACE,
- signal.c_str(),
- nullptr,
- &error);
- if (ret != TRUE) {
- _E("g_dbus_connection_emit_signal() is failed. error(%s)",
- error ? error->message : "unknown");
- g_clear_error(&error);
- return;
- }
-
- ret = g_dbus_connection_flush_sync(conn, nullptr, &error);
- if (ret != TRUE) {
- _E("g_dbus_connection_flush_sync() is failed. error(%s)",
- error ? error->message : "unknown");
- g_clear_error(&error);
- return;
- }
-
- _W("EmitSignal(%s)", signal.c_str());
-}
-
-void DebugPort::OnGDBusSignalCb(GDBusConnection *connection,
- const gchar* sender_name,
- const gchar* object_path,
- const gchar* interface_name,
- const gchar* signal_name,
- GVariant* parameters,
- gpointer user_data) {
- _W("signal_name(%s)", signal_name);
- std::string signal(signal_name);
- if (signal != RPC_PORT_SIGNAL_DEBUG)
- return;
-
- gchar* port_name = nullptr;
- gint pid = -1;
- g_variant_get(parameters, "(&si)", &port_name, &pid);
- _W("port_name(%s), pid(%d)", port_name, pid);
-
- if (pid != 0 && pid != getpid()) {
- _W("Invalid pid(%d)", pid);
- return;
- }
-
- auto* debug_port = static_cast<DebugPort*>(user_data);
- int fd = debug_port->Connect();
- if (fd < 0)
- return;
-
- std::lock_guard<std::recursive_mutex> lock(debug_port->GetMutex());
- debug_port->port_.reset(new Port(fd, signal));
- int ret = debug_port->Watch(fd);
- if (ret < 0)
- return;
-
- debug_port->CreateThread();
- debug_port->SetConnectionStatus(true);
- _W("Connected");
-}
-
void DebugPort::SetConnectionStatus(bool status) {
std::lock_guard<std::recursive_mutex> lock(GetMutex());
connected_ = status;
break;
}
- if (!IsConnected())
- continue;
+ if (!IsConnected()) {
+ int fd = Connect();
+ if (fd < 0)
+ continue;
+
+ {
+ std::lock_guard<std::recursive_mutex> lock(GetMutex());
+ port_.reset(new Port(fd, "Debug"));
+ int ret = Watch(fd);
+ if (ret < 0)
+ continue;
+
+ SetConnectionStatus(true);
+ _W("Connected");
+ }
+ }
int ret = port_->Write(reinterpret_cast<void*>(&len), sizeof(len));
if (ret < 0) {
int Connect();
int Watch(int fd);
void Unwatch();
- GDBusConnection* GetConnection();
- void Subscribe();
- void Unsubscribe();
- void EmitSignal(std::string signal);
void SetConnectionStatus(bool status);
void CreateThread();
void JoinThread();
static gboolean OnDebugPortDisconnectedCb(GIOChannel* io,
GIOCondition cond, gpointer data);
- static void OnGDBusSignalCb(GDBusConnection *connection,
- const gchar* sender_name,
- const gchar* object_path,
- const gchar* interface_name,
- const gchar* signal_name,
- GVariant* parameters,
- gpointer user_data);
private:
bool disposed_ = true;
bool connected_ = false;
- GDBusConnection* conn_ = nullptr;
- guint subs_tag_ = 0;
std::unique_ptr<Port> port_;
GIOChannel* io_ = nullptr;
guint watch_tag_ = 0;
namespace rpc_port {
namespace util {
+namespace {
-static const char PATH_RPC_PORT_UTIL_SOCK[] =
+constexpr const char PATH_RPC_PORT_UTIL_SOCK[] =
"/run/aul/daemons/.rpc-port-util-sock";
-static const char RPC_PORT_SIGNAL_PATH[] = "/Org/Tizen/RPC/Port/Signal";
-static const char RPC_PORT_SIGNAL_INTERFACE[] = "org.tizen.rpc.port.signal";
-static const char RPC_PORT_SIGNAL_DEBUG[] = "Debug";
-static const char RPC_PORT_SIGNAL_NEW[] = "New";
+
+} // namespace
class DisconnectedEvent {
public:
DebugPort::DebugPort(std::string port_name, int pid)
: port_name_(std::move(port_name)),
pid_(pid) {
- Subscribe();
-
int fd = CreateSocket();
if (fd < 0) {
_E("Failed to create socket");
if (fd_ > 0)
close(fd_);
-
- Unsubscribe();
-}
-
-void DebugPort::EmitSignal() {
- GDBusConnection* conn = GetConnection();
- if (conn == nullptr)
- return;
-
- GError* error = nullptr;
- gboolean ret = g_dbus_connection_emit_signal(conn,
- nullptr,
- RPC_PORT_SIGNAL_PATH,
- RPC_PORT_SIGNAL_INTERFACE,
- RPC_PORT_SIGNAL_DEBUG,
- g_variant_new("(si)", port_name_.c_str(), pid_),
- &error);
- if (ret != TRUE) {
- _E("g_dbus_connection_emit_signal() is failed. error(%s)",
- error ? error->message : "Unknown");
- g_clear_error(&error);
- return;
- }
-
- ret = g_dbus_connection_flush_sync(conn, nullptr, &error);
- if (ret != TRUE) {
- _E("g_dbus_connection_flush_sync() is failed. error(%s)",
- error ? error->message : "Unknown");
- g_clear_error(&error);
- return;
- }
-
- _W("EmitSignal");
-}
-
-GDBusConnection* DebugPort::GetConnection() {
- if (conn_)
- return conn_;
-
- GError* error = nullptr;
- conn_ = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &error);
- if (conn_ == nullptr) {
- _E("g_bus_get_sync() is failed. error(%s)",
- error ? error->message : "Unknown");
- g_clear_error(&error);
- return nullptr;
- }
-
- return conn_;
-}
-
-void DebugPort::Subscribe() {
- GDBusConnection* conn = GetConnection();
- if (conn == nullptr)
- return;
-
- subs_tag_ = g_dbus_connection_signal_subscribe(conn,
- nullptr,
- RPC_PORT_SIGNAL_INTERFACE,
- RPC_PORT_SIGNAL_NEW,
- RPC_PORT_SIGNAL_PATH,
- nullptr,
- G_DBUS_SIGNAL_FLAGS_NONE,
- OnGDBusSignalCb,
- this,
- nullptr);
- if (subs_tag_ == 0) {
- _E("g_dbus_connection_signal_subscribe() is failed");
- return;
- }
-
- _W("tag(%u)", subs_tag_);
-}
-
-void DebugPort::Unsubscribe() {
- if (subs_tag_)
- g_dbus_connection_signal_unsubscribe(conn_, subs_tag_);
-
- if (conn_)
- g_object_unref(conn_);
}
int DebugPort::CreateSocket() {
}, event);
}
-void DebugPort::OnGDBusSignalCb(GDBusConnection *connection,
- const gchar* sender_name,
- const gchar* object_path,
- const gchar* interface_name,
- const gchar* signal_name,
- GVariant* parameters,
- gpointer user_data) {
- _E("signal_name(%s)", signal_name);
- std::string signal(signal_name);
- if (signal != RPC_PORT_SIGNAL_NEW)
- return;
-
- auto* debug_port = static_cast<DebugPort*>(user_data);
- debug_port->EmitSignal();
-}
-
int DebugPort::Watch(int fd) {
GIOChannel* io = g_io_channel_unix_new(fd);
if (io == nullptr) {
DebugPort(std::string port_name, int pid);
virtual ~DebugPort();
- void EmitSignal();
-
private:
- GDBusConnection* GetConnection();
- void Subscribe();
- void Unsubscribe();
int CreateSocket();
int Watch(int fd);
void Unwatch();
void OnDataReceived(int pid, rpc_port_parcel_h parcel) override;
void OnDisconnected(int pid, int fd) override;
- static void OnGDBusSignalCb(GDBusConnection *connection,
- const gchar* sender_name,
- const gchar* object_path,
- const gchar* interface_name,
- const gchar* signal_name,
- GVariant* parameters,
- gpointer user_data);
static gboolean OnDebugPortConnectedCb(GIOChannel* io,
GIOCondition cond,
gpointer data);
private:
std::string port_name_;
int pid_;
- GDBusConnection* conn_ = nullptr;
- guint subs_tag_ = 0;
int fd_ = -1;
GIOChannel* io_ = nullptr;
guint watch_tag_ = 0;
}
DebugPort debug_port(options->GetPortName(), options->GetPid());
- debug_port.EmitSignal();
-
MainLoop loop;
loop.Run();
-
return 0;
}