Skip to content
Snippets Groups Projects
Commit b15a4b82 authored by Jan Včelák's avatar Jan Včelák :rocket:
Browse files

dthreads: add support for thread destructor

Called when before the thread is definitelly destroyed.
parent 2aab1f49
No related branches found
No related tags found
No related merge requests found
......@@ -209,6 +209,13 @@ static void *thread_ep(void *data)
}
}
// Thread destructor
if (thread->destruct) {
dbg_dt("dthreads: [%p] entering destructor\n", thread);
thread->destruct(thread);
dbg_dt("dthreads: [%p] exited destructor\n", result);
}
// Report thread state change
dbg_dt("dthreads: [%p] thread finished\n", thread);
unit_signalize_change(unit);
......@@ -372,7 +379,8 @@ dt_unit_t *dt_create(int count)
return unit;
}
dt_unit_t *dt_create_coherent(int count, runnable_t runnable, void *data)
dt_unit_t *dt_create_coherent(int count, runnable_t runnable,
runnable_t destructor, void *data)
{
// Check count
if (count <= 0) {
......@@ -393,6 +401,7 @@ dt_unit_t *dt_create_coherent(int count, runnable_t runnable, void *data)
dthread_t *thread = unit->threads[i];
lock_thread_rw(thread);
thread->run = runnable;
thread->destruct = destructor;
thread->_adata = data;
unlock_thread_rw(thread);
}
......
......@@ -78,6 +78,7 @@ typedef int (*runnable_t)(struct dthread_t *);
typedef struct dthread_t {
volatile unsigned state; /*!< Bitfield of dt_flag flags. */
runnable_t run; /*!< Runnable function or 0. */
runnable_t destruct; /*!< Destructor function or 0. */
void *data; /*!< Currently active data */
struct dt_unit_t *unit; /*!< Reference to assigned unit. */
void *_adata; /* Thread-specific data. */
......@@ -123,12 +124,14 @@ dt_unit_t *dt_create(int count);
*
* \param count Requested thread count.
* \param runnable Runnable function for all threads.
* \param destructor Destructor for all threads.
* \param data Any data passed onto threads.
*
* \retval New instance if successful
* \retval NULL on error
*/
dt_unit_t *dt_create_coherent(int count, runnable_t runnable, void *data);
dt_unit_t *dt_create_coherent(int count, runnable_t runnable,
runnable_t destructor, void *data);
/*!
* \brief Free unit.
......
......@@ -334,7 +334,7 @@ server_t *server_create()
// Create event scheduler
dbg_server("server: creating event scheduler\n");
server->sched = evsched_new();
server->iosched = dt_create_coherent(1, evsched_run, server->sched);
server->iosched = dt_create_coherent(1, evsched_run, NULL, server->sched);
// Create name server
dbg_server("server: creating Name Server structure\n");
......@@ -593,7 +593,8 @@ int server_conf_hook(const struct conf_t *conf, void *data)
/* Initialize I/O handlers. */
size_t udp_size = tu_size;
if (udp_size < 2) udp_size = 2;
dt_unit_t *tu = dt_create_coherent(udp_size, &udp_master, NULL);
dt_unit_t *tu = dt_create_coherent(udp_size, &udp_master, NULL,
NULL);
server_init_handler(server->h + IO_UDP, server, tu, NULL);
/* Create at least CONFIG_XFERS threads for TCP for faster
......
......@@ -1676,7 +1676,7 @@ static int zones_insert_zones(knot_nameserver_t *ns,
/* Initialize threads. */
size_t thrs = dt_optimal_size();
if (thrs > zcount) thrs = zcount;
dt_unit_t *unit = dt_create_coherent(thrs, &zonewalker, zw);
dt_unit_t *unit = dt_create_coherent(thrs, &zonewalker, NULL, zw);
if (unit != NULL) {
/* Start loading. */
dt_start(unit);
......
......@@ -255,7 +255,7 @@ static int dt_tests_run(int argc, char *argv[])
/* Test 15: Wrong values. */
unit = dt_create(-1);
ok(unit == 0, "dthreads: create with negative count");
unit = dt_create_coherent(dt_optimal_size(), 0, 0);
unit = dt_create_coherent(dt_optimal_size(), 0, 0, 0);
/* Test 16: NULL runnable. */
cmp_ok(dt_start(unit), "==", 0, "dthreads: start with NULL runnable");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment