/* * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Flora License, Version 1.1 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://floralicense.org/license/ * * 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 #include #include #include #include "ipc.h" #include "err-check.h" #include "task-worker.h" #include "log.h" static void send_report(const char *report_data, int status); static void submit_result_cb(ttd_worker_submit_result_e result, ttd_worker_report *report, void *user_data); static struct ipc { char *command_id; volatile gint counter; } ipc_data = { .command_id = NULL }; void ipc_init(const char *command_id, int counter) { ON_NULL_RETURN(command_id); ON_TRUE_RETURN(counter < 0); ipc_data.command_id = strdup(command_id); g_atomic_int_set(&ipc_data.counter, counter); } void ipc_shutdown() { if (ipc_data.command_id) g_free(ipc_data.command_id); } void ipc_send_report(const char *report) { ON_NULL_RETURN(report); if (!g_atomic_int_dec_and_test(&ipc_data.counter)) { send_report(report, TTD_WORKER_WORKING); } else { send_report(report, TTD_WORKER_COMPLETED); cleanup_and_exit(); } } struct report_data { char *data; ttd_worker_working_state_e status; }; static gboolean invoke_on_main_thread_cb(gpointer user_data) { ON_NULL_RETURN_VAL(user_data, FALSE); struct report_data *r_data = (struct report_data *)user_data; ON_NULL_RETURN_VAL(r_data->data, FALSE); ttd_worker_report *report = ttd_worker_report_new_by_cmd_id(ipc_data.command_id); ttd_worker_report_set_working_state(report, r_data->status); ttd_worker_report_set_report_data(report, r_data->data); if (r_data->status == TTD_WORKER_WORKING) { ttd_worker_submit_report(report, submit_result_cb, NULL); } else if (r_data->status == TTD_WORKER_COMPLETED) { ttd_worker_submit_result_e result; ttd_worker_submit_report_sync(report, &result); if (result == TTD_WORKER_SUBMIT_SUCCESS) DBG("Sending final result succeeded"); else DBG("Sending final result failed"); ttd_worker_report_free(report); cleanup_and_exit(); } g_free(r_data->data); g_free(r_data); return FALSE; } static void send_report(const char *report_data, ttd_worker_working_state_e status) { struct report_data *r_data = (struct report_data *)g_malloc(sizeof(struct report_data)); r_data->data = strdup(report_data); r_data->status = status; g_main_context_invoke(NULL, invoke_on_main_thread_cb, r_data); } static void submit_result_cb(ttd_worker_submit_result_e result, ttd_worker_report *report, void *user_data) { if (result == TTD_WORKER_SUBMIT_SUCCESS) DBG("Sending result succeeded"); else DBG("Sending result failed"); ttd_worker_report_free(report); }