#include <glib-unix.h>
#include <rpc-port-internal.h>
#include <bundle_internal.h>
+#include <tizen_core.h>
#include "hal-common.h"
#include "hal-api-conf.h"
#include "common.h"
-#include "thread.h"
-
#define RPC_STUB_PROC_NAME "d::HalBackendService"
struct hal_backend_service_data {
enum hal_module module;
- struct thread *thread;
- gboolean is_initialized;
+ tizen_core_task_h task;
+ bool is_initialized;
};
enum hal_backend_service_func {
extern char *program_invocation_name;
-static GMainLoop *g_g_main_loop;
+static tizen_core_task_h g_main_task = NULL;
+
static GSList *g_hal_backend_service_data_list = NULL;
G_LOCK_DEFINE_STATIC(hal_backend_service_lock);
static int add_hal_backend_service(enum hal_module module)
{
- struct hal_backend_service_data *hal_backend_service_data;
+ struct hal_backend_service_data *hal_backend_service_data = NULL;
if (module <= HAL_MODULE_UNKNOWN || module >= HAL_MODULE_END) {
_E("Invalid parameter of HAL module (%d)\n", module);
}
hal_backend_service_data->module = module;
- hal_backend_service_data->thread = NULL;
- hal_backend_service_data->is_initialized = FALSE;
+ hal_backend_service_data->task = NULL;
+ hal_backend_service_data->is_initialized = false;
g_hal_backend_service_data_list = g_slist_prepend(g_hal_backend_service_data_list,
(gpointer)hal_backend_service_data);
return 0;
}
-static int hal_backend_service_thread_func(void *data, void **user_data)
+static bool hal_backend_service_initialize_cb(tizen_core_source_h source, int *timeout, void *data)
{
struct hal_backend_service_data *service_data = NULL;
int ret = 0;
+ /* FIXME: This is error situation, task should be terminated? */
if (data == NULL) {
_E("Invalid hal_backend_service(NULL)");
- return THREAD_RETURN_ERROR;
+ return false;
}
service_data = (struct hal_backend_service_data *)data;
+ if (service_data->is_initialized)
+ return false;
+
if (service_data->module <= HAL_MODULE_UNKNOWN || service_data->module >= HAL_MODULE_END) {
_E("Invalid parameter of HAL module (%d)\n", service_data->module);
- return THREAD_RETURN_ERROR;
+ return false;
}
ret = hal_common_init_backend_service(service_data->module, NULL);
if (ret < 0) {
_E("Failed to initialize hal backend service: ret(%d)", ret);
- return THREAD_RETURN_ERROR;
+ return false;
}
- suspend_thread(service_data->thread);
+ service_data->is_initialized = true;
- return THREAD_RETURN_CONTINUE;
+ return false;
}
-static int hal_backend_thread_finalize_func(void *data)
+static void hal_backend_service_finalize_cb(tizen_core_source_h source, void *data)
{
struct hal_backend_service_data *service_data = NULL;
int ret = 0;
if (data == NULL) {
_E("Invalid hal_backend_service(NULL)");
- return THREAD_RETURN_ERROR;
+ return;
}
service_data = (struct hal_backend_service_data *)data;
if (service_data->module <= HAL_MODULE_UNKNOWN || service_data->module >= HAL_MODULE_END) {
_E("Invalid parameter of HAL module (%d)\n", service_data->module);
- return THREAD_RETURN_ERROR;
+ return;
}
ret = hal_common_exit_backend_service(service_data->module, NULL);
if (ret < 0) {
_E("Failed to exit hal backend service: ret(%d)", ret);
- return THREAD_RETURN_ERROR;
+ return;
}
- _D("Exit done.");
+ service_data->is_initialized = false;
- return THREAD_RETURN_DONE;
+ _D("Exit done.");
}
-static void create_hal_backend_service_thread(gpointer data, gpointer user_data)
+static void create_hal_backend_service_task(gpointer data, gpointer user_data)
{
- struct hal_backend_service_data *service_data;
- size_t *failed_count;
- struct thread *thread;
+ tizen_core_task_h task = NULL;
+ tizen_core_h core = NULL;
+ tizen_core_source_h source = NULL;
+
+ struct hal_backend_service_data *service_data = NULL;
+ struct __hal_module_info *module_info = NULL;
+ size_t *failed_count = NULL;
int ret = 0;
if (data == NULL || user_data == NULL) {
service_data = (struct hal_backend_service_data *)data;
failed_count = (size_t *)user_data;
- ret = create_daemon_thread(&thread,
- hal_backend_service_thread_func, service_data,
- hal_backend_thread_finalize_func, service_data);
- if (ret < 0) {
- _E("Failed to create hal_backend_service thread: ret(%d)", ret);
- (*failed_count)++;
- return;
+ module_info = _hal_api_conf_get_module_info(service_data->module, NULL);
+ ret = tizen_core_task_create(module_info->backend_module_name, true, &task);
+ if (ret != TIZEN_CORE_ERROR_NONE) {
+ _E("Failed to create tizen_core task: ret(%d)", ret);
+ goto error;
+ }
+
+ ret = tizen_core_source_create(&source);
+ if (ret != TIZEN_CORE_ERROR_NONE) {
+ _E("Failed to create tizen_core source: ret(%d)", ret);
+ goto error;
+ }
+
+ ret = tizen_core_task_get_tizen_core(task, &core);
+ if (ret != TIZEN_CORE_ERROR_NONE) {
+ _E("Failed to get tizen_core core from task: ret(%d)", ret);
+ goto error;
+ }
+
+ ret = tizen_core_source_set_prepare_cb(source, hal_backend_service_initialize_cb, service_data);
+ if (ret != TIZEN_CORE_ERROR_NONE) {
+ _E("Failed to set prepare callback: ret(%d)", ret);
+ goto error;
+ }
+
+ ret = tizen_core_source_set_finalize_cb(source, hal_backend_service_finalize_cb, service_data);
+ if (ret != TIZEN_CORE_ERROR_NONE) {
+ _E("Failed to set finalize callback: ret(%d)", ret);
+ goto error;
+ }
+
+ ret = tizen_core_add_source(core, source);
+ if (ret != TIZEN_CORE_ERROR_NONE) {
+ _E("Failed to add tizen_core source to core: ret(%d)", ret);
+ goto error;
+ }
+
+ ret = tizen_core_task_run(task);
+ if (ret != TIZEN_CORE_ERROR_NONE) {
+ _E("Failed to run tizen_core task: ret(%d)", ret);
+ goto error;
}
- service_data->thread = thread;
- _D("Thread created for hal_module(%d)", service_data->module);
+ service_data->task = task;
+
+ _D("Task created for hal_module(%d)", service_data->module);
+
+ return;
+
+error:
+ if (source != NULL)
+ tizen_core_source_destroy(source);
+
+ if (task != NULL)
+ tizen_core_task_destroy(task);
+
+ (*failed_count)++;
+
+ return;
}
-static void delete_hal_backend_service_thread(gpointer data, gpointer user_data)
+static void delete_hal_backend_service_task(gpointer data, gpointer user_data)
{
- struct hal_backend_service_data *service_data;
+ struct hal_backend_service_data *service_data = NULL;
+ int ret = 0;
if (data == NULL) {
_E("Invalid parameter: data(NULL)");
}
service_data = (struct hal_backend_service_data *)data;
- destroy_thread(service_data->thread);
- service_data->thread = NULL;
+ if (service_data->task == NULL) {
+ _D("No task for hal_module(%d)", service_data->module);
+ return;
+ }
- _D("Thread destroyed for hal_module(%d)", service_data->module);
+ ret = tizen_core_task_quit(service_data->task);
+ if (ret != TIZEN_CORE_ERROR_NONE) {
+ _E("Failed to quit task for hal_module(%d)", service_data->module);
+ return;
+ }
+
+ ret = tizen_core_task_destroy(service_data->task);
+ if (ret != TIZEN_CORE_ERROR_NONE) {
+ _E("Failed to destroy task for hal_module(%d)", service_data->module);
+ return;
+ }
+
+ service_data->task = NULL;
+
+ _D("Task destroyed for hal_module(%d)", service_data->module);
}
static void hal_backend_service_start(void)
{
size_t failed_count = 0;
- /* Create threads for hal-backend-service and then tie them */
+ /* Create tasks for hal-backend-service and then tie them */
g_slist_foreach(g_hal_backend_service_data_list,
- create_hal_backend_service_thread,
+ (GFunc)create_hal_backend_service_task,
&failed_count);
if (failed_count != 0)
_W("Cannot register %zu service(s)", failed_count);
static void hal_backend_service_stop(void)
{
g_slist_foreach(g_hal_backend_service_data_list,
- delete_hal_backend_service_thread, NULL);
+ delete_hal_backend_service_task, NULL);
}
/**
int signal_number = (int)data;
_D("Received signal(%d)", signal_number);
- if (g_g_main_loop != NULL)
- g_main_loop_quit(g_g_main_loop);
+ if (g_main_task != NULL)
+ tizen_core_task_quit(g_main_task);
return G_SOURCE_REMOVE;
}
int main(int argc, char **argv)
{
+ int ret = 0;
+
_D("Initialize hal-backend-service");
- g_g_main_loop = g_main_loop_new(NULL, FALSE);
+ tizen_core_init();
+
+ ret = tizen_core_task_create("main", false, &g_main_task);
+ if (ret != TIZEN_CORE_ERROR_NONE) {
+ _E("Failed to create tizen_core main task: ret(%d)", ret);
+ tizen_core_shutdown();
+ return 1;
+ }
rpc_port_register_proc_info(RPC_STUB_PROC_NAME, NULL);
attach_signal_handlers();
- g_main_loop_run(g_g_main_loop);
+ tizen_core_task_run(g_main_task);
/* Un-load hal-backend-service plugin */
hal_backend_service_stop();
hal_backend_service_delete_and_close_plugin();
+ tizen_core_task_destroy(g_main_task);
+
+ tizen_core_shutdown();
+
_D("Exit hal-backend-service");
return 0;
+++ /dev/null
-/*
- * Copyright (c) 2025 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <errno.h>
-
-#include "thread.h"
-
-static void __thread_loop_main(void *_ctx)
-{
- enum thread_return ret = THREAD_RETURN_DONE;
- enum thread_return finalize_ret = THREAD_RETURN_DONE;
- struct thread_context *ctx = _ctx;
- void *result = NULL;
-
- mtx_lock(&ctx->lock);
- while (ctx->state != THREAD_STATE_TERMINATED) {
- if (ctx->timer.tv_sec || ctx->timer.tv_nsec) {
- mtx_unlock(&ctx->lock);
- thrd_sleep(&ctx->timer, NULL);
- mtx_lock(&ctx->lock);
- }
-
- while (ctx->state == THREAD_STATE_STOPPED)
- cnd_wait(&ctx->wait, &ctx->lock);
- if (ctx->state == THREAD_STATE_TERMINATED)
- break;
-
- mtx_unlock(&ctx->lock);
- ret = ctx->func(ctx->func_arg, &result);
- mtx_lock(&ctx->lock);
-
- if (ret != THREAD_RETURN_CONTINUE) {
- ctx->state = THREAD_STATE_TERMINATED;
- ctx->result = result;
- }
- }
- mtx_unlock(&ctx->lock);
-
- if (ctx->finalize != NULL)
- finalize_ret = ctx->finalize(ctx->finalize_arg);
-
- if (finalize_ret != THREAD_RETURN_DONE)
- ret = finalize_ret;
-
- thrd_exit(ret);
-}
-
-static void do_destroy_thread(struct thread *thread)
-{
- struct thread_context *ctx = thread->ctx;
-
- mtx_lock(&ctx->lock);
- ctx->state = THREAD_STATE_TERMINATED;
- mtx_unlock(&ctx->lock);
-
- /* try to wake up thread whether it is sleeping or not */
- cnd_signal(&ctx->wait);
-
- thrd_join(thread->id, NULL);
-
- cnd_destroy(&ctx->wait);
- mtx_destroy(&ctx->lock);
-}
-
-void destroy_thread(struct thread *thread)
-{
- do_destroy_thread(thread);
- free(thread->ctx);
- thread->ctx = NULL;
-
- free(thread);
-}
-
-static int do_create_thread(struct thread **thread, enum thread_type type,
- u_int32_t timer_expire_msec,
- int (*func)(void *, void **), void *func_arg,
- int (*finalize)(void *), void *finalize_arg)
-{
- struct thread *new_thread;
- struct thread_context *ctx;
- thrd_t tid;
- int ret;
-
- if (!thread || !func)
- return -EINVAL;
-
- new_thread = malloc(sizeof(struct thread));
- if (!new_thread)
- return -ENOMEM;
-
- ctx = calloc(1, sizeof(struct thread_context));
- if (!ctx) {
- ret = -ENOMEM;
- goto err_malloc;
- }
-
- mtx_init(&ctx->lock, mtx_plain);
- cnd_init(&ctx->wait);
-
- ctx->func = func;
- ctx->func_arg = func_arg;
- ctx->finalize = finalize;
- ctx->finalize_arg = finalize_arg;
-
- mtx_lock(&ctx->lock);
- switch (type) {
- case THREAD_TYPE_WORKER:
- ctx->state = THREAD_STATE_STOPPED;
- break;
- case THREAD_TYPE_DAEMON:
- ctx->state = THREAD_STATE_RUNNING;
- break;
- case THREAD_TYPE_TIMER:
- ctx->state = THREAD_STATE_RUNNING;
- ctx->timer = (struct timespec) {
- .tv_sec = timer_expire_msec / 1000,
- .tv_nsec = (timer_expire_msec % 1000) * 1000000,
- };
- break;
- default:
- ret = -EINVAL;
- goto err;
- }
-
- ret = thrd_create(&tid, (thrd_start_t) __thread_loop_main, (void *)ctx);
- if (ret == thrd_error) {
- ret = -EINVAL;
- goto err;
- }
-
- new_thread->id = tid;
- new_thread->ctx = ctx;
-
- *thread = new_thread;
- mtx_unlock(&ctx->lock);
-
- return 0;
-
-err:
- mtx_unlock(&ctx->lock);
- cnd_destroy(&ctx->wait);
- mtx_destroy(&ctx->lock);
- free(ctx);
-err_malloc:
- free(new_thread);
-
- return ret;
-}
-
-int create_daemon_thread(struct thread **thread,
- int (*func)(void *, void **), void *func_arg,
- int (*finalize)(void *), void *finalize_arg)
-{
- return do_create_thread(thread, THREAD_TYPE_DAEMON, 0, func, func_arg,
- finalize, finalize_arg);
-}
-
-int create_timer_thread(struct thread **thread, u_int32_t timer_expire_msec,
- int (*func)(void *, void **), void *func_arg,
- int (*finalize)(void *), void *finalize_arg)
-{
- return do_create_thread(thread, THREAD_TYPE_TIMER, timer_expire_msec,
- func, func_arg, finalize, finalize_arg);
-}
-
-int create_worker_thread(struct thread **thread,
- int (*func)(void *, void **), void *arg,
- int (*finalize)(void *), void *finalize_arg)
-{
- return do_create_thread(thread, THREAD_TYPE_WORKER, 0, func, arg,
- finalize, finalize_arg);
-}
-
-void suspend_thread(struct thread *thread)
-{
- struct thread_context *ctx = thread->ctx;
-
- mtx_lock(&ctx->lock);
- ctx->state = THREAD_STATE_STOPPED;
- mtx_unlock(&ctx->lock);
-}
-
-void resume_thread(struct thread *thread)
-{
- struct thread_context *ctx = thread->ctx;
-
- mtx_lock(&ctx->lock);
- ctx->state = THREAD_STATE_RUNNING;
- mtx_unlock(&ctx->lock);
- cnd_signal(&ctx->wait);
-}
-
-int wait_for_completion(struct thread *thread, void **result)
-{
- struct thread_context *ctx = thread->ctx;
- int ret;
-
- thrd_join(thread->id, &ret);
- if (ret == THREAD_RETURN_ERROR)
- return ret;
-
- if (result)
- *result = ctx->result;
-
- cnd_destroy(&ctx->wait);
- mtx_destroy(&ctx->lock);
-
- free(thread->ctx);
- thread->ctx = NULL;
-
- free(thread);
-
- return 0;
-}
+++ /dev/null
-/*
- * Copyright (c) 2025 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <stdlib.h>
-#include <threads.h>
-#include <time.h>
-
-enum thread_type {
- THREAD_TYPE_WORKER,
- THREAD_TYPE_DAEMON,
- THREAD_TYPE_TIMER,
-};
-
-enum thread_state {
- THREAD_STATE_RUNNING,
- THREAD_STATE_STOPPED,
- THREAD_STATE_TERMINATED,
-};
-
-enum thread_return {
- THREAD_RETURN_ERROR = -EXIT_FAILURE,
- THREAD_RETURN_DONE = EXIT_SUCCESS,
- THREAD_RETURN_CONTINUE,
-};
-
-struct thread_context {
- enum thread_state state;
- struct timespec timer;
- int (*func)(void *func_arg, void **result);
- int (*finalize)(void *finalize_arg);
- void *func_arg;
- void *result;
- void *finalize_arg;
- mtx_t lock;
- cnd_t wait;
-};
-
-struct thread {
- thrd_t id;
- struct thread_context *ctx;
-};
-
-int create_daemon_thread(struct thread **thread,
- int (*func)(void *, void **), void *func_arg,
- int (*finalize)(void *), void *finalize_arg);
-int create_timer_thread(struct thread **thread, u_int32_t timer_expire_msec,
- int (*func)(void *, void **), void *func_arg,
- int (*finalize)(void *), void *finalize_arg);
-int create_worker_thread(struct thread **thread,
- int (*func)(void *, void **), void *func_arg,
- int (*finalize)(void *), void *finalize_arg);
-
-void destroy_thread(struct thread *thread);
-void suspend_thread(struct thread *thread);
-void resume_thread(struct thread *thread);
-
-int wait_for_completion(struct thread *thread, void **result);