Lely core libraries  2.2.5
loop.c File Reference

This file is part of the event library; it contains the implementation of the polling event loop functions. More...

#include "ev.h"
#include <lely/libc/stdatomic.h>
#include <lely/libc/threads.h>
#include <lely/ev/exec.h>
#include <lely/ev/loop.h>
#include <lely/ev/std_exec.h>
#include <lely/ev/task.h>
#include <lely/util/dllist.h>
#include <lely/util/errnum.h>
#include <lely/util/time.h>
#include <lely/util/util.h>
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
Include dependency graph for loop.c:

Go to the source code of this file.

Data Structures

struct  ev_loop_ctx
 An event loop context. More...
 
struct  ev_loop_thrd
 An event loop thread. More...
 
struct  ev_loop
 A polling event loop. More...
 

Macros

#define LELY_EV_LOOP_CTX_MAX_UNUSED   16
 The maximum number of unused contexts per event loop.
 

Functions

ev_loop_tev_loop_create (ev_poll_t *poll, size_t npoll, int poll_task)
 Creates a new polling event loop. More...
 
void ev_loop_destroy (ev_loop_t *loop)
 Destroys a polling event loop. More...
 
ev_poll_tev_loop_get_poll (const ev_loop_t *loop)
 Returns a pointer to the polling instance used by the event loop, or NULL if the loop does not poll.
 
ev_exec_tev_loop_get_exec (const ev_loop_t *loop)
 Returns a pointer to the executor corresponding to the event loop.
 
void ev_loop_stop (ev_loop_t *loop)
 Stops the event loop. More...
 
int ev_loop_stopped (const ev_loop_t *loop)
 Returns 1 if the event loop is stopped, and 0 if not.
 
void ev_loop_restart (ev_loop_t *loop)
 Restarts an event loop. More...
 
size_t ev_loop_wait (ev_loop_t *loop, ev_future_t *future)
 Equivalent to

size_t n = 0;
while (ev_loop_wait_one(loop, future))
n += n < SIZE_MAX;
return n;

.

 
size_t ev_loop_wait_until (ev_loop_t *loop, ev_future_t *future, const struct timespec *abs_time)
 Equivalent to

size_t n = 0;
while (ev_loop_wait_one_until(loop, future, abs_time))
n += n < SIZE_MAX;
return n;

.

 
size_t ev_loop_wait_one (ev_loop_t *loop, ev_future_t *future)
 If the event loop has pending tasks, runs a single task. More...
 
size_t ev_loop_wait_one_until (ev_loop_t *loop, ev_future_t *future, const struct timespec *abs_time)
 If the event loop has pending tasks, runs a single task. More...
 
void * ev_loop_self (void)
 Returns the identifier of the calling thread. More...
 
int ev_loop_kill (ev_loop_t *loop, void *thr_)
 Interrupts an event loop running on the specified thread. More...
 

Detailed Description

This file is part of the event library; it contains the implementation of the polling event loop functions.

See also
lely/ev/loop.h
Author
J. S. Seldenthuis jseld.nosp@m.enth.nosp@m.uis@l.nosp@m.ely..nosp@m.com

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Definition in file loop.c.

Function Documentation

◆ ev_loop_create()

ev_loop_t* ev_loop_create ( ev_poll_t poll,
size_t  npoll,
int  poll_task 
)

Creates a new polling event loop.

Parameters
polla pointer to the polling instance to be used to poll for events. If poll is NULL, the event loop does not poll.
npollthe maximum number of threads allowed to poll (i.e., invoke ev_poll_wait(poll, ...) concurrently. If npoll is 0, there is no limit. If poll is NULL, this parameter is ignored. On platforms supporting I/O completion ports (Windows) it is generally most efficient to allow all threads to poll (i.e., npoll == 0), while on platforms using the reactor pattern (POSIX) it is best to allow a single polling thread (npoll == 1).
poll_taskif poll_task is non-zero, a polling task is queued to the event loop and requeued when executed. This can prevent starvation, since the event loop otherwise only polls if no tasks are pending, which may never happen in CPU-bound situations. Under light loads, however, the extra polling overhead may harm performance. If poll is NULL, this parameter is ignored.
Returns
a pointer to the new event loop, or NULL on error. In the latter case, the error number can be obtained with get_errc().

Definition at line 286 of file loop.c.

◆ ev_loop_destroy()

void ev_loop_destroy ( ev_loop_t loop)

Destroys a polling event loop.

See also
ev_loop_create()

Definition at line 313 of file loop.c.

◆ ev_loop_stop()

void ev_loop_stop ( ev_loop_t loop)

Stops the event loop.

Ongoing calls to ev_loop_run(), ev_loop_run_until(), ev_loop_run_one() and ev_loop_run_one_until() will terminate and future calls will return 0 immediately.

If this function is invoked explicitly, the loop MAY still contain outstanding work and it MAY NOT be safe to destroy submitted, but not completed, tasks. Invoke ev_loop_poll(), preceded by ev_loop_restart() if necessary, to ensure no outstanding work remains.

Postcondition
ev_loop_stopped() returns 1.

Definition at line 338 of file loop.c.

◆ ev_loop_restart()

void ev_loop_restart ( ev_loop_t loop)

Restarts an event loop.

Postcondition
ev_loop_stopped() returns 0.

Definition at line 367 of file loop.c.

◆ ev_loop_wait_one()

size_t ev_loop_wait_one ( ev_loop_t loop,
ev_future_t future 
)

If the event loop has pending tasks, runs a single task.

Otherwise, blocks while the loop has outstanding work or until the loop is stopped or the specified future (if not NULL) becomes ready. If the loop has no outstanding work, ev_loop_stop() is invoked. Note that more than one task MAY be executed if the task function invokes ev_exec_dispatch().

Returns
1 if a task was executed, and 0 otherwise.

Definition at line 404 of file loop.c.

◆ ev_loop_wait_one_until()

size_t ev_loop_wait_one_until ( ev_loop_t loop,
ev_future_t future,
const struct timespec *  abs_time 
)

If the event loop has pending tasks, runs a single task.

Otherwise, blocks while the loop has outstanding work or until the loop is stopped or the specified future (if not NULL) becomes ready or the absolute timeout expires. If abs_time is NULL, this function will not block. If the loop has no outstanding work, ev_loop_stop() is invoked. Note that more than one task MAY be executed if the task function invokes ev_exec_dispatch().

Returns
1 if a task was executed, and 0 otherwise. If no task was executed because of a timeout, get_errnum() returns ERRNUM_TIMEDOUT.

Definition at line 413 of file loop.c.

◆ ev_loop_self()

void* ev_loop_self ( void  )

Returns the identifier of the calling thread.

This identifier can be used to interrupt a call to one of the run funtions from another thread with ev_loop_kill().

Definition at line 423 of file loop.c.

◆ ev_loop_kill()

int ev_loop_kill ( ev_loop_t loop,
void *  thr 
)

Interrupts an event loop running on the specified thread.

In case of a nested event loop, this function only interrupts the inner loop.

Returns
0 on success, or -1 on error. In the latter case, the error code can be obtained with get_errc().

Definition at line 429 of file loop.c.