mirror of
https://github.com/openharmony/third_party_backends.git
synced 2026-07-01 09:11:13 -04:00
!53 merge master into master
使用线程池优化扫描仪发现接口
Created-by: Q-haosu
Commit-by: 刘昊苏
Merged-by: openharmony_ci
Description: ### 一、内容说明(相关的Issue)
### 二、建议测试周期和提测地址
建议测试完成时间:xxxx.xx.xx
投产上线时间:xxxx.xx.xx
提测地址:CI环境/压测环境
测试账号:
### 三、变更内容
* 3.1 关联PR列表
* 3.2 数据库和部署说明
1. 常规更新
2. 重启unicorn
3. 重启sidekiq
4. 迁移任务:是否有迁移任务,没有写 "无"
5. rake脚本:`bundle exec xxx RAILS_ENV = production`;没有写 "无"
* 3.4 其他技术优化内容(做了什么,变更了什么)
- 重构了 xxxx 代码
- xxxx 算法优化
* 3.5 废弃通知(什么字段、方法弃用?)
* 3.6 后向不兼容变更(是否有无法向后兼容的变更?)
### 四、研发自测点(自测哪些?冒烟用例全部自测?)
自测测试结论:
### 五、测试关注点(需要提醒QA重点关注的、可能会忽略的地方)
检查点:
| 需求名称 | 是否影响xx公共模块 | 是否需要xx功能 | 需求升级是否依赖其他子产品 |
|------|------------|----------|---------------|
| xxx | 否 | 需要 | 不需要 |
| | | | |
接口测试:
性能测试:
并发测试:
其他:
See merge request: openharmony/third_party_backends!53
This commit is contained in:
@@ -21,6 +21,8 @@ SANE_LIB_DIR = "/data/service/el1/public/print_service/sane/backend"
|
||||
SANE_V_MAJOR = 1
|
||||
SANE_V_MINOR = 2
|
||||
enable_hilog = true
|
||||
enable_thread_pool = true
|
||||
enable_scan_service = true
|
||||
source_dir = "//third_party/backends"
|
||||
target_dir = "${target_gen_dir}/sane"
|
||||
|
||||
@@ -29,7 +31,8 @@ action("backends_action") {
|
||||
script = "//third_party/backends/install.py"
|
||||
inputs = [
|
||||
"${source_dir}/patches/modifying_driver_search_path.patch",
|
||||
"${source_dir}/patches/dll.c.patch",
|
||||
"${source_dir}/patches/add_thread_poll.patch",
|
||||
"${source_dir}/patches/hilog_debug.patch",
|
||||
]
|
||||
outputs = [
|
||||
"${target_dir}/include/config.h",
|
||||
@@ -69,6 +72,14 @@ config("backends_private_config") {
|
||||
cflags += [ "-DENABLE_HILOG" ]
|
||||
}
|
||||
|
||||
if (enable_thread_pool) {
|
||||
cflags += [ "-DHAVE_THREAD_POLL"]
|
||||
}
|
||||
|
||||
if (enable_scan_service) {
|
||||
cflags += [ "-DHAVE_SCAN_SERVICE"]
|
||||
}
|
||||
|
||||
defines = [
|
||||
"PATH_SANE_CONFIG_DIR=$SANE_CONFIG_DIR",
|
||||
"PATH_SANE_DATA_DIR=$SANE_DATA_DIR",
|
||||
@@ -185,6 +196,33 @@ ohos_source_set("sane_strstatus") {
|
||||
part_name = "backends"
|
||||
}
|
||||
|
||||
|
||||
ohos_source_set("threadpool_c") {
|
||||
sources = [
|
||||
"threadpool/src/threadpool_c.cpp",
|
||||
"threadpool/src/threadpool_wrapper.cpp"
|
||||
]
|
||||
|
||||
include_dirs = [
|
||||
"threadpool/include",
|
||||
]
|
||||
|
||||
external_deps = [
|
||||
"c_utils:utils",
|
||||
]
|
||||
|
||||
if (enable_hilog) {
|
||||
external_deps += [ "hilog:libhilog" ]
|
||||
}
|
||||
|
||||
public_configs = [ ":backends_public_config" ]
|
||||
|
||||
configs = [ ":backends_private_config" ]
|
||||
|
||||
subsystem_name = "thirdparty"
|
||||
part_name = "backends"
|
||||
}
|
||||
|
||||
ohos_shared_library("sane") {
|
||||
sources = [
|
||||
"./backend/dll.c",
|
||||
@@ -207,6 +245,13 @@ ohos_shared_library("sane") {
|
||||
":sanei_usb",
|
||||
]
|
||||
|
||||
include_dirs = []
|
||||
|
||||
if (enable_thread_pool) {
|
||||
deps += [ ":threadpool_c" ]
|
||||
include_dirs += [ "threadpool/include" ]
|
||||
}
|
||||
|
||||
if (enable_hilog) {
|
||||
external_deps = [ "hilog:libhilog" ]
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
"deps": {
|
||||
"components": [
|
||||
"hilog",
|
||||
"c_utils",
|
||||
"libusb"
|
||||
],
|
||||
"third_party": [
|
||||
|
||||
+2
-1
@@ -24,7 +24,8 @@ import shutil
|
||||
def apply_patch(source_dir):
|
||||
patch_list = [
|
||||
'modifying_driver_search_path.patch',
|
||||
'dll.c.patch',
|
||||
'add_thread_poll.patch',
|
||||
'hilog_debug.patch',
|
||||
]
|
||||
|
||||
for patch in patch_list:
|
||||
|
||||
@@ -0,0 +1,269 @@
|
||||
diff --git a/backend/dll.c b/backend/dll.c
|
||||
index 7a505d13f..120dcf7e5 100644
|
||||
--- a/backend/dll.c
|
||||
+++ b/backend/dll.c
|
||||
@@ -292,6 +292,26 @@ static const char *op_name[] = {
|
||||
};
|
||||
#endif /* __BEOS__ */
|
||||
|
||||
+#ifdef HAVE_THREAD_POLL
|
||||
+
|
||||
+#include "threadpool_c.h"
|
||||
+
|
||||
+typedef struct backend_task {
|
||||
+ struct backend *be;
|
||||
+ SANE_Bool local_only;
|
||||
+ const SANE_Device **be_list;
|
||||
+ SANE_Status status;
|
||||
+ int num_devs;
|
||||
+ SANE_Device **devices;
|
||||
+ int device_count;
|
||||
+} backend_task_t;
|
||||
+
|
||||
+static threadpool_handle_t* pool = NULL;
|
||||
+
|
||||
+static const int max_thread_number = 20;
|
||||
+
|
||||
+#endif // HAVE_THREAD_POLL
|
||||
+
|
||||
#if defined(HAVE_SCAN_SERVICE)
|
||||
static int has_suffix(const char *filename, const char *suffix)
|
||||
{
|
||||
@@ -1052,6 +1072,13 @@ sane_exit (void)
|
||||
|
||||
DBG (2, "sane_exit: exiting\n");
|
||||
|
||||
+#ifdef HAVE_THREAD_POLL
|
||||
+if (pool) {
|
||||
+ threadpool_destroy(pool);
|
||||
+ pool = NULL;
|
||||
+}
|
||||
+#endif // HAVE_THREAD_POLL
|
||||
+
|
||||
for (be = first_backend; be; be = next)
|
||||
{
|
||||
next = be->next;
|
||||
@@ -1123,6 +1150,7 @@ sane_exit (void)
|
||||
DBG (3, "sane_exit: finished\n");
|
||||
}
|
||||
|
||||
+#ifndef HAVE_THREAD_POLL
|
||||
/* Note that a call to get_devices() implies that we'll have to load
|
||||
all backends. To avoid this, you can call sane_open() directly
|
||||
(assuming you know the name of the backend/device). This is
|
||||
@@ -1238,6 +1266,215 @@ sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
+#else
|
||||
+static void process_backend_task(void *arg) {
|
||||
+ backend_task_t *task = (backend_task_t *)arg;
|
||||
+ if (!task || !task->be) {
|
||||
+ DBG (1, "process_backend_task: parameter is null\n");
|
||||
+ return;
|
||||
+ }
|
||||
+ struct backend *be = task->be;
|
||||
+ SANE_Status status;
|
||||
+ char *full_name;
|
||||
+ int i, num_devs;
|
||||
+ size_t len;
|
||||
+
|
||||
+ if (!be->inited) {
|
||||
+ if (init(be) != SANE_STATUS_GOOD) {
|
||||
+ task->status = SANE_STATUS_INVAL;
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ if (be->name) {
|
||||
+ DBG (1, "process_backend_task: driver [%s] sane_get_devices begin\n", be->name);
|
||||
+ }
|
||||
+ status = (*(op_get_devs_t)be->op[OP_GET_DEVS]) (&task->be_list, task->local_only);
|
||||
+ if (be->name) {
|
||||
+ DBG (1, "process_backend_task: driver [%s] sane_get_devices end\n", be->name);
|
||||
+ }
|
||||
+ task->status = status;
|
||||
+
|
||||
+ if (status != SANE_STATUS_GOOD || !task->be_list) {
|
||||
+ DBG (1, "process_backend_task: driver [%s] sane_get_devices fail, ret = %d\n", be->name, (int)status);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ for (task->num_devs = 0; task->be_list[task->num_devs]; ++task->num_devs);
|
||||
+
|
||||
+ task->devices = malloc(task->num_devs * sizeof(SANE_Device*));
|
||||
+ if (!task->devices) {
|
||||
+ task->status = SANE_STATUS_NO_MEM;
|
||||
+ return;
|
||||
+ }
|
||||
+ task->device_count = 0;
|
||||
+
|
||||
+ for (i = 0; i < task->num_devs; ++i) {
|
||||
+ SANE_Device *dev;
|
||||
+ char *mem;
|
||||
+ struct alias *alias;
|
||||
+
|
||||
+ for (alias = first_alias; alias != NULL; alias = alias->next) {
|
||||
+ len = strlen(be->name);
|
||||
+ if (strlen(alias->oldname) <= len)
|
||||
+ continue;
|
||||
+ if (strncmp(alias->oldname, be->name, len) == 0
|
||||
+ && alias->oldname[len] == ':'
|
||||
+ && strcmp(&alias->oldname[len + 1], task->be_list[i]->name) == 0)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (alias) {
|
||||
+ if (!alias->newname) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ len = strlen(alias->newname);
|
||||
+ mem = malloc(sizeof(*dev) + len + 1);
|
||||
+ if (!mem) {
|
||||
+ task->status = SANE_STATUS_NO_MEM;
|
||||
+ for (int j = 0; j < task->device_count; j++) {
|
||||
+ free(task->devices[j]);
|
||||
+ }
|
||||
+ free(task->devices);
|
||||
+ task->devices = NULL;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ full_name = mem + sizeof(*dev);
|
||||
+ strcpy(full_name, alias->newname);
|
||||
+ } else {
|
||||
+ len = strlen(be->name) + 1 + strlen(task->be_list[i]->name);
|
||||
+ mem = malloc(sizeof(*dev) + len + 1);
|
||||
+ if (!mem) {
|
||||
+ task->status = SANE_STATUS_NO_MEM;
|
||||
+ for (int j = 0; j < task->device_count; j++) {
|
||||
+ free(task->devices[j]);
|
||||
+ }
|
||||
+ free(task->devices);
|
||||
+ task->devices = NULL;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ full_name = mem + sizeof(*dev);
|
||||
+ strcpy(full_name, be->name);
|
||||
+ strcat(full_name, ":");
|
||||
+ strcat(full_name, task->be_list[i]->name);
|
||||
+ }
|
||||
+
|
||||
+ dev = (SANE_Device *) mem;
|
||||
+ dev->name = full_name;
|
||||
+ dev->vendor = task->be_list[i]->vendor;
|
||||
+ dev->model = task->be_list[i]->model;
|
||||
+ dev->type = task->be_list[i]->type;
|
||||
+
|
||||
+ task->devices[task->device_count++] = dev;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+SANE_Status
|
||||
+sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
|
||||
+{
|
||||
+ const SANE_Device **be_list;
|
||||
+ struct backend *be;
|
||||
+ SANE_Status status;
|
||||
+ char *full_name;
|
||||
+ int i, num_devs;
|
||||
+ size_t len;
|
||||
+ #define ASSERT_SPACE(n) do \
|
||||
+ { \
|
||||
+ if (devlist_len + (n) > devlist_size) \
|
||||
+ { \
|
||||
+ devlist_size += (n) + 15; \
|
||||
+ if (devlist) \
|
||||
+ devlist = realloc (devlist, devlist_size * sizeof (devlist[0])); \
|
||||
+ else \
|
||||
+ devlist = malloc (devlist_size * sizeof (devlist[0])); \
|
||||
+ if (!devlist) \
|
||||
+ return SANE_STATUS_NO_MEM; \
|
||||
+ } \
|
||||
+ } while (0)
|
||||
+
|
||||
+ DBG (3, "sane_get_devices\n");
|
||||
+
|
||||
+ if (devlist)
|
||||
+ for (i = 0; i < devlist_len; ++i)
|
||||
+ free ((void *) devlist[i]);
|
||||
+ devlist_len = 0;
|
||||
+
|
||||
+ int backend_count = 0;
|
||||
+ for (be = first_backend; be; be = be->next) {
|
||||
+ backend_count++;
|
||||
+ }
|
||||
+
|
||||
+ if (backend_count == 0) {
|
||||
+ ASSERT_SPACE (1);
|
||||
+ devlist[devlist_len++] = 0;
|
||||
+ *device_list = (const SANE_Device **) devlist;
|
||||
+ return SANE_STATUS_GOOD;
|
||||
+ }
|
||||
+
|
||||
+ backend_task_t *tasks = malloc(backend_count * sizeof(backend_task_t));
|
||||
+ if (!tasks) {
|
||||
+ return SANE_STATUS_NO_MEM;
|
||||
+ }
|
||||
+ if (pool == NULL) {
|
||||
+ int discoverThreadNum = backend_count < max_thread_number ? backend_count : max_thread_number;
|
||||
+ pool = threadpool_create(discoverThreadNum);
|
||||
+ }
|
||||
+ int task_index = 0;
|
||||
+ for (be = first_backend; be; be = be->next, task_index++) {
|
||||
+ tasks[task_index].be = be;
|
||||
+ tasks[task_index].local_only = local_only;
|
||||
+ tasks[task_index].be_list = NULL;
|
||||
+ tasks[task_index].status = SANE_STATUS_GOOD;
|
||||
+ tasks[task_index].num_devs = 0;
|
||||
+ tasks[task_index].devices = NULL;
|
||||
+ tasks[task_index].device_count = 0;
|
||||
+
|
||||
+ if (!threadpool_add_task(pool, process_backend_task, &tasks[task_index])) {
|
||||
+ DBG(1, "Failed to add task for backend %s\n", be->name);
|
||||
+ tasks[task_index].status = SANE_STATUS_IO_ERROR;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ threadpool_wait(pool);
|
||||
+
|
||||
+ int total_devices = 0;
|
||||
+ for (task_index = 0; task_index < backend_count; task_index++) {
|
||||
+ if (tasks[task_index].status == SANE_STATUS_GOOD && tasks[task_index].devices) {
|
||||
+ total_devices += tasks[task_index].device_count;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ASSERT_SPACE(total_devices);
|
||||
+
|
||||
+ for (task_index = 0; task_index < backend_count; task_index++) {
|
||||
+ backend_task_t *task = &tasks[task_index];
|
||||
+
|
||||
+ if (task->status != SANE_STATUS_GOOD || !task->devices) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < task->device_count; i++) {
|
||||
+ devlist[devlist_len++] = task->devices[i];
|
||||
+ }
|
||||
+
|
||||
+ free(task->devices);
|
||||
+ }
|
||||
+
|
||||
+ free(tasks);
|
||||
+ threadpool_destroy(pool);
|
||||
+ pool = NULL;
|
||||
+
|
||||
+ ASSERT_SPACE (1);
|
||||
+ devlist[devlist_len++] = 0;
|
||||
+
|
||||
+ *device_list = (const SANE_Device **) devlist;
|
||||
+ DBG (3, "sane_get_devices: found %d devices\n", devlist_len - 1);
|
||||
+ return SANE_STATUS_GOOD;
|
||||
+}
|
||||
+#endif // HAVE_THREAD_POLL
|
||||
+
|
||||
SANE_Status
|
||||
sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle)
|
||||
{
|
||||
@@ -1,17 +0,0 @@
|
||||
diff --git a/backend/dll.c b/backend/dll.c
|
||||
index 9b13d3a59..7a505d13f 100644
|
||||
--- a/backend/dll.c
|
||||
+++ b/backend/dll.c
|
||||
@@ -1353,6 +1353,12 @@ sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle)
|
||||
}
|
||||
free(be_name);
|
||||
|
||||
+ if (!be)
|
||||
+ {
|
||||
+ DBG (3, "sane_open: be is nullptr\n");
|
||||
+ return SANE_STATUS_NO_MEM;
|
||||
+ }
|
||||
+
|
||||
if (!be->inited)
|
||||
{
|
||||
status = init (be);
|
||||
@@ -0,0 +1,27 @@
|
||||
diff --git a/include/sane/sanei_debug.h b/include/sane/sanei_debug.h
|
||||
index 465d3e25e..b18da651c 100644
|
||||
--- a/include/sane/sanei_debug.h
|
||||
+++ b/include/sane/sanei_debug.h
|
||||
@@ -8,7 +8,9 @@
|
||||
#define _SANEI_DEBUG_H
|
||||
|
||||
#include <sane/sanei.h>
|
||||
-
|
||||
+#ifdef ENABLE_HILOG
|
||||
+#include "hilog/log.h"
|
||||
+#endif // ENABLE_HILOG
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -79,7 +81,11 @@ extern void sanei_debug_ndebug (int level, const char *msg, ...);
|
||||
|
||||
# define DBG_LEVEL (0)
|
||||
# define DBG_INIT()
|
||||
+#ifndef ENABLE_HILOG
|
||||
# define DBG sanei_debug_ndebug
|
||||
+#else
|
||||
+# define DBG(level, ...) ((void)HiLogPrint(LOG_APP, LOG_INFO, 0, "sanekit", __VA_ARGS__))
|
||||
+#endif // ENABLE_HILOG
|
||||
# define IF_DBG(x)
|
||||
|
||||
#else /* !NDEBUG */
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/backend/dll.c b/backend/dll.c
|
||||
index bf34c4f6d..9b13d3a59 100644
|
||||
index bf34c4f6d..7a505d13f 100644
|
||||
--- a/backend/dll.c
|
||||
+++ b/backend/dll.c
|
||||
@@ -292,6 +292,46 @@ static const char *op_name[] = {
|
||||
@@ -102,17 +102,16 @@ index bf34c4f6d..9b13d3a59 100644
|
||||
fp = sanei_config_open (DLL_ALIASES_FILE);
|
||||
if (!fp)
|
||||
return SANE_STATUS_GOOD; /* don't insist on aliases file */
|
||||
diff --git a/include/sane/config.h b/include/sane/config.h
|
||||
index 20dfa104b..206a4147e 100644
|
||||
--- a/include/sane/config.h
|
||||
+++ b/include/sane/config.h
|
||||
@@ -209,6 +209,9 @@
|
||||
/* Define to 1 if you have libusb-1.0 */
|
||||
#define HAVE_LIBUSB 1
|
||||
@@ -1284,6 +1353,12 @@ sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle)
|
||||
}
|
||||
free(be_name);
|
||||
|
||||
+/* Define to 1 if you have scan_service */
|
||||
+#define HAVE_SCAN_SERVICE 1
|
||||
+ if (!be)
|
||||
+ {
|
||||
+ DBG (3, "sane_open: be is nullptr\n");
|
||||
+ return SANE_STATUS_NO_MEM;
|
||||
+ }
|
||||
+
|
||||
/* Define to 1 if you have libusb-0.1 */
|
||||
/* #undef HAVE_LIBUSB_LEGACY */
|
||||
|
||||
if (!be->inited)
|
||||
{
|
||||
status = init (be);
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Huawei Device Co., Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef THREADPOOL_C_H
|
||||
#define THREADPOOL_C_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void (*threadpool_task_func_t)(void* arg);
|
||||
|
||||
typedef struct threadpool_handle_t threadpool_handle_t;
|
||||
|
||||
threadpool_handle_t* threadpool_create(int thread_num);
|
||||
|
||||
bool threadpool_add_task(threadpool_handle_t* pool, threadpool_task_func_t func, void* arg);
|
||||
|
||||
void threadpool_destroy(threadpool_handle_t* pool);
|
||||
|
||||
void threadpool_wait(threadpool_handle_t* pool);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // THREADPOOL_C_H
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Huawei Device Co., Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef THREADPOOL_WRAPPER
|
||||
#define THREADPOOL_WRAPPER
|
||||
|
||||
#include "threadpool_c.h"
|
||||
#include "thread_pool.h"
|
||||
#include <string>
|
||||
|
||||
class ThreadPoolWrapper {
|
||||
public:
|
||||
ThreadPoolWrapper() = default;
|
||||
|
||||
~ThreadPoolWrapper() = default;
|
||||
|
||||
bool Start(int thread_num);
|
||||
|
||||
void Stop();
|
||||
|
||||
void AddTask(threadpool_task_func_t func, void* arg);
|
||||
|
||||
void Wait();
|
||||
|
||||
private:
|
||||
OHOS::ThreadPool pool_;
|
||||
};
|
||||
|
||||
#endif // THREADPOOL_WRAPPER
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Huawei Device Co., Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "threadpool_c.h"
|
||||
#include "threadpool_wrapper.h"
|
||||
#include "sanei_debug.h"
|
||||
|
||||
#define LEVEL 1
|
||||
|
||||
struct threadpool_handle_t {
|
||||
ThreadPoolWrapper* wrapper;
|
||||
};
|
||||
|
||||
threadpool_handle_t* threadpool_create(int32_t thread_num)
|
||||
{
|
||||
constexpr int32_t maxThreadNum = 20;
|
||||
if (thread_num <= 0 || thread_num > maxThreadNum) {
|
||||
DBG(LEVEL, "threadpool_create: fail\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
threadpool_handle_t* handle = new(std::nothrow) threadpool_handle_t();
|
||||
if (!handle) {
|
||||
DBG(LEVEL, "threadpool_create: handle is nullptr\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
handle->wrapper = new(std::nothrow) ThreadPoolWrapper();
|
||||
if (!handle->wrapper) {
|
||||
delete handle;
|
||||
DBG(LEVEL, "threadpool_create: wrapper is nullptr\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!handle->wrapper->Start(thread_num)) {
|
||||
delete handle->wrapper;
|
||||
delete handle;
|
||||
DBG(LEVEL, "threadpool_create: Start fail\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
bool threadpool_add_task(threadpool_handle_t* pool, threadpool_task_func_t func, void* arg)
|
||||
{
|
||||
if (!pool || !pool->wrapper || !func) {
|
||||
DBG(LEVEL, "threadpool_add_task: fail\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
pool->wrapper->AddTask(func, arg);
|
||||
return true;
|
||||
}
|
||||
|
||||
void threadpool_destroy(threadpool_handle_t* pool)
|
||||
{
|
||||
if (pool) {
|
||||
if (pool->wrapper) {
|
||||
delete pool->wrapper;
|
||||
}
|
||||
delete pool;
|
||||
}
|
||||
}
|
||||
|
||||
void threadpool_wait(threadpool_handle_t* pool)
|
||||
{
|
||||
if (pool && pool->wrapper) {
|
||||
pool->wrapper->Wait();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Huawei Device Co., Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include "errors.h"
|
||||
#include "threadpool_wrapper.h"
|
||||
|
||||
bool ThreadPoolWrapper::Start(int32_t thread_num)
|
||||
{
|
||||
return pool_.Start(thread_num) == OHOS::ERR_OK;
|
||||
}
|
||||
|
||||
void ThreadPoolWrapper::Stop()
|
||||
{
|
||||
pool_.Stop();
|
||||
}
|
||||
|
||||
void ThreadPoolWrapper::AddTask(threadpool_task_func_t func, void* arg)
|
||||
{
|
||||
if (func) {
|
||||
pool_.AddTask([func, arg]() {
|
||||
func(arg);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void ThreadPoolWrapper::Wait()
|
||||
{
|
||||
constexpr int32_t WAIT_TIME = 1;
|
||||
int32_t curTaskNum = 0;
|
||||
do {
|
||||
curTaskNum = static_cast<int32_t>(pool_.GetCurTaskNum());
|
||||
std::this_thread::sleep_for(std::chrono::seconds(WAIT_TIME));
|
||||
} while (curTaskNum != 0);
|
||||
pool_.Stop();
|
||||
}
|
||||
Reference in New Issue
Block a user