constexpr const char SYS_EVENT_NAME_PREFIX[] = "tizen.system.event";
-std::unique_ptr<rpc_proxy::EventSystem> es_proxy_;
+std::future<void> connection_fut_;
+
+std::shared_ptr<rpc_proxy::EventSystem> es_proxy_;
class Event : public rpc_proxy::EventSystem::EventListener {
public:
class ESConnection : public rpc_proxy::EventSystem::IEventListener {
public:
void OnConnected() override {
- connected_ = true;
_D("OnConnected");
}
/* LCOV_EXCL_START */
void OnDisconnected() override {
- connected_ = false;
- es_proxy_.reset();
_E("OnDisconnected");
+ es_proxy_.reset();
}
void OnRejected() override {
- es_proxy_.reset();
_E("OnRejected");
+ es_proxy_.reset();
}
/* LCOV_EXCL_STOP */
- bool IsConnected() const { return connected_; }
-
- void Reset() { connected_ = false; }
-
- private:
- bool connected_ = false;
} connection_listener_;
-std::future<void> connection_fut_;
-
void Connect() {
- if (!es_proxy_) {
+ if (!es_proxy_ ) {
es_proxy_.reset(new rpc_proxy::EventSystem(
&connection_listener_, "d::org.tizen.appfw.service.esd"));
- connection_fut_ =
- std::async(std::launch::async, []() { es_proxy_->Connect(true); });
+ connection_fut_ = std::async(std::launch::async, [p = es_proxy_]() mutable {
+ p->Connect(true);
+ p.reset();
+ });
}
connection_fut_.wait();
auto ev = std::unique_ptr<rpc_proxy::EventSystem::EventListener>(
new Event(callback, user_data));
- if (!connection_listener_.IsConnected() && ::IsReservedEvent(name)) {
+ if (::IsReservedEvent(name) && !es_proxy_) {
_W("Connect Asynchronously");
- bool first_time = false;
- if (!es_proxy_) {
- es_proxy_.reset(new rpc_proxy::EventSystem(
- &connection_listener_, "d::org.tizen.appfw.service.esd"));
- first_time = true;
- }
+ es_proxy_.reset(new rpc_proxy::EventSystem(
+ &connection_listener_, "d::org.tizen.appfw.service.esd"));
*reg_id = ev->GetSeqId();
es_proxy_->AddAsyncEventList(name, std::move(ev));
*event_type = ::GetEventType(name);
- if (first_time) {
- connection_fut_ =
- std::async(std::launch::async, []() { es_proxy_->Connect(true); });
- }
+ connection_fut_ =
+ std::async(std::launch::async, [p = es_proxy_]() mutable {
+ p->Connect(true);
+ p.reset();
+ });
return ES_R_OK;
}
extern "C" EXPORT_API int eventsystem_application_finalize() {
if (!es_proxy_) return 0;
- es_proxy_->Disconnect();
es_proxy_.reset();
- connection_listener_.Reset();
return 0;
}
if (es_proxy_->GetSizeAsyncEventList() == 0) {
es_proxy_.reset();
- connection_listener_.Reset();
- es_proxy_ = nullptr;
}
return ES_R_OK;
}
LocalExecution::~LocalExecution() {
+ std::lock_guard<std::recursive_mutex> lock(mutex_q_);
while (!result_queue_.empty()) {
auto parcel = result_queue_.front();
result_queue_.pop();
reinterpret_cast<StubConnectFunc>(dlsym(RTLD_DEFAULT, symbol.c_str()));
if (connect_func_ == nullptr) {
_E("Failed to find symbol(%s)", symbol.c_str()); /* LCOV_EXCL_LINE */
- return false; /* LCOV_EXCL_LINE */
+ return false; /* LCOV_EXCL_LINE */
}
}
dlsym(RTLD_DEFAULT, symbol.c_str()));
if (disconnect_func_ == nullptr) {
_E("Failed to find symbol(%s)", symbol.c_str()); /* LCOV_EXCL_LINE */
- return false; /* LCOV_EXCL_LINE */
+ return false; /* LCOV_EXCL_LINE */
}
}
reinterpret_cast<StubSendFunc>(dlsym(RTLD_DEFAULT, symbol.c_str()));
if (send_func_ == nullptr) {
_E("Failed to find symbol(%s)", symbol.c_str()); /* LCOV_EXCL_LINE */
- return false; /* LCOV_EXCL_LINE */
+ return false; /* LCOV_EXCL_LINE */
}
}
}
void LocalExecution::ResultQueuePush(rpc_port_parcel_h parcel) {
- std::lock_guard<std::recursive_mutex> lock(mutex_);
+ std::lock_guard<std::recursive_mutex> lock(mutex_q_);
result_queue_.push(parcel);
}
rpc_port_parcel_h LocalExecution::ResultQueuePop() {
- std::lock_guard<std::recursive_mutex> lock(mutex_);
+ std::lock_guard<std::recursive_mutex> lock(mutex_q_);
auto parcel = result_queue_.front();
result_queue_.pop();
return parcel;
}
bool LocalExecution::ResultQueueEmpty() const {
- std::lock_guard<std::recursive_mutex> lock(mutex_);
+ std::lock_guard<std::recursive_mutex> lock(mutex_q_);
return result_queue_.empty();
}
void LocalExecution::RequestQueuePush(rpc_port_parcel_h parcel) {
- std::lock_guard<std::recursive_mutex> lock(mutex_);
+ std::lock_guard<std::recursive_mutex> lock(mutex_q_);
request_queue_.push(parcel);
}
rpc_port_parcel_h LocalExecution::RequestQueuePop() {
- std::lock_guard<std::recursive_mutex> lock(mutex_);
+ std::lock_guard<std::recursive_mutex> lock(mutex_q_);
auto parcel = request_queue_.front();
request_queue_.pop();
return parcel;
EventSystem::~EventSystem() {
_W("EventSystem dtor");
+ if (local_execution_.get() != nullptr && local_execution_->IsConnected()) {
+ local_execution_->Disconnect();
+ }
+
if (proxy_ != nullptr) rpc_port_proxy_destroy(proxy_);
}
}
void EventSystem::AddAsyncEventList(std::string event_name,
- std::unique_ptr<EventListener> event) {
+ std::unique_ptr<EventListener> event) {
std::lock_guard<std::recursive_mutex> lock(mutex_);
async_event_list_.push_back(std::pair(event_name, std::move(event)));
}
bool EventSystem::RemoveAsyncEventList(int id) {
bool found = false;
std::lock_guard<std::recursive_mutex> lock(mutex_);
- for (auto it = async_event_list_.begin(); it != async_event_list_.end(); ++it) {
+ for (auto it = async_event_list_.begin(); it != async_event_list_.end();
+ ++it) {
if (it->second->GetSeqId() == id) {
async_event_list_.erase(it);
found = true;
void EventSystem::OnLocalConnected() {
if (listener_) listener_->OnConnected();
+
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ for (auto& i : async_event_list_)
+ RegisterEvent(EventSystem::EventType::User, i.first,
+ std::move(i.second));
+ async_event_list_.clear();
}
void EventSystem::OnLocalDisconnected() {
std::lock_guard<std::recursive_mutex> lock(handle->mutex_);
for (auto& i : handle->async_event_list_)
- handle->RegisterEvent(EventSystem::EventType::User,
- i.first, std::move(i.second));
+ handle->RegisterEvent(EventSystem::EventType::User, i.first,
+ std::move(i.second));
handle->async_event_list_.clear();
}
EXPORT_API int rpc_port_proxy_eventsystem_lem_EventSystem_connect(void* h,
bool sync) {
auto* handle = static_cast<rpc_port::es_proxy::LocalExecution*>(h);
- handle->OnConnected();
- return RPC_PORT_ERROR_NONE;
-}
+ if (sync) {
+ handle->OnConnected();
+ return RPC_PORT_ERROR_NONE;
+ }
-EXPORT_API int rpc_port_proxy_eventsystem_lem_EventSystem_disconnect(void* h) {
- auto* handle = static_cast<rpc_port::es_proxy::LocalExecution*>(h);
+ /* LCOV_EXCL_START */
auto* ptr = new std::weak_ptr<rpc_port::es_proxy::LocalExecution>(
handle->shared_from_this());
auto* source = g_idle_source_new();
if (source == nullptr) {
- /* LCOV_EXCL_START */
_E("Failed to create idle source");
delete ptr;
return RPC_PORT_ERROR_OUT_OF_MEMORY;
- /* LCOV_EXCL_STOP */
}
g_source_set_callback(
static_cast<std::weak_ptr<rpc_port::es_proxy::LocalExecution>*>(
user_data);
auto p = wp->lock();
- if (p != nullptr) p->OnDisconnected();
+ if (p != nullptr) p->OnConnected();
delete wp;
return G_SOURCE_REMOVE;
ptr, nullptr);
g_source_attach(source, handle->GetContext());
g_source_unref(source);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+EXPORT_API int rpc_port_proxy_eventsystem_lem_EventSystem_disconnect(void* h) {
+ auto* handle = static_cast<rpc_port::es_proxy::LocalExecution*>(h);
+ handle->OnDisconnected();
return RPC_PORT_ERROR_NONE;
}
int ret = eventsystem_application_finalize();
EXPECT_EQ(ret, ES_R_OK);
}
+
+TEST_F(EventSystemTest, eventsystem_register_application_event3) {
+ unsigned int id;
+ int type;
+ static GMainLoop* loop;
+ static std::string g_event_name;
+
+ g_event_name = "";
+ loop = g_main_loop_new(nullptr, FALSE);
+ int ret = eventsystem_register_application_event(
+ "event.signal_agent.tidl_iface_PkgSignal.test", &id, &type,
+ [](const char* event_name, bundle_raw* event_data, int len,
+ void* user_data) {
+ g_event_name = event_name;
+ g_main_loop_quit(loop);
+ },
+ nullptr);
+ EXPECT_EQ(ret, ES_R_OK);
+
+ g_timeout_add(
+ 1000,
+ [](auto* l) {
+ tizen_base::Bundle data;
+ eventsystem_send_system_event(
+ "event.signal_agent.tidl_iface_PkgSignal.test", data.GetHandle());
+ return G_SOURCE_REMOVE;
+ },
+ loop);
+
+ g_main_loop_run(loop);
+
+ EXPECT_EQ(g_event_name, "event.signal_agent.tidl_iface_PkgSignal.test");
+ g_main_loop_unref(loop);
+}
EXPECT_EQ(g_event_name, "event.d::org.tizen.appfw.service.esd.test");
g_main_loop_unref(loop);
}
+
+TEST_F(EventSystemTest, eventsystem_register_application_event3) {
+ unsigned int id;
+ int type;
+ static GMainLoop* loop;
+ static std::string g_event_name;
+
+ RunModule();
+ g_event_name = "";
+ loop = g_main_loop_new(nullptr, FALSE);
+ int ret = eventsystem_register_application_event(
+ "event.signal_agent.tidl_iface_PkgSignal.test", &id, &type,
+ [](const char* event_name, bundle_raw* event_data, int len,
+ void* user_data) {
+ g_event_name = event_name;
+ g_main_loop_quit(loop);
+ },
+ nullptr);
+ EXPECT_EQ(ret, ES_R_OK);
+
+ g_timeout_add(
+ 1000,
+ [](auto* l) {
+ tizen_base::Bundle data;
+ eventsystem_send_system_event(
+ "event.signal_agent.tidl_iface_PkgSignal.test", data.GetHandle());
+ return G_SOURCE_REMOVE;
+ },
+ loop);
+
+ g_main_loop_run(loop);
+
+ EXPECT_EQ(g_event_name, "event.signal_agent.tidl_iface_PkgSignal.test");
+ g_main_loop_unref(loop);
+}