2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-22 10:10:06 +00:00

remove references to obsolete isc_task/timer functions

removed references in code comments, doc/dev documentation, etc, to
isc_task, isc_timer_reset(), and isc_timertype_inactive. also removed a
coccinelle patch related to isc_timer_reset() that was no longer needed.
This commit is contained in:
Evan Hunt 2023-02-21 12:21:32 -08:00
parent ee186855bf
commit b058f99cb8
9 changed files with 43 additions and 148 deletions

View File

@ -1,6 +0,0 @@
@@
expression E1, E2, E3, E4;
@@
- isc_timer_reset(E1, E2, NULL, E3, E4)
+ isc_timer_reset(E1, E2, E3, E4)

View File

@ -32,7 +32,7 @@ information regarding copyright ownership.
* [Iterators](#iterators) * [Iterators](#iterators)
* [Logging](#logging) * [Logging](#logging)
* [Adding a new RR type](#rrtype) * [Adding a new RR type](#rrtype)
* [Task and timer model](#tasks) * [Asynchronous operations](#async)
### <a name="reviews"></a>The code review process ### <a name="reviews"></a>The code review process
@ -1366,86 +1366,10 @@ In nearly all cases, this is simply a wrapper around the `compare()`
function, except where DNSSEC comparisons are specified as function, except where DNSSEC comparisons are specified as
case-sensitive. Unknown RR types are always compared case-sensitively. case-sensitive. Unknown RR types are always compared case-sensitively.
#### <a name="tasks"></a>Task and timer model #### <a name="async"></a>Asynchronous operations
The BIND task/timer management system can be thought of as comparable to a Asynchronous operations are processed using the event loop manager;
simple non-preemptive multitasking operating system. see the [Loop Manager](loopmgr.md) document for details.
In this model, what BIND calls a "task" (or an `isc_task_t` object) is the
equivalent of what is usually called a "process" in an operating system:
a persistent execution context in which functions run when action is
required. When the action is complete, the task goes to sleep, and
wakes up again when more work arrives. A "worker thread" is comparable
to an operating system's CPU; when a task is ready to run, a worker
thread will run it. By default, BIND creates one worker thread for each
system CPU.
An "event" object can be associated with a task, and triggered when a a
specific condition occurs. Each event object contains a pointer to a
specific function and arguments to be passed to it. When the event
triggers, the task is placed onto a "ready queue" in the task manager. As
each running task finishes, the worker threads pull new tasks off the ready
queue. When the task associated with a given event reaches the head of the
queue, the specified function will be called.
Examples:
A timer is set for a specified time in the future, and the event will
be triggered at that time.
/*
* Function to handle a timeout
*/
static void
timeout(isc_task_t *task, isc_event_t *event) {
/* do things */
}
...
/*
* Set up a timer in timer manager 'timermgr', to run
* once, with a NULL expiration time, after 'interval'
* has passed; it will run the function 'timeout' with
* 'arg' as its argument in task 'task'.
*/
isc_timer_t *timer = NULL;
result = isc_timer_create(timermgr, task, timeout, arg, &timer);
result = isc_timer_reset(timermgr, isc_timertype_once, NULL,
interval, false);
An event can also be explicitly triggered via `isc_task_send()`.
static void
do_things(isc_task_t *task, isc_event_t *event) {
/* this function does things */
}
...
/*
* Allocate an event that calls 'do_things' with a
* NULL argument, using 'myself' as ev_sender.
*
* DNS_EVENT_DOTHINGS must be defined in <dns/events.h>.
*
* (Note that 'size' must be specified because there are
* event objects that inherit from isc_event_t, incorporating
* common members via the ISC_EVENT_COMMON member and then
* following them with other members.)
*/
isc_event_t *event;
event = isc_event_allocate(mctx, myself, DNS_EVENT_DOTHINGS,
do_things, NULL, sizeof(isc_event_t));
if (event == NULL)
return (ISC_R_NOMEMORY);
...
/*
* Send the allocated event to task 'task'
*/
isc_task_send(task, event);
#### More... #### More...

View File

@ -79,38 +79,25 @@ need to run the event on a different thread.
manager, uses locked list to collect new jobs and uv_async() primitive to manager, uses locked list to collect new jobs and uv_async() primitive to
enqueue the collected jobs onto the event loop. enqueue the collected jobs onto the event loop.
## Tasks
The ``isc_task`` API has been modified to run the tasks directly on the loop
manager. The new ``isc_job`` and ``isc_async`` APIs are preferred for simple
events; the ``isc_task`` API is provided for backward-compatibility purposes
and thus is also thread-safe because it uses locking and uv_async() to enqueue
events onto the event loop.
## Timers ## Timers
The ``isc_timer`` API is now built on top of the ``uv_timer_t`` object. It has The ``isc_timer`` API is built on top of the ``uv_timer_t`` object.
been changed to support only ``ticker`` and ``once`` timers, and now uses It supports ``ticker`` and ``once`` timers, and uses ``isc_timer_start()``
``isc_timer_start()`` and ``isc_timer_stop()`` instead of changing the timer and ``isc_timer_stop()`` to start and stop timers. The ``isc_timer_t``
type to ``inactive``. The ``isc_timer_t`` object is not thread-safe. object is not thread-safe.
## Network Manager ## Network Manager
The network manager has been changed to use the loop manager event loops The network manager is built on top loop manager event loops rather than
instead of managing its own event loops. managing its own event loops. Network manager calls are not thread-safe:
all connect/read/write functions MUST be called from the thread that created
The new network manager calls are not thread-safe; all connect/read/write the network manager socket.
functions MUST be called from the thread that created the network manager
socket.
The ``isc_nm_listen*()`` functions MUST be called from the ``main`` loop. The ``isc_nm_listen*()`` functions MUST be called from the ``main`` loop.
The general design of Network Manager is based on callbacks. An extra care must The general design of Network Manager is based on callbacks. Callback
be taken when implementing new functions because the callbacks MUST be called functions should always be called asynchronously by the network manager,
asynchronously because the caller might be inside a lock and the same lock must because the caller might be holding a lock, and the callback may try to
be acquired in the callback. This doesn't mean that the callback must be always acquire the same lock. So even if a network manager function is able to
called asynchronously, because sometimes we are already in the libuv callback determine a result immediately, the callback must be scheduled onto the
and thus we can just call the callback directly, but in other places, especially event loop instead of executed directly.
when returning an error, the control hasn't been returned to the caller yet and
in such case, the callback must be scheduled onto the event loop instead of
executing it directly.

View File

@ -46,7 +46,7 @@ result information as the return value of the function. E.g.
isc_result_t result; isc_result_t result;
result = isc_task_send(task, &event); result = isc_stdio_open(filename, 0644, &fp);
Note that an explicit result type is used, instead of mixing the error result Note that an explicit result type is used, instead of mixing the error result
type with the normal result type. E.g. the C library routine getc() can type with the normal result type. E.g. the C library routine getc() can

View File

@ -764,24 +764,18 @@ described for the public interfaces, except `{library}` and `{module}` are
separated by a double-underscore. This indicates that the name is separated by a double-underscore. This indicates that the name is
internal, its API is not as formal as the public API, and thus it might internal, its API is not as formal as the public API, and thus it might
change without any sort of notice. Examples of this usage include change without any sort of notice. Examples of this usage include
`dns__zone_loadpending()` and `isc__taskmgr_ready()`. `dns__zone_loadpending()` and `isc__mem_printallactive()`.
In many cases, a public interface is instantiated by a private back-end In some cases, a public interface is instantiated by a private back-end
implementation. The double-underscore naming style is sometimes used in implementation. The private interface implementations are typically
that situation; for example, `isc_task_attach()` calls the `attach` static functions that are pointed to by "method" tables. For example,
function provided by a task API implementation; in BIND 9, this function the `dns_db` interface is implemented in several places, including
is provided by `isc__task_attach()`. `lib/dns/rbtdb.c` (the red-black tree database used for internal storage of
zones and cache data) and `lib/dns/sdlz.c` (an interface to DLZ modules).
Other times, private interface implementations are static functions
that are pointed to by "method" tables. For example, the `dns_db`
interface is implemented in several places, including `lib/dns/rbtdb.c`
(the red-black tree database used for internal storage of zones and
cache data) and `lib/dns/sdlz.c` (an interface to DLZ modules).
An object of type `dns_dbmethods_t` is created for each of these, An object of type `dns_dbmethods_t` is created for each of these,
containing function pointers to the local implementations of each containing function pointers to the local implementations of each of the
of the `dns_db` API functions. The `dns_db_findnode()` function `dns_db` API functions. The `dns_db_findnode()` function is provided by
is provided by static functions called `findnode()` in each file, static functions called `findnode()` in each file, and so on.
and so on.
#### Initialization #### Initialization

View File

@ -530,8 +530,8 @@ void
dns_view_thaw(dns_view_t *view); dns_view_thaw(dns_view_t *view);
/*%< /*%<
* Thaw view. This allows zones to be added or removed at runtime. This is * Thaw view. This allows zones to be added or removed at runtime. This is
* NOT thread-safe; the caller MUST have run isc_task_exclusive() prior to * NOT thread-safe; the caller MUST have paused the loopmgr prior to thawing
* thawing the view. * the view.
* *
* Requires: * Requires:
* *

View File

@ -1133,17 +1133,17 @@ dns_zone_clearxfracl(dns_zone_t *zone);
bool bool
dns_zone_getupdatedisabled(dns_zone_t *zone); dns_zone_getupdatedisabled(dns_zone_t *zone);
/*%< /*%<
* Return update disabled. * Return true if updates are disabled.
* Transient unless called when running in isc_task_exclusive() mode.
*/ */
void void
dns_zone_setupdatedisabled(dns_zone_t *zone, bool state); dns_zone_setupdatedisabled(dns_zone_t *zone, bool state);
/*%< /*%<
* Set update disabled. * Enable or disable updates.
* Should only be called only when running in isc_task_exclusive() mode. *
* Failure to do so may result in updates being committed after the * This should only be called when running in exclusive mode;
* call has been made. * otherwise, updates that were already in progress could be
* committed after disabling.
*/ */
bool bool

View File

@ -14583,7 +14583,7 @@ zone_timer(void *arg) {
static void static void
zone_timer_stop(dns_zone_t *zone) { zone_timer_stop(dns_zone_t *zone) {
zone_debuglog(zone, __func__, 10, "settimer inactive"); zone_debuglog(zone, __func__, 10, "stop zone timer");
if (zone->timer != NULL) { if (zone->timer != NULL) {
isc_timer_stop(zone->timer); isc_timer_stop(zone->timer);
} }

View File

@ -170,16 +170,12 @@ isc__nmhandle_attach(isc_nmhandle_t *handle, isc_nmhandle_t **dest FLARG);
void void
isc__nmhandle_detach(isc_nmhandle_t **handlep FLARG); isc__nmhandle_detach(isc_nmhandle_t **handlep FLARG);
/*%< /*%<
* Increment/decrement the reference counter in a netmgr handle, * Increment/decrement the reference counter in a netmgr handle.
* but (unlike the attach/detach functions) do not change the pointer
* value. If reference counters drop to zero, the handle can be
* marked inactive, possibly triggering deletion of its associated
* socket.
* *
* (This will be used to prevent a client from being cleaned up when * When the detach function is called on a thread other than the one that
* it's passed to an isc_task event handler. The libuv code would not * created the handle, it is scheduled to asynchronously by the handle's
* otherwise know that the handle was in use and might free it, along * event loop. When references go to zero, the associated socket will be
* with the client.) * closed and deleted.
*/ */
#undef FLARG #undef FLARG