event_loop.h File Reference

event loop implementation More...

#include <signal.h>
#include "cgul_exception.h"
#include "event_loop_common.h"
Include dependency graph for event_loop.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Typedefs

typedef typedefCGUL_BEGIN_C struct event_loop * event_loop_t
 
typedef void * event_loop__timeout_t
 
typedef void(* event_loop__fd_ready_cb_t) (cgul_exception_t *cex, int fd, void *data)
 
typedef void(* event_loop__timeout_cb_t) (cgul_exception_t *cex, event_loop__timeout_t timeout, void *data)
 
typedef void(* event_loop__signal_cb_t) (cgul_exception_t *cex, int signal_number, void *data)
 

Functions

event_loop_t event_loop__get_instance (cgul_exception_t *cex)
 
void event_loop__put_instance ()
 
event_loop_t event_loop__new (cgul_exception_t *cex)
 
void event_loop__delete (event_loop_t loop)
 
void event_loop__start (cgul_exception_t *cex, event_loop_t loop)
 
void event_loop__stop (cgul_exception_t *cex, event_loop_t loop)
 
void event_loop__add_signal_handler (cgul_exception_t *cex, event_loop_t loop, int signal_number, event_loop__signal_cb_t cb, void *cb_data)
 
void event_loop__remove_signal_handler (cgul_exception_t *cex, event_loop_t loop, int signal_number)
 
event_loop__timeout_t event_loop__add_timeout (cgul_exception_t *cex, event_loop_t loop, double period, event_loop__timeout_cb_t cb, void *cb_data)
 
void event_loop__remove_timeout (cgul_exception_t *cex, event_loop_t loop, event_loop__timeout_t timeout)
 
void event_loop__add_read_fd (cgul_exception_t *cex, event_loop_t loop, int fd, event_loop__fd_ready_cb_t cb, void *cb_data)
 
void event_loop__remove_read_fd (cgul_exception_t *cex, event_loop_t loop, int fd)
 
void event_loop__add_write_fd (cgul_exception_t *cex, event_loop_t loop, int fd, event_loop__fd_ready_cb_t cb, void *cb_data)
 
void event_loop__remove_write_fd (cgul_exception_t *cex, event_loop_t loop, int fd)
 
void event_loop__add_exception_fd (cgul_exception_t *cex, event_loop_t loop, int fd, event_loop__fd_ready_cb_t cb, void *cb_data)
 
void event_loop__remove_exception_fd (cgul_exception_t *cex, event_loop_t loop, int fd)
 

Detailed Description

This class implements an event loop. This class is probably only functional on unix-like operating systems. This is why it is not part of cgul.

NOTE: This class is not thread-safe. This is by design because you generally only call this class's methods from the same thread. If you need to call this class's methods from multiple threads, you'll need to add external locking.

NOTE: This class is re-entrant. This allows any callback to directly add or remove any callback including itself.

Author
Paul Serice

Typedef Documentation

§ event_loop_t

typedef typedefCGUL_BEGIN_C struct event_loop* event_loop_t

Opaque pointer to a event_loop instance.

§ event_loop__timeout_t

typedef void* event_loop__timeout_t

Opaque pointer to a timeout handle.

§ event_loop__fd_ready_cb_t

typedef void(* event_loop__fd_ready_cb_t) (cgul_exception_t *cex, int fd, void *data)

File descriptor ready callback. Functions you write that match this prototype can be registered to be called when the file descriptor fd is ready. The data parameter is the usual client data. The cex parameter is a pointer that can be used to throw a c-style exception. Any exception that escapes this callback will be caught by the main event loop and printed to standard error. If you do not like this behavior, you do not have to use cex, or you can catch it inside your function.

Parameters
[in,out]cexc-style exception
[in]fdfile descriptor
[in]dataclient data

§ event_loop__timeout_cb_t

typedef void(* event_loop__timeout_cb_t) (cgul_exception_t *cex, event_loop__timeout_t timeout, void *data)

Timeout expired callback. Functions you write that match this prototype can be registered to be called when a timeout expires. The timeout parameter is the same value returned by event_loop__add_timeout(). It can be used to remove the timeout so that its callback will no longer be called. The data parameter is the usual client data. The cex parameter is a pointer that can be used to throw a c-style exception. Any exception that escapes this callback will be caught by the main event loop and printed to standard error. If you do not like this behavior, you do not have to use cex, or you can catch it inside your function.

Parameters
[in,out]cexc-style exception
[in]timeouttimeout handle
[in]dataclient data

§ event_loop__signal_cb_t

typedef void(* event_loop__signal_cb_t) (cgul_exception_t *cex, int signal_number, void *data)

Posix asynchronous signal caught callback. Functions you write that match this prototype can be registered to be called when a particular signal has been caught. The signal_number is the signal number for the signal that was caught. The data parameter is the usual client data. The cex parameter is a pointer that can be used to throw a c-style exception. Any exception that escapes this callback will be caught by the main event loop and printed to standard error. If you do not like this behavior, you do not have to use cex, or you can catch it inside your function.

Parameters
[in,out]cexc-style exception
[in]signal_numbersignal number for the signal that was caught
[in]dataclient data

Function Documentation

§ event_loop__get_instance()

event_loop_t event_loop__get_instance ( cgul_exception_t *  cex)

Get the single instance of the event_loop class. The single instance is created the first time this method is called. If the instance cannot be created, an exception is thrown.

Note
For the main thread, use the singleton returned by this method which can handle Posix asynchronous signals. Do not use a per-thread instance returned by event_loop__new() which cannot handle Posix asynchronous signals.
Parameters
[in,out]cexc-style exception
Returns
single instance (i.e., main event loop)

Referenced by event_loop_cxx::get_instance().

§ event_loop__put_instance()

void event_loop__put_instance ( )

Put the single instance of the event_loop class. The single instance is destroyed whenever this method is called. In general, it should only be called before exiting the application if it is called at all.

Referenced by event_loop_cxx::put_instance().

§ event_loop__new()

event_loop_t event_loop__new ( cgul_exception_t *  cex)

Create a new, per-thread event_loop object that handles file descriptor and timeout events but not Posix asynchronous signal events. The caller is responsible for freeing the object by calling event_loop_delete(). If memory cannot be allocated, NULL is returned, and an exception is thrown.

Note
For the main thread, do not create a new event_loop object using this method; instead, use the singleton returned by event_loop__get_instance() which has global visibility and can handle Posix asynchronous signals.
Parameters
[in,out]cexc-style exception
Returns
new event_loop instance

Referenced by event_loop_cxx::event_loop_cxx().

§ event_loop__delete()

void event_loop__delete ( event_loop_t  loop)

This method frees all internally allocated memory associated with loop. Do not try to access loop after calling this method.

Note
Only call this method on instances returned by direct calls to event_loop__new(). Do not call this method on the singleton returned by event_loop__get_instance(); instead call event_loop__put_instance() to properly delete the singleton.
Parameters
[in]loopevent_loop instance

Referenced by event_loop_cxx::set_obj(), and event_loop_cxx::~event_loop_cxx().

§ event_loop__start()

void event_loop__start ( cgul_exception_t *  cex,
event_loop_t  loop 
)

This method starts the main event loop which only returns when one of the callbacks registered with the event loop invokes event_loop__stop().

Parameters
[in]cexc-style exception
[in]loopevent_loop instance

Referenced by event_loop_cxx::start().

§ event_loop__stop()

void event_loop__stop ( cgul_exception_t *  cex,
event_loop_t  loop 
)

Call this method from within an event callback or from a different thread in order to stop processing events. This will cause event_loop__start to return to its caller. This method is thread-safe. If an error occurs, an exception is thrown.

Parameters
[in,out]cexc-style exception
[in]loopevent_loop instance

Referenced by event_loop_cxx::stop().

§ event_loop__add_signal_handler()

void event_loop__add_signal_handler ( cgul_exception_t *  cex,
event_loop_t  loop,
int  signal_number,
event_loop__signal_cb_t  cb,
void *  cb_data 
)

This method arranges for cb to be called synchronously with cb_data when a Posix asynchronous signal is caught. The big advantage of this is that cb runs in the synchronous context of the event loop's thread instead of in the asynchronous context of a true signal handler. If cb is NULL, the signal is effectively ignored. If the signal cannot be registered, an exception is thrown.

You can change cb and cb_data for a particular signal by calling this method more than once, but only one signal handler can simultaneously be registered per signal.

As a convenience, the event_loop class is re-entrant with respect to the event loop's single thread of execution. This means you can call any of the methods of this class even from callbacks registered with this class.

If an error occurs, NULL is returned, and an exception is thrown.

Parameters
[in,out]cexc-style exception
[in]loopevent_loop instance
[in]signal_numbersignal number
[in]cbcallback
[in]cb_datacallback data passed to cb

Referenced by event_loop_cxx::add_signal_handler().

§ event_loop__remove_signal_handler()

void event_loop__remove_signal_handler ( cgul_exception_t *  cex,
event_loop_t  loop,
int  signal_number 
)

Remove the the signal handler for the signal signal_number from the list of Posix asynchronous signals handled by the event loop. This causes the default system action for the signal to be restored. If an error occurs, an exception is thrown.

Parameters
[in,out]cexc-style exception
[in]loopevent_loop instance
[in]signal_numbersignal number

Referenced by event_loop_cxx::remove_signal_handler().

§ event_loop__add_timeout()

event_loop__timeout_t event_loop__add_timeout ( cgul_exception_t *  cex,
event_loop_t  loop,
double  period,
event_loop__timeout_cb_t  cb,
void *  cb_data 
)

This method adds a timeout event that repeatedly schedules itself every period seconds. Because period is a double, timeouts with millisecond resolution can easily be scheduled. The only guarantee regarding when the timeout occurs is that it occurs at least period seconds after it has been scheduled. If period is less than zero, the timeout will not be registered.

The event_loop class is re-entrant with respect to the event loop's single thread of execution making it possible to remove a timeout from cb itself.

The value returned is the handle for the timeout. It uniquely identifies the timeout and must be passed into event_loop__remove_timeout() in order to remove the timeout. If you plan on removing the callback from inside cb, you do not need to keep a reference to the value that is returned as it is always passed into your callback.

If an error occurs, NULL is returned, and an exception is thrown.

Parameters
[in,out]cexc-style exception
[in]loopevent_loop instance
[in]periodtimeout period
[in]cb_datacallback data passed to cb
[in]cbcallback
Returns
timeout handle

Referenced by event_loop_cxx::add_timeout().

§ event_loop__remove_timeout()

void event_loop__remove_timeout ( cgul_exception_t *  cex,
event_loop_t  loop,
event_loop__timeout_t  timeout 
)

This function removes timeouts registered with event_loop__add_timeout(). After calling this function, timeout is invalid. If an error occurs, an exception is thrown.

This method can throw an out-of-memory exception. This can happen when this method is called from any timeout callback because this causes this class to be re-entered which requires that the request to remove the timeout be added to a queue so it can be honored later when it is safe to do so.

Parameters
[in,out]cexc-style exception
[in]loopevent_loop instance
[in]timeouttimeout handle

Referenced by event_loop_cxx::remove_timeout().

§ event_loop__add_read_fd()

void event_loop__add_read_fd ( cgul_exception_t *  cex,
event_loop_t  loop,
int  fd,
event_loop__fd_ready_cb_t  cb,
void *  cb_data 
)

This method adds fd to the list of file descriptors the event loop monitors. The event loop will then call cb with the client-supplied cb_data pointer when fd is ready to be read.

You can change cb and cb_data for a particular file descriptor by calling this method more than once, but only one "read" callback per file descriptor can simultaneously be registered.

As a convenience, the event_loop class is re-entrant with respect to the event loop's single thread of execution. This means you can call any of the methods of this class even from callbacks registered with this class.

If an error occurs, an exception is thrown.

Parameters
[in,out]cexc-style exception
[in]loopevent_loop instance
[in]fdfile descriptor to monitor
[in]cbcallback
[in]cb_datacallback data passed to cb

Referenced by event_loop_cxx::add_read_fd().

§ event_loop__remove_read_fd()

void event_loop__remove_read_fd ( cgul_exception_t *  cex,
event_loop_t  loop,
int  fd 
)

Remove fd from the list of file descriptors the event loop monitors to see when they are ready to be read. If an error occurs, an exception is thrown.

Parameters
[in,out]cexc-style exception
[in]loopevent_loop instance
[in]fdfile descriptor to remove

Referenced by event_loop_cxx::remove_read_fd().

§ event_loop__add_write_fd()

void event_loop__add_write_fd ( cgul_exception_t *  cex,
event_loop_t  loop,
int  fd,
event_loop__fd_ready_cb_t  cb,
void *  cb_data 
)

This method adds fd to the list of file descriptors the event loop monitors. The event loop will then call cb with the client-supplied cb_data pointer when fd is ready to be written.

You can change cb and cb_data for a particular file descriptor by calling this method more than once, but only one "write" callback per file descriptor can simultaneously be registered.

As a convenience, the event_loop class is re-entrant with respect to the event loop's single thread of execution. This means you can call any of the methods of this class even from callbacks registered with this class.

If an error occurs, an exception is thrown.

Parameters
[in,out]cexc-style exception
[in]loopevent_loop instance
[in]fdfile descriptor to monitor
[in]cbcallback
[in]cb_datacallback data passed to cb

Referenced by event_loop_cxx::add_write_fd().

§ event_loop__remove_write_fd()

void event_loop__remove_write_fd ( cgul_exception_t *  cex,
event_loop_t  loop,
int  fd 
)

Remove fd from the list of file descriptors the event loop monitors to see when they are ready to be written. If an error occurs, an exception is thrown.

Parameters
[in,out]cexc-style exception
[in]loopevent_loop instance
[in]fdfile descriptor to remove

Referenced by event_loop_cxx::remove_write_fd().

§ event_loop__add_exception_fd()

void event_loop__add_exception_fd ( cgul_exception_t *  cex,
event_loop_t  loop,
int  fd,
event_loop__fd_ready_cb_t  cb,
void *  cb_data 
)

This method adds fd to the list of file descriptors the event loop monitors. The event loop will then call cb with the client-supplied cb_data pointer when fd has an exception.

You can change cb and cb_data for a particular file descriptor by calling this method more than once, but only one "exception" callback per file descriptor can simultaneously be registered.

As a convenience, the event_loop class is re-entrant with respect to the event loop's single thread of execution. This means you can call any of the methods of this class even from callbacks registered with this class.

If an error occurs, an exception is thrown.

Parameters
[in,out]cexc-style exception
[in]loopevent_loop instance
[in]fdfile descriptor to monitor
[in]cbcallback
[in]cb_datacallback data passed to cb

Referenced by event_loop_cxx::add_exception_fd().

§ event_loop__remove_exception_fd()

void event_loop__remove_exception_fd ( cgul_exception_t *  cex,
event_loop_t  loop,
int  fd 
)

Remove fd from the list of file descriptors the event loop monitors to see when an exception occurs. If an error occurs, an exception is thrown.

Parameters
[in,out]cexc-style exception
[in]loopevent_loop instance
[in]fdfile descriptor to remove

Referenced by event_loop_cxx::remove_exception_fd().