42static void ev_strand_exec_on_task_init(
ev_exec_t *exec);
43static void ev_strand_exec_on_task_fini(
ev_exec_t *exec);
50 &ev_strand_exec_on_task_init,
51 &ev_strand_exec_on_task_fini,
52 &ev_strand_exec_dispatch,
53 &ev_strand_exec_defer,
54 &ev_strand_exec_defer,
55 &ev_strand_exec_abort,
72static void ev_strand_func(
struct ev_task *task);
77static const int ev_strand_thrd;
85 struct ev_strand *strand = malloc(
sizeof(*strand));
91 return strand ? &strand->exec_vptr : NULL;
95ev_strand_free(
void *ptr)
103 struct ev_strand *strand = ev_strand_from_exec(exec);
106 strand->exec_vptr = &ev_strand_exec_vtbl;
108 strand->inner_exec = inner_exec;
110 strand->inner_exec, &ev_strand_func);
129 struct ev_strand *strand = ev_strand_from_exec(exec);
131 ev_strand_exec_abort(exec, NULL);
141 while (strand->posted) {
163 ev_exec_t *tmp = ev_strand_init(exec, inner_exec);
173 ev_strand_free((
void *)exec);
183 ev_strand_fini(exec);
184 ev_strand_free((
void *)exec);
191 struct ev_strand *strand = ev_strand_from_exec(exec);
193 return strand->inner_exec;
197ev_strand_exec_on_task_init(
ev_exec_t *exec)
199 struct ev_strand *strand = ev_strand_from_exec(exec);
205ev_strand_exec_on_task_fini(
ev_exec_t *exec)
207 struct ev_strand *strand = ev_strand_from_exec(exec);
215 struct ev_strand *strand = ev_strand_from_exec(exec);
217 assert(!task->
exec || task->
exec == exec);
221 ev_strand_exec_on_task_init(exec);
226 if (strand->thr == &ev_strand_thrd) {
232 ev_strand_exec_on_task_fini(exec);
236 int post = !strand->posted;
250 struct ev_strand *strand = ev_strand_from_exec(exec);
252 assert(!task->
exec || task->
exec == exec);
256 ev_strand_exec_on_task_init(exec);
262 int post = !strand->posted;
274 struct ev_strand *strand = ev_strand_from_exec(exec);
292 ev_strand_exec_on_task_fini(exec);
299ev_strand_func(
struct ev_task *task)
310 assert(!strand->thr);
311 strand->thr = &ev_strand_thrd;
315 assert(task->
exec == exec);
318 ev_strand_exec_on_task_fini(exec);
322 assert(strand->thr == &ev_strand_thrd);
325 assert(strand->posted == 1);
326 int post = strand->posted = !
sllist_empty(&strand->queue);
335ev_strand_from_exec(
const ev_exec_t *exec)
This header file is part of the utilities library; it contains the native and platform-independent er...
int get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function.
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
int errno2c(int errnum)
Transforms a standard C error number to a native error code.
This header file is part of the event library; it contains the abstract task executor interface.
size_t ev_exec_abort(ev_exec_t *exec, struct ev_task *task)
Aborts the specified task submitted to *exec, if it has not yet begun executing, or all pending tasks...
void ev_exec_post(ev_exec_t *exec, struct ev_task *task)
Submits *task to *exec for execution.
void ev_exec_on_task_fini(ev_exec_t *exec)
Undoes the effect of a previous call to ev_exec_on_task_init().
void ev_exec_on_task_init(ev_exec_t *exec)
Indicates to the specified executor that a task will be submitted for execution in the future.
#define _Thread_local
An object whose identifier is declared with the storage-class specifier _Thread_local has thread stor...
const struct ev_exec_vtbl *const ev_exec_t
An abstract task executor.
This is the public header file of the utilities library.
#define structof(ptr, type, member)
Obtains the address of a structure from the address of one of its members.
void sllist_init(struct sllist *list)
Initializes a singly-linked list.
struct sllist * sllist_append(struct sllist *dst, struct sllist *src)
Appends the singly-linked list at src to the one at dst.
struct slnode * sllist_remove(struct sllist *list, struct slnode *node)
Removes a node from a singly-linked list.
void sllist_push_back(struct sllist *list, struct slnode *node)
Pushes a node to the back of a singly-linked list.
int sllist_empty(const struct sllist *list)
Returns 1 if the singly-linked list is empty, and 0 if not.
struct slnode * sllist_pop_front(struct sllist *list)
Pops a node from the front of a singly-linked list.
This is the internal header file of the event library.
This header file is part of the C11 and POSIX compatibility library; it includes <stdatomic....
This header file is part of the C11 and POSIX compatibility library; it includes <stdint....
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib....
void ev_strand_destroy(ev_exec_t *exec)
Destroys a strand executor.
ev_exec_t * ev_strand_get_inner_exec(const ev_exec_t *exec)
Returns a pointer to the inner executor of a strand.
ev_exec_t * ev_strand_create(ev_exec_t *inner_exec)
Creates a strand executor.
This header file is part of the event library; it contains the strand executor declarations.
ev_task_func_t * func
The function to be invoked when the task is run.
ev_exec_t * exec
A pointer to the executor to which the task is (to be) submitted.
This header file is part of the event library; it contains the task declarations.
struct ev_task * ev_task_from_node(struct slnode *node)
Converts a pointer to a node in a queue to the address of the task containing the node.
#define EV_TASK_INIT(exec, func)
The static initializer for ev_task.
This header file is part of the C11 and POSIX compatibility library; it includes <threads....
int mtx_init(mtx_t *mtx, int type)
Creates a mutex object with properties indicated by type, which must have one of the four values:
int mtx_lock(mtx_t *mtx)
Blocks until it locks the mutex at mtx.
void thrd_yield(void)
Endeavors to permit other threads to run, even if the current thread would ordinarily continue to run...
@ thrd_success
Indicates that the requested operation succeeded.
int mtx_unlock(mtx_t *mtx)
Unlocks the mutex at mtx.
pthread_mutex_t mtx_t
A complete object type that holds an identifier for a mutex.
void mtx_destroy(mtx_t *mtx)
Releases any resources used by the mutex at mtx.
@ mtx_plain
A mutex type that supports neither timeout nor test and return.