Mstdlib-1.24.0

Typedefs

typedef enum M_event_type M_event_type_t
 
typedef struct M_event_trigger M_event_trigger_t
 
typedef struct M_event_timer M_event_timer_t
 
typedef struct M_event M_event_t
 
typedef void(* M_event_callback_t) (M_event_t *event, M_event_type_t type, M_io_t *io, void *cb_arg)
 
typedef enum M_event_timer_modes M_event_timer_mode_t
 
typedef enum M_event_status M_event_status_t
 
typedef enum M_event_err M_event_err_t
 

Enumerations

enum  M_event_type {
  M_EVENT_TYPE_CONNECTED = 0 ,
  M_EVENT_TYPE_ACCEPT ,
  M_EVENT_TYPE_READ ,
  M_EVENT_TYPE_DISCONNECTED ,
  M_EVENT_TYPE_ERROR ,
  M_EVENT_TYPE_WRITE ,
  M_EVENT_TYPE_OTHER
}
 
enum  M_EVENT_FLAGS {
  M_EVENT_FLAG_NONE = 0 ,
  M_EVENT_FLAG_NOWAKE = 1 << 0 ,
  M_EVENT_FLAG_EXITONEMPTY = 1 << 1 ,
  M_EVENT_FLAG_EXITONEMPTY_NOTIMERS = 1 << 2 ,
  M_EVENT_FLAG_NON_SCALABLE = 1 << 3
}
 
enum  M_event_statistic_t {
  M_EVENT_STATISTIC_WAKE_COUNT ,
  M_EVENT_STATISTIC_OSEVENT_COUNT ,
  M_EVENT_STATISTIC_SOFTEVENT_COUNT ,
  M_EVENT_STATISTIC_TIMER_COUNT ,
  M_EVENT_STATISTIC_PROCESS_TIME_MS
}
 
enum  M_event_timer_modes {
  M_EVENT_TIMER_MODE_RELATIVE = 1 ,
  M_EVENT_TIMER_MODE_MONOTONIC = 2
}
 
enum  M_event_status {
  M_EVENT_STATUS_RUNNING = 0 ,
  M_EVENT_STATUS_PAUSED = 1 ,
  M_EVENT_STATUS_RETURN = 2 ,
  M_EVENT_STATUS_DONE = 3
}
 
enum  M_event_err {
  M_EVENT_ERR_DONE = 1 ,
  M_EVENT_ERR_TIMEOUT = 2 ,
  M_EVENT_ERR_RETURN = 3 ,
  M_EVENT_ERR_MISUSE = 4
}
 

Functions

M_event_tM_event_create (M_uint32 flags)
 
M_event_tM_event_pool_create (size_t max_threads)
 
M_event_tM_event_get_pool (M_event_t *event)
 
M_event_tM_io_get_event (M_io_t *io)
 
void M_event_destroy (M_event_t *event)
 
M_bool M_event_add (M_event_t *event, M_io_t *io, M_event_callback_t callback, void *cb_data)
 
M_bool M_event_edit_io_cb (M_io_t *io, M_event_callback_t callback, void *cb_data)
 
M_event_callback_t M_event_get_io_cb (M_io_t *io, void **cb_data_out)
 
void M_event_remove (M_io_t *io)
 
M_event_trigger_tM_event_trigger_add (M_event_t *event, M_event_callback_t callback, void *cb_data)
 
void M_event_trigger_remove (M_event_trigger_t *trigger)
 
M_bool M_event_trigger_edit_cb (M_event_trigger_t *trigger, M_event_callback_t callback, void *cb_data)
 
void M_event_trigger_signal (M_event_trigger_t *trigger)
 
M_event_timer_tM_event_timer_add (M_event_t *event, M_event_callback_t callback, void *cb_data)
 
M_bool M_event_timer_start (M_event_timer_t *timer, M_uint64 interval_ms)
 
M_bool M_event_timer_stop (M_event_timer_t *timer)
 
M_bool M_event_timer_reset (M_event_timer_t *timer, M_uint64 interval_ms)
 
M_bool M_event_timer_adjust (M_event_timer_t *timer, M_uint64 interval_ms)
 
M_bool M_event_timer_set_starttv (M_event_timer_t *timer, M_timeval_t *start_tv)
 
M_bool M_event_timer_set_endtv (M_event_timer_t *timer, M_timeval_t *end_tv)
 
M_bool M_event_timer_set_firecount (M_event_timer_t *timer, size_t cnt)
 
M_bool M_event_timer_set_autoremove (M_event_timer_t *timer, M_bool enabled)
 
M_bool M_event_timer_set_mode (M_event_timer_t *timer, M_event_timer_mode_t mode)
 
M_uint64 M_event_timer_get_remaining_ms (M_event_timer_t *timer)
 
M_uint64 M_event_timer_get_interval_ms (M_event_timer_t *timer)
 
M_bool M_event_timer_get_status (M_event_timer_t *timer)
 
M_event_timer_tM_event_timer_oneshot (M_event_t *event, M_uint64 interval_ms, M_bool autoremove, M_event_callback_t callback, void *cb_data)
 
M_bool M_event_timer_remove (M_event_timer_t *timer)
 
M_bool M_event_timer_edit_cb (M_event_timer_t *timer, M_event_callback_t callback, void *cb_data)
 
M_bool M_event_queue_task (M_event_t *event, M_event_callback_t callback, void *cb_data)
 
M_event_err_t M_event_loop (M_event_t *event, M_uint64 timeout_ms)
 
void M_event_done (M_event_t *event)
 
void M_event_return (M_event_t *event)
 
void M_event_done_with_disconnect (M_event_t *event, M_uint64 timeout_before_disconnect_ms, M_uint64 disconnect_timeout_ms)
 
M_event_status_t M_event_get_status (M_event_t *event)
 
M_uint64 M_event_get_statistic (M_event_t *event, M_event_statistic_t type)
 
size_t M_event_num_objects (M_event_t *event)
 
const char * M_event_type_string (M_event_type_t type)
 

Detailed Description

Cross platform event based processing. A platform specific backend will be used as the underlying event system but all events will be exposed though this interface. No platform specific knowledge is needed.

Developers used to working with macOS event loop style of programming can use this event system to use that paradigm on other platforms. In this scenario most events would be triggered as OTHER. Some sort of tracking would be necessary to determine why an event was triggered if the same callback is used for multiple situations.

The event system is thread safe allowing io objects and times can be added to and moved between different event loops running on different threads. Triggers can be triggered from different threads. Destruction of an io object from a different thread will be queued in the event loop it's running on.

Note: the CONNECTED event will be triggered when a io object is added to an event loop using M_event_add().

Example application that demonstrates read/write events, timers, and queued tasks.

#include <mstdlib/mstdlib.h>
#include <mstdlib/mstdlib_io.h>
typedef struct {
M_buf_t *buf;
M_parser_t *parser;
M_io_t *io; // Necessary for the queued task and timer to have the correct io object.
} ldata_t;
static void add_queued_data(M_event_t *el, M_event_type_t etype, M_io_t *io, void *thunk)
{
ldata_t *ldata = thunk;
(void)el;
(void)etype;
M_buf_add_str(ldata->buf, "STARTING\n");
M_io_write_from_buf(ldata->io, ldata->buf);
}
static void add_data(M_event_t *el, M_event_type_t etype, M_io_t *io, void *thunk)
{
ldata_t *ldata = thunk;
static int i = 1;
(void)el;
(void)etype;
M_buf_add_str(ldata->buf, "TEST ");
M_buf_add_int(ldata->buf, i++);
M_buf_add_byte(ldata->buf, '\n');
M_io_write_from_buf(ldata->io, ldata->buf);
}
static void stop(M_event_t *el, M_event_type_t etype, M_io_t *io, void *thunk)
{
(void)etype;
(void)io;
(void)thunk;
}
static void run_cb(M_event_t *el, M_event_type_t etype, M_io_t *io, void *thunk)
{
ldata_t *ldata = thunk;
char *out;
switch (etype) {
break;
M_io_read_into_parser(io, ldata->parser);
out = M_parser_read_strdup(ldata->parser, M_parser_len(ldata->parser));
M_printf("%s", out);
M_free(out);
break;
// Write any data pending in the buffer.
M_io_write_from_buf(io, ldata->buf);
break;
break;
break;
}
}
int main(int argc, char *argv)
{
M_event_t *el;
M_io_t *io;
ldata_t ldata;
ldata.buf = M_buf_create();
ldata.io = io;
M_event_add(el, io, run_cb, &ldata);
M_event_queue_task(el, add_queued_data, &ldata);
timer = M_event_timer_add(el, add_data, &ldata);
M_event_timer_start(timer, 500);
timer = M_event_timer_add(el, stop, NULL);
M_event_timer_start(timer, 5000);
M_event_loop(el, M_TIMEOUT_INF);
M_buf_cancel(ldata.buf);
M_parser_destroy(ldata.parser);
return 0;
}
void M_buf_add_byte(M_buf_t *buf, unsigned char byte)
void M_buf_add_int(M_buf_t *buf, M_int64 n)
struct M_buf M_buf_t
Definition: m_buf.h:77
M_buf_t * M_buf_create(void) M_WARN_UNUSED_RESULT M_MALLOC
void M_buf_add_str(M_buf_t *buf, const char *str)
void M_buf_cancel(M_buf_t *buf) M_FREE(1)
M_bool M_event_timer_start(M_event_timer_t *timer, M_uint64 interval_ms)
M_event_timer_t * M_event_timer_add(M_event_t *event, M_event_callback_t callback, void *cb_data)
void M_event_destroy(M_event_t *event)
enum M_event_type M_event_type_t
Definition: m_event.h:189
struct M_event M_event_t
Definition: m_event.h:210
M_bool M_event_add(M_event_t *event, M_io_t *io, M_event_callback_t callback, void *cb_data)
void M_event_done(M_event_t *event)
M_event_err_t M_event_loop(M_event_t *event, M_uint64 timeout_ms)
M_bool M_event_queue_task(M_event_t *event, M_event_callback_t callback, void *cb_data)
M_event_t * M_event_create(M_uint32 flags)
void M_event_done_with_disconnect(M_event_t *event, M_uint64 timeout_before_disconnect_ms, M_uint64 disconnect_timeout_ms)
struct M_event_timer M_event_timer_t
Definition: m_event.h:203
@ M_EVENT_TYPE_WRITE
Definition: m_event.h:184
@ M_EVENT_TYPE_ACCEPT
Definition: m_event.h:174
@ M_EVENT_TYPE_DISCONNECTED
Definition: m_event.h:176
@ M_EVENT_TYPE_OTHER
Definition: m_event.h:185
@ M_EVENT_TYPE_READ
Definition: m_event.h:175
@ M_EVENT_TYPE_CONNECTED
Definition: m_event.h:173
@ M_EVENT_TYPE_ERROR
Definition: m_event.h:181
@ M_EVENT_FLAG_NONE
Definition: m_event.h:232
ssize_t M_printf(const char *fmt,...)
M_io_error_t M_io_loopback_create(M_io_t **io_out)
M_io_error_t M_io_read_into_parser(M_io_t *comm, M_parser_t *parser)
void M_io_destroy(M_io_t *comm)
struct M_io M_io_t
Definition: m_io.h:59
M_io_error_t M_io_write_from_buf(M_io_t *comm, M_buf_t *buf)
void M_free(void *ptr) M_FREE(1)
size_t M_parser_len(const M_parser_t *parser)
void M_parser_destroy(M_parser_t *parser)
char * M_parser_read_strdup(M_parser_t *parser, size_t len)
struct M_parser M_parser_t
Definition: m_parser.h:52
M_parser_t * M_parser_create(M_uint32 flags)
@ M_PARSER_FLAG_NONE
Definition: m_parser.h:60

Typedef Documentation

◆ M_event_type_t

Events that can be generated.

◆ M_event_trigger_t

typedef struct M_event_trigger M_event_trigger_t

Handle for an event trigger

◆ M_event_timer_t

typedef struct M_event_timer M_event_timer_t

Handle for an event timer

◆ M_event_t

typedef struct M_event M_event_t

◆ M_event_callback_t

typedef void(* M_event_callback_t) (M_event_t *event, M_event_type_t type, M_io_t *io, void *cb_arg)

Definition for a function callback that is called every time an event is triggered by the event subsystem.

Parameters
[in]eventInternal event object, this is an event-thread specific object which could be the member of a pool. This object may be used to add new events to the same event thread, or M_event_get_pool() can be used to retrieve the master pool handle for distributing events across threads.
[in]typeThe type of event that has been triggered, see M_event_type_t. Always M_EVENT_TYPE_OTHER for trigger, timer, and queued tasks.
[in]ioPointer to the M_io_t object associated with the event, or NULL for trigger, timer, and queued tasks.
[in]cb_argUser-specified callback argument registered when the object was added to the event handle.

◆ M_event_timer_mode_t

Timer modes of operation

◆ M_event_status_t

Possible event status codes for an event loop or pool

◆ M_event_err_t

typedef enum M_event_err M_event_err_t

Possible return codes for M_event_loop()

Enumeration Type Documentation

◆ M_event_type

Events that can be generated.

Events are enumerated in priority of delivery order

Enumerator
M_EVENT_TYPE_CONNECTED 

The connection has been completed

M_EVENT_TYPE_ACCEPT 

A new incoming connection is ready to be accepted

M_EVENT_TYPE_READ 

There is available data to be read

M_EVENT_TYPE_DISCONNECTED 

The connection has been successfully disconnected. This is only triggered after a disconnect request, Otherwise most failures are determined by a Read event followed by a read failure. The connection object should be closed after this.

M_EVENT_TYPE_ERROR 

An error occurred. Most likely during connection establishment by a higher-level protocol. The connection object should be closed after this.

M_EVENT_TYPE_WRITE 

There is room available in the write buffer

M_EVENT_TYPE_OTHER 

Some other event occurred, such as a triggered or timer-based event

◆ M_EVENT_FLAGS

Possible list of flags that can be used when initializing an event loop

Enumerator
M_EVENT_FLAG_NONE 

No specialized flags

M_EVENT_FLAG_NOWAKE 

We will never need to wake the event loop from another thread. Not recommended to use as some internal subsystems (like M_dns) may need to use it without your knowledge.

M_EVENT_FLAG_EXITONEMPTY 

Exit the event loop when there are no registered events

M_EVENT_FLAG_EXITONEMPTY_NOTIMERS 

When combined with M_EVENT_FLAG_EXITONEMPTY, will ignore timers

M_EVENT_FLAG_NON_SCALABLE 

Utilize the 'non-scalable/small' event subsystem, generally implemented using poll() instead of the more scalable solution using kqueue() or epoll(). The main reason one might want to use this is if a large number of event loops are being created such as when using the blocking APIs, using the scalable solution generally consumes additional file descriptors which may not be desirable. Not all systems have different subsystems, in which case this flag will be ignored.

◆ M_event_statistic_t

Possible values to pass to M_event_get_statistic()

Enumerator
M_EVENT_STATISTIC_WAKE_COUNT 

Get the number of times the event loop has woken due to some sort of event

M_EVENT_STATISTIC_OSEVENT_COUNT 

Get the number of OS-delivered events

M_EVENT_STATISTIC_SOFTEVENT_COUNT 

Get the number of soft-events delivered

M_EVENT_STATISTIC_TIMER_COUNT 

Get the number of timer (or queued) events delivered

M_EVENT_STATISTIC_PROCESS_TIME_MS 

Get the about of non-idle time spent by the event loop in ms

◆ M_event_timer_modes

Timer modes of operation

Enumerator
M_EVENT_TIMER_MODE_RELATIVE 

The interval will be added on to the end of the last actual run time

M_EVENT_TIMER_MODE_MONOTONIC 

The interval will be added on to the last scheduled run time, even if that time has already passed. This means you could have events that run closer together than the specified interval if it is trying to "catch up" due to a long running event handler. In general this is more useful for needing an event to run as close to a certain interval as possible without skewing the interval between events by the amount of time it takes to handle event callbacks.

◆ M_event_status

Possible event status codes for an event loop or pool

Enumerator
M_EVENT_STATUS_RUNNING 

The event loop is current running and processing events

M_EVENT_STATUS_PAUSED 

The event loop is not running due to not being started or a timeout occurring

M_EVENT_STATUS_RETURN 

The event loop was explicitly told to return using M_event_return()

M_EVENT_STATUS_DONE 

The event loop either exited due to M_event_done() or there were no objects remaining as the event loop was initialized with M_EVENT_FLAG_EXITONEMPTY

◆ M_event_err

Possible return codes for M_event_loop()

Enumerator
M_EVENT_ERR_DONE 

The event loop either exited due to M_event_done() or M_event_done_with_disconnect() or there were no objects remaining as the event loop was initialized with M_EVENT_FLAG_EXITONEMPTY

M_EVENT_ERR_TIMEOUT 

The timeout specified in M_event_loop() has expired

M_EVENT_ERR_RETURN 

M_event_return() was explicitly called

M_EVENT_ERR_MISUSE 

Misuse, e.g. NULL event handle

Function Documentation

◆ M_event_create()

M_event_t * M_event_create ( M_uint32  flags)

Create a base event loop object.

An event loop is typically run in the main process thread and will block until process termination. IO and timer objects are enqueued into the event loop and dispatched within the event loop. Event loops are more efficient and scalable than using a thread per tracked io object.

Parameters
[in]flagsOne or more enum M_EVENT_FLAGS
Returns
Initialized event loop object.

◆ M_event_pool_create()

M_event_t * M_event_pool_create ( size_t  max_threads)

Create a pool of M_event_t objects bound to a master pool handle to distribute load of event handling across multiple threads.

One thread per CPU core will be created for handling events, up to the maximum specified during creationg of the pool. When an object is added to the event pool handle, an internal search is performed, and the least-loaded thread will receive the new object.

Objects bound to the same internal event object will always execute in the same thread which may be desirable for co-joined objects (otherwise additional locking may be required since multiple events could fire from different threads for some shared resource). Typically this co-joined objects will be created based on events that have been fired, so the M_event_t object returned from the M_event_callback_t callback should be used to ensure they stay co-joined.

For non co-joined objects, always ensure the event handle used is the pool by calling M_event_get_pool() otherwise load will not be distributed at all.

Parameters
[in]max_threadsArtificial limitation on the maximum number of threads, the actual number of threads will be the lesser of this value and the number of cpu cores in the system. Use 0 for this value to simply use the number of cpu cores.
Returns
Initialized event pool, or in the case only a single thread would be used, a normal event object.

◆ M_event_get_pool()

M_event_t * M_event_get_pool ( M_event_t event)

Retrieve the distributed pool handle for balancing the load across an event pool, or self if not part of a pool.

This should be called to get the event handle during M_event_add(), M_event_trigger_add(), M_event_timer_add(), M_event_timer_oneshot(), or M_event_queue_task() as by default tasks will otherwise not be distributed if using the event handle returned by the M_event_callback_t. In some cases it is desirable to ensure co-joined objects run within the same event thread and therefore desirable to enqueue multiple tasks for an internal event loop handle rather than the distributed pool.

Parameters
[in]eventPointer to event handle either returned by M_event_create(), M_event_pool_create(), or from an M_event_callback_t.
Returns
Pointer to event pool, or self if not part of a pool (or if a pool object already passed in).

◆ M_io_get_event()

M_event_t * M_io_get_event ( M_io_t io)

Get the registered event handle for the io object

Parameters
[in]ioIO object.
Returns
Event loop object associated with the io object.

◆ M_event_destroy()

void M_event_destroy ( M_event_t event)

Destroy the event loop or pool object

Parameters
[in]eventPointer to event handle either returned by M_event_create(), M_event_pool_create(), or from an M_event_callback_t.

◆ M_event_add()

M_bool M_event_add ( M_event_t event,
M_io_t io,
M_event_callback_t  callback,
void *  cb_data 
)

Add an io object to the event loop handle with a registered callback to deliver events to.

Adding handles to an event handle is threadsafe and can be executed either within an event callback or from a separate thread.

Parameters
[in]eventEvent handle to add the event to. If desirable to ensure this io object is distributed across a pool, it is recommended to pass the return value of M_event_get_pool() rather than the event handle returned by an M_event_callback_t callback.
[in]ioIO object to bind to the event handle.
[in]callbackCallback to be called when events occur.
[in]cb_dataOptional. User-defined callback data that will be passed to the user-defined callback. Use NULL if no data is necessary.
Returns
M_TRUE on success, or M_FALSE on failure (e.g. misuse, or io handle already bound to an event).

◆ M_event_edit_io_cb()

M_bool M_event_edit_io_cb ( M_io_t io,
M_event_callback_t  callback,
void *  cb_data 
)

Edit the callback associated with an io object in the event subsystem.

Editing allows a user to re-purpose an io object while processing events without needing to remove and re-add the object which may cause a loss of events.

Note
This will NOT cause a connected event to be triggered like M_event_add() does when you first add an io object to an event loop for already-established connections.
Parameters
[in]ioIO object to modify the callback for
[in]callbackCallback to set. NULL will set it to no callback.
[in]cb_dataData passed to callback function. NULL will remove the cb_data.
Returns
M_FALSE on error, such as if the IO object is not currently attached to an event loop.

◆ M_event_get_io_cb()

M_event_callback_t M_event_get_io_cb ( M_io_t io,
void **  cb_data_out 
)

Retrieve the callback associated with an io object in the event subsystem.

Parameters
[in]ioIO object to modify the callback for
[out]cb_data_outPointer to store callback data registered with callback.
Returns
registered callback, or NULL if none.

◆ M_event_remove()

void M_event_remove ( M_io_t io)

Remove an io object from its associated event handle.

Removing handles is threadsafe and can be executed either within an event callback or from a separate thread.

Parameters
[in]ioIO object.

◆ M_event_trigger_add()

M_event_trigger_t * M_event_trigger_add ( M_event_t event,
M_event_callback_t  callback,
void *  cb_data 
)

Create a user-callable trigger which will call the pre-registered callback. Useful for cross-thread completion or status update notifications. Triggering events is threadsafe.

Parameters
[in]eventEvent handle to add the event to. If desirable to ensure this io object is distributed across a pool, it is recommended to pass the return value of M_event_get_pool() rather than the event handle returned by an M_event_callback_t callback.
[in]callbackCallback to be called when the trigger is called.
[in]cb_dataOptional. User-defined callback data that will be passed to the user-defined callback. Use NULL if no data is necessary.
Returns
handle to trigger to be used to execute callback, or NULL on failure

◆ M_event_trigger_remove()

void M_event_trigger_remove ( M_event_trigger_t trigger)

Remove the user-callable trigger, once removed, the trigger is no longer valid and cannot be called.

Parameters
[in]triggerTrigger returned from M_event_trigger_add()

◆ M_event_trigger_edit_cb()

M_bool M_event_trigger_edit_cb ( M_event_trigger_t trigger,
M_event_callback_t  callback,
void *  cb_data 
)

Edit the callback associated with a trigger object in the event subsystem.

Editing allows a user to re-purpose a timer object while processing events without needing to remove and add a new object.

Parameters
[in]triggerTrigger returned from M_event_trigger_add()
[in]callbackCallback to set.
[in]cb_dataData passed to callback function. NULL will remove the cb_data.
Returns
M_FALSE on error, such as if the callback is NULL.

◆ M_event_trigger_signal()

void M_event_trigger_signal ( M_event_trigger_t trigger)

Signal the registered callback associated with the trigger to be called. This is threadsafe and may be called cross thread. If multiple signals are delivered before the callback is called, the duplicate signals will be silently discarded.

Parameters
[in]triggerTrigger returned from M_event_trigger_add()

◆ M_event_timer_add()

M_event_timer_t * M_event_timer_add ( M_event_t event,
M_event_callback_t  callback,
void *  cb_data 
)

Add a timer object to the event loop specified that will call the user-supplied callback when the timer expires. The timer is created in a stopped state and must be started before it will fire.

If the timer is associated with another object (e.g. co-joined) then the same event handle as the other object should be used.

Parameters
[in]eventEvent handle to add the timer to. If the event handle is a pool object, it will automatically distribute to an event thread.
[in]callbackUser-specified callback to call when the timer expires
[in]cb_dataOptional. User-specified data supplied to user-specified callback when executed.
Returns
Timer handle on success, NULL on failure.

◆ M_event_timer_start()

M_bool M_event_timer_start ( M_event_timer_t timer,
M_uint64  interval_ms 
)

Starts the specified timer with timeout specified. When the timeout expires, the callback associated with the timer will be executed.

Parameters
[in]timerTimer handle returned by M_event_timer_add()
[in]interval_msTime in milliseconds before the timer will expire. May only be 0 if the configured "firecount" is 1.
Returns
M_TRUE on success, M_FALSE on failure (such as timer already running or invalid use).

◆ M_event_timer_stop()

M_bool M_event_timer_stop ( M_event_timer_t timer)

Stops the specified timer.

Parameters
[in]timerTimer handle returned by M_event_timer_add()
Returns
M_TRUE on success, M_FALSE if timer not running

◆ M_event_timer_reset()

M_bool M_event_timer_reset ( M_event_timer_t timer,
M_uint64  interval_ms 
)

Restart the timer.

If the timer is already stopped, will simply start it again. If the timer has "autoremove" configured, the removal will be skipped on stop.

Parameters
[in]timerTimer handle returned by M_event_timer_add()
[in]interval_msTime in milliseconds before the timer will expire. If specified as 0, will use the same interval_ms as the original M_event_timer_start() call (NOTE: this is different behavior than the value of 0 for M_event_timer_start())
Returns
M_TRUE on success, M_FALSE on failure.

◆ M_event_timer_adjust()

M_bool M_event_timer_adjust ( M_event_timer_t timer,
M_uint64  interval_ms 
)

Adjust the timer interval_ms.

See also
M_event_timer_reset will stop the timer and schedule it to start again in interval_ms in the future. Adjusting the time does not stop the timer. It is used to prevent timers from not being run if the interval_ms is constancy being adjusted.

If the remaining time on the timer is > the new interval_ms the timer will be reset to run after the new interval_ms. If the timer has less time remaining than the new interval_ms it will be allowed to trigger after the remaining time and then be scheduled to run using the new interval_ms.

Parameters
[in]timerTimer handle returned by M_event_timer_add()
[in]interval_msTime in milliseconds before the timer will expire. 0 is considered an error.
Returns
M_TRUE on success, M_FALSE on failure.

◆ M_event_timer_set_starttv()

M_bool M_event_timer_set_starttv ( M_event_timer_t timer,
M_timeval_t start_tv 
)

Set absolute time for first event to be fired.

This will not take effect until the next call to M_event_timer_start() or M_event_timer_reset().

Parameters
[in]timerTimer handle returned by M_event_timer_add()
[in]start_tvAbsolute time of first event to be fired, or NULL to clear.
Returns
M_TRUE on success, M_FALSE on failure

◆ M_event_timer_set_endtv()

M_bool M_event_timer_set_endtv ( M_event_timer_t timer,
M_timeval_t end_tv 
)

Set absolute time for when the timer will automatically stop

Parameters
[in]timerTimer handle returned by M_event_timer_add()
[in]end_tvAbsolute time of when to stop the timer, or NULL to clear.
Returns
M_TRUE on success, M_FALSE on failure

◆ M_event_timer_set_firecount()

M_bool M_event_timer_set_firecount ( M_event_timer_t timer,
size_t  cnt 
)

Set the maximum number of times the timer should fire. Default is unlimited.

Parameters
[in]timerTimer handle returned by M_event_timer_add()
[in]cntMaximum number of times timer should fire. Use 0 for unlimited.
Returns
M_TRUE on success, M_FALSE on failure

◆ M_event_timer_set_autoremove()

M_bool M_event_timer_set_autoremove ( M_event_timer_t timer,
M_bool  enabled 
)

Set the timer to automatically remove itself and free all used memory when the timer enters the stopped state. This will happen when exceeding the fire count, exceeding the configured end_tv or explicitly calling M_event_timer_stop().

NOTE: Be careful not to attempt to use the timer handle once it has been autoremoved as it will result in access to uninitialized memory.

Parameters
[in]timerTimer handle returned by M_event_timer_add()
[in]enabledM_TRUE to enable autoremove, M_FALSE to disable autoremove.
Returns
M_TRUE on success, M_FALSE on failure.

◆ M_event_timer_set_mode()

M_bool M_event_timer_set_mode ( M_event_timer_t timer,
M_event_timer_mode_t  mode 
)

Sets the timer mode of operation.

Parameters
[in]timerTimer handle returned by M_event_timer_add()
[in]modeDefaults to M_EVENT_TIMER_MODE_RELATIVE if not specified.
Returns
M_TRUE on success, M_FALSE on failure.

◆ M_event_timer_get_remaining_ms()

M_uint64 M_event_timer_get_remaining_ms ( M_event_timer_t timer)

Retrieve number of milliseconds remaining on timer.

Parameters
[in]timerTimer handle returned by M_event_timer_add()
Returns
Number of milliseconds remaining on timer, or 0 if stopped.

◆ M_event_timer_get_interval_ms()

M_uint64 M_event_timer_get_interval_ms ( M_event_timer_t timer)

Retrieve the current millisecond interval the time is using.

Parameters
[in]timerTimer handle returned by M_event_timer_add()
Returns
Number of milliseconds the timer is configured to use. Set from start, reset, or adjust.

◆ M_event_timer_get_status()

M_bool M_event_timer_get_status ( M_event_timer_t timer)

Retrieves if the timer is active(started) or not.

NOTE: Do not use with auto-destroy timers as the timer handle may not be valid if you don't already know the status.

Parameters
[in]timerTimer handle returned by M_event_timer_add()
Returns
M_TRUE if timer is started, M_FALSE if timer is stopped.

◆ M_event_timer_oneshot()

M_event_timer_t * M_event_timer_oneshot ( M_event_t event,
M_uint64  interval_ms,
M_bool  autoremove,
M_event_callback_t  callback,
void *  cb_data 
)

Create a single-event timer.

This is a convenience function equivalent to: M_event_timer_add(event, callback, cbdata) + M_event_timer_set_firecount(timer, 1) + M_event_timer_set_autoremove(timer, autoremove) + M_event_timer_start(timer, interval_ms)

Parameters
[in]eventEvent handle to add the timer to. If the event handle is a pool object, it will automatically distribute to an event thread.
[in]interval_msTime in milliseconds before the timer will expire.
[in]autoremoveWhether the timer should automatically remove itself when it fires.
[in]callbackUser-specified callback to call when the timer expires
[in]cb_dataOptional. User-specified data supplied to user-specified callback when executed.
Returns
Timer handle on success, NULL on failure.

◆ M_event_timer_remove()

M_bool M_event_timer_remove ( M_event_timer_t timer)

Remove the timer and free all memory used by the timer.

If the timer isn't already stopped, this will prevent the timer from firing.

Parameters
[in]timerTimer handle returned by M_event_timer_add()
Returns
M_TRUE on success, M_FALSE on failure.

◆ M_event_timer_edit_cb()

M_bool M_event_timer_edit_cb ( M_event_timer_t timer,
M_event_callback_t  callback,
void *  cb_data 
)

Edit the callback associated with a timer object in the event subsystem.

Editing allows a user to re-purpose a timer object while processing events without needing to remove and add a new object.

Parameters
[in]timerTimer handle returned by M_event_timer_add()
[in]callbackCallback to set.
[in]cb_dataData passed to callback function. NULL will remove the cb_data.
Returns
M_FALSE on error, such as if the callback is NULL.

◆ M_event_queue_task()

M_bool M_event_queue_task ( M_event_t event,
M_event_callback_t  callback,
void *  cb_data 
)

Queue a task to run in the same thread as the event loop.

This is threadsafe to call, and convenient when wanting to avoid additional locks when operating on an object in the event loop.

This is currently implemented as a oneshot timer set for 0ms.

Parameters
[in]eventEvent handle to add task to. Does not make sense to hand an event pool object since the purpose is to choose the event loop to use.
[in]callbackUser-specified callback to call
[in]cb_dataOptional. User-specified data supplied to user-specified callback when executed.
Returns
M_TRUE on success, M_FALSE on failure.

◆ M_event_loop()

M_event_err_t M_event_loop ( M_event_t event,
M_uint64  timeout_ms 
)

Start the event loop to start processing events.

Events will not be delivered unless the event loop is running. If the event handle is a pool, will spawn threads for each member of the pool except one which will run and block the thread executing this function.

Parameters
[in]eventInitialized event handle
[in]timeout_msTime in milliseconds to wait for events. Use M_TIMEOUT_INF to wait until an explicit exit condition has been met, which is the recommended way to run the event loop.
Returns
One of the M_event_err_t conditions.

◆ M_event_done()

void M_event_done ( M_event_t event)

Exit the event loop immediately.

This is safe to call from a thread other than the event loop. Will set the M_EVENT_ERR_DONE return code for the event loop.

This will exit all threads for event pools as well, and if an event child handle is passed instead of the pool handle, it will automatically escalate to the pool handle.

This does not clean up the resources for the event loop and it is safe to re-execute the same event loop handle once it has returned.

Parameters
[in]eventInitialized event handle

◆ M_event_return()

void M_event_return ( M_event_t event)

Exit the event loop immediately.

This is safe to call from a thread other than the event loop. Will set the M_EVENT_ERR_RETURN return code for the event loop, this is the only way this call differs from M_event_done().

This will exit all threads for event pools as well, and if an event child handle is passed instead of the pool handle, it will automatically escalate to the pool handle.

This does not clean up the resources for the event loop and it is safe to re-execute the same event loop handle once it has returned.

Parameters
[in]eventInitialized event handle

◆ M_event_done_with_disconnect()

void M_event_done_with_disconnect ( M_event_t event,
M_uint64  timeout_before_disconnect_ms,
M_uint64  disconnect_timeout_ms 
)

Signal all IO objects in the event loop to start their disconnect sequence and exit the event loop when all are closed, or the specified timeout has elapsed.

This is safe to call from a thread other than the event loop. Will set the M_EVENT_ERR_DONE return code for the event loop. The only difference between this and M_event_done() is it attempts to close the IO objects gracefully, some users may want to use this for program termination.

This will exit all threads for event pools as well, and if an event child handle is passed instead of the pool handle, it will automatically escalate to the pool handle.

This does not clean up the resources for the event loop and it is safe to re-execute the same event loop handle once it has returned.

Parameters
[in]eventInitialized event handle
[in]timeout_before_disconnect_msNumber of milliseconds to wait for io objects to exit on their own before issuing a disconnect. May be set to 0 to immediately start a disconnect sequence on all IO objects.
[in]disconnect_timeout_msNumber of milliseconds to wait on IO handles to close after issuing a disconnect, before giving up. This should be set to some reasonable number to accommodate for proper disconnect sequences. A good starting point may be 5s (5000ms).

◆ M_event_get_status()

M_event_status_t M_event_get_status ( M_event_t event)

Get the current running status of the event loop.

If an event child handle is passed instead of the pool handle, it will automatically escalate to the pool handle.

Parameters
[in]eventInitialized event handle
Returns
one of M_event_status_t results.

◆ M_event_get_statistic()

M_uint64 M_event_get_statistic ( M_event_t event,
M_event_statistic_t  type 
)

Retrieve the specified statistic.

Will return results for the actual handle passed. If the handle is a child of an event pool, it will only return the child's processing time. If all processing time is desired, use M_event_get_pool() to get the pool handle before calling this function.

Parameters
[in]eventInitialized event handle
[in]typeType of statistic to return
Returns
statistic as 64bit integer

◆ M_event_num_objects()

size_t M_event_num_objects ( M_event_t event)

Retrieve the number of M_io_t objects plus the number of M_event_timer_t objects associated with an event handle

Will return results for the actual handle passed. If the handle is a child of an event pool, it will only return the child's processing time. If all processing time is desired, use M_event_get_pool() to get the pool handle before calling this function.

Parameters
[in]eventInitialized event handle
Returns
count of objects.

◆ M_event_type_string()

const char * M_event_type_string ( M_event_type_t  type)

Get human readable event type from M_event_type_t

Parameters
[in]typeevent type
Returns
constant human readable string