1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
/* BSD-2-Clause license
*
* Copyright (c) 2018-2023 NST <www.newinfosec.ru>, sss <sss at dark-alexandr dot net>.
*
*/
#pragma once
#include <stdint.h>
#include <ev.h>
struct wrdp_thpool_s;
typedef struct wrdp_thpool_s wrdp_thpool;
struct wrdp_thpool_thread_s;
typedef struct wrdp_thpool_thread_s wrdp_thpool_thread;
struct wrdp_thpool_task_s;
typedef struct wrdp_thpool_task_s wrdp_thpool_task;
/* initialize thread pool */
/* function called in each thread to do additional initialization
* of user_pool_data
void (*custom_thread_init) (void *user_pool_data);
*/
/* function called in each thread to do additional cleanup of
* user_pool_data
void (*custom_thread_deinit) (void *user_pool_data);
*/
/* function called in wrdp_thpool_create to do additional initialization
* of user_pool_data
void (*custom_pool_create) (void *user_pool_data);
*/
/* function called in wrdp_thpool_destroy to do additional cleanup of
* user_pool_data
void (*custom_pool_destroy) (void *user_pool_data);
*/
/* function called on incomming mesdage with "void *user_data" directed to
* pool
void (*pool_message_handler) (void *user_data);
*/
/* function called on incomming message with "void *user_data" directed to
* thrad
void (*thread_message_handler) (void *user_data);
*/
/* struct ev_loop* loop
* it's possible to use specified ev_loop instead of EV_DEFAULT
*/
wrdp_thpool *wrdp_thpool_create(uint16_t thread_count,
uint64_t max_tasks_per_thread,
void (*custom_thread_init)(void *user_pool_data, wrdp_thpool_thread *t),
void (*custom_thread_deinit)(void *user_pool_data, wrdp_thpool_thread *t),
void (*custom_pool_create)(void *user_pool_data),
void (*custom_pool_destroy)(void *user_pool_data),
void (*pool_message_handler)(void *user_data),
void (*thread_message_handler)(void *user_data), struct ev_loop *loop,
void *user_pool_data);
/* deinitialize thread pool */
void wrdp_thpool_destroy(wrdp_thpool *pool);
/*
* Add task to thread pool.
* task will be added to thread with minimal tasks count
* Not thread safe.
* Must be called from thread which created thread pool only.
*
* pool: fully initialized thread pool
* run_task: task entry point callback
* must not block but set libev watcher instead
*
* userdata: user specified data pointer
*/
bool wrdp_thread_pool_add_task(wrdp_thpool *pool,
void (*run_task)(wrdp_thpool_task *task, void *userdata),
void (*task_init_cb)(wrdp_thpool_task *task, void *userdata),
void *userdata);
/*
* Add task to thread pool to specified thread.
* task will be added to specified thread
* Not thread safe.
* Must be called from thread which created thread pool only.
*
* pool: fully initialized thread pool
*
* thread_id: id of the thread to run task in
*
* run_task: task entry point callback
* must not block but set libev watcher instead
*
* userdata: user specified data pointer
*/
bool wrdp_thread_pool_add_task_to_thread(wrdp_thpool *pool,
void (*run_task)(wrdp_thpool_task *task, void *userdata),
uint32_t thread_id,
void (*task_init_cb)(wrdp_thpool_task *task, void *userdata),
void *userdata);
/*
* Move task to specified thread.
* task will be moved to specified thread
*
* (technically new task in specified thread will
* be created, and current task will be deleted
* preserving task internal state)
*
* pool: fully initialized thread pool
*
* thread_id: id of the thread to run task in
*
* run_task: task entry point callback
* must not block but set libev watcher instead
*
* stop_task: callback function used to prepare task for ruining in new thread
*
* userdata: user specified data pointer
*/
bool wrdp_thread_pool_move_task_to_thread(wrdp_thpool *pool,
void (*run_task)(wrdp_thpool_task *task, void *userdata),
void (*stop_task)(wrdp_thpool_task *current_task, void *userdata),
uint32_t thread_id,
void (*task_init_cb)(wrdp_thpool_task *task, void *userdata),
wrdp_thpool_task *current_task, void *userdata);
/*
* it is possible to send message with "void *user_data" to specified thread,
* or to pool main thread
* NOTE: custom message handler function must also be set during pool creation
*/
bool wrdp_thpool_send_msg_to_thread(
wrdp_thpool *pool, uint32_t thread_id, void *user_data);
bool wrdp_thpool_send_msg_to_pool(wrdp_thpool *pool, void *user_data);
/*
* Destroy runing task.
* Custom destroy is function ptr "void(*callable)(wrdp_thpool_task* task)".
*/
void wrdp_thread_pool_destroy_task(
wrdp_thpool_task *task, void (*on_task_destroy)(wrdp_thpool_task *task));
|