From 938852afd347b7a09ae57eefa2b6c7f68cc77bf0 Mon Sep 17 00:00:00 2001 From: Laurence Withers Date: Sat, 13 Oct 2007 20:30:31 +0000 Subject: [PATCH] WIP --- src/docs/Doxyfile | 232 ++++++++++++++++++++++++++++ src/docs/Doxyfile.in | 7 +- src/liblwevent/000_TopSource.c | 5 + src/liblwevent/100_struct_lwevent.c | 41 +++++ src/liblwevent/200_eventloop.c | 149 ++++++++++++++++++ src/liblwevent/200_eventloop.h | 32 ++++ src/liblwevent/300_fdevent.c | 91 +++++++++++ src/liblwevent/300_fdevent.h | 35 ++++- src/liblwevent/350_fdparams.h | 150 ++++++++++++++++-- src/liblwevent/build.lib | 6 +- 10 files changed, 729 insertions(+), 19 deletions(-) create mode 100644 src/docs/Doxyfile create mode 100644 src/liblwevent/100_struct_lwevent.c create mode 100644 src/liblwevent/200_eventloop.c create mode 100644 src/liblwevent/300_fdevent.c diff --git a/src/docs/Doxyfile b/src/docs/Doxyfile new file mode 100644 index 0000000..0665842 --- /dev/null +++ b/src/docs/Doxyfile @@ -0,0 +1,232 @@ +# Doxyfile 1.5.3 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = liblwevent +PROJECT_NUMBER = +OUTPUT_DIRECTORY = +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = YES +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = YES +DETAILS_AT_TOP = YES +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 4 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = NO +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = YES +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = NO +INLINE_INFO = YES +SORT_MEMBER_DOCS = NO +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = NO +SHOW_DIRECTORIES = NO +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = YES +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = YES +WARN_FORMAT = "$file:$line: $text " +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = /home/lwithers/git/liblwevent/src/liblwevent +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = +RECURSIVE = NO +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = src/docs +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +REFERENCES_LINK_SOURCE = YES +USE_HTAGS = NO +VERBATIM_HEADERS = NO +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +HTML_DYNAMIC_SECTIONS = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = DOXYGEN \ + __attribute__()= +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +MSCGEN_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = YES +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = NO +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = NO +INCLUDED_BY_GRAPH = NO +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = NO +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 1000 +DOT_TRANSPARENT = YES +DOT_MULTI_TARGETS = YES +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/src/docs/Doxyfile.in b/src/docs/Doxyfile.in index 7d3b3a6..303a871 100644 --- a/src/docs/Doxyfile.in +++ b/src/docs/Doxyfile.in @@ -140,12 +140,13 @@ PERLMOD_LATEX = NO PERLMOD_PRETTY = YES PERLMOD_MAKEVAR_PREFIX = ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = NO -EXPAND_ONLY_PREDEF = NO +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = YES SEARCH_INCLUDES = YES INCLUDE_PATH = INCLUDE_FILE_PATTERNS = -PREDEFINED = DOXYGEN +PREDEFINED = DOXYGEN \ + __attribute__()= EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES TAGFILES = diff --git a/src/liblwevent/000_TopSource.c b/src/liblwevent/000_TopSource.c index 5d124da..63e6d9b 100644 --- a/src/liblwevent/000_TopSource.c +++ b/src/liblwevent/000_TopSource.c @@ -8,6 +8,11 @@ #include "lwevent.h" /* Below are all the includes used throughout the library. */ +#include +#include +#include +#include +#include /* options for text editors kate: replace-trailing-space-save true; space-indent true; tab-width 4; diff --git a/src/liblwevent/100_struct_lwevent.c b/src/liblwevent/100_struct_lwevent.c new file mode 100644 index 0000000..585f145 --- /dev/null +++ b/src/liblwevent/100_struct_lwevent.c @@ -0,0 +1,41 @@ +/* liblwevent/src/liblwevent/100_struct_lwevent.c + * + * (c)2007, Laurence Withers, . + * Released under the GNU GPLv2. See file COPYING or + * http://www.gnu.org/copyleft/gpl.html for details. +*/ + + + +/* struct lwevent + * The opaque file descriptor event structure. + */ +struct lwevent { + /* file descriptor -- set to -1 if invalid */ + int fd; + + /* bitmask of events being listened for (EPOLLIN et al.) */ + int events; + + /* callback function */ + lwevent_callback callback; + + /* user pointer */ + void* user; + + /* destructor */ + lwevent_dtor dtor; + + /* autodestroy mask */ + int autodestroy; + + /* if invalid (fd == -1), this forms a linked list of invalid objects */ + struct lwevent* invalid_next; +}; + + + +/* options for text editors +kate: replace-trailing-space-save true; space-indent true; tab-width 4; +vim: expandtab:ts=4:sw=4 +*/ diff --git a/src/liblwevent/200_eventloop.c b/src/liblwevent/200_eventloop.c new file mode 100644 index 0000000..7b0e5ab --- /dev/null +++ b/src/liblwevent/200_eventloop.c @@ -0,0 +1,149 @@ +/* liblwevent/src/liblwevent/200_eventloop.c + * + * (c)2007, Laurence Withers, . + * Released under the GNU GPLv2. See file COPYING or + * http://www.gnu.org/copyleft/gpl.html for details. +*/ + + + +/* lwevent_epoll_fd + * File descriptor returned by epoll_create(). Initialised in lwevent_init(). + */ +int lwevent_epoll_fd; + + + +/* lwevent_loop_exit + * Flag which, when non-zero, causes lwevent_loop() to exit after calling lwevent_wait(). + * Initialised to zero in lwevent_init(). May be set by any user code. + */ +volatile int lwevent_loop_exit; + + + +/* _lw_revents[] + * A dynamic array of returned events. Initialised in lwevent_init(). + */ +static int _lw_revents_size; +static struct epoll_event* _lw_revents; + + + +/* _lw_revents_count, _lw_revents_overcount + * A count of times that epoll_wait(2) has returned in total, and a count of times it has returned + * with the maximum number of events. Used to dynamically scale up the size of the retrieval buffer + * at runtime. Initialised in lwevent_init(). + */ +static int _lw_revents_count, _lw_revents_overcount; + + + +/* lwevent_init() + * Initialise lwevent_epoll_fd, lwevent_loop_exit, _lw_revents[] etc. + */ +int lwevent_init(void) +{ + _lw_revents_size = 4; + _lw_revents = malloc(sizeof(struct epoll_event) * _lw_revents_size); + if(!_lw_revents) return -1; + _lw_revents_count = 0; + _lw_revents_overcount = 0; + + lwevent_loop_exit = 0; + + lwevent_epoll_fd = TEMP_FAILURE_RETRY( + epoll_create(4 /* initial number of file descriptors */) + ); + if(lwevent_epoll_fd == -1) { + free(_lw_revents); + return -1; + } + + return 0; +} + + + +/* lwevent_loop() + * Convenience function which just keeps calling lwevent_wait(), with no timeout, until an error + * occurs or lwevent_loop_exit is set. + */ +int lwevent_loop(void) +{ + while(!lwevent_loop_exit) { + if(lwevent_wait(-1)) { + if(errno == EINTR) continue; + return -1; + } + } + return 0; +} + + + +/* _lwevent_invalidate(), _lwevent_invalid_head + * Marks the object `ev' as invalid. The associated file descriptor must already have been closed, + * since we set it to -1. A linked list of invalid events is created. + */ +static struct lwevent* _lwevent_invalid_head; +static void _lwevent_invalid(struct lwevent* ev) __attribute__((nonnull)); +static void _lwevent_invalid(struct lwevent* ev) +{ + /* skip already invalid structures */ + if(ev->fd == -1) return; + + /* mark as invalid */ + ev->fd = -1; + + /* add to linked list */ + ev->invalid_next = _lwevent_invalid_head; + _lwevent_invalid_head = ev; +} + + + +/* lwevent_wait() + * Wrapper around epoll_wait(2). For every returned event, we assume the object has an associated + * struct lwevent in the struct epoll_event. + */ +int lwevent_wait(int timeout_ms) +{ + int ret, i; + struct lwevent* ev; + + _lwevent_invalid_head = 0; + + /* perform epoll_wait(2) */ + ret = epoll_wait(lwevent_epoll_fd, _lw_revents, _lw_revents_size, timeout_ms); + if(ret == -1) return -1; + + /* process returned events */ + for(i = 0; i < ret; ++i) { + ev = (struct lwevent*)(_lw_revents[i].data.ptr); + if(ev->fd == -1) continue; /* skip invalid events */ + + ret = _lw_revents[i].events; + if(ret & ev->autodestroy) { + lwevent_free(ev); + continue; + } + + ev->callback(ev, ret); + } + + /* free any invalid struct lwevent objects */ + for(ev = _lwevent_invalid_head; ev; ev = _lwevent_invalid_head) { + _lwevent_invalid_head = _lwevent_invalid_head->invalid_next; + free(ev); + } + + return 0; +} + + + +/* options for text editors +kate: replace-trailing-space-save true; space-indent true; tab-width 4; +vim: expandtab:ts=4:sw=4 +*/ diff --git a/src/liblwevent/200_eventloop.h b/src/liblwevent/200_eventloop.h index 3bcefb0..f754f06 100644 --- a/src/liblwevent/200_eventloop.h +++ b/src/liblwevent/200_eventloop.h @@ -18,6 +18,31 @@ program should exit), and lwevent_wait(), which implements a single run of the e +/*! \brief Event loop file descriptor. + +The file descriptor returned from \c epoll_create(2). Use of this file descriptor is not +recommended, although it is made available in case an application ever needs to access it (perhaps +to close after a \c fork(2), etc.). + +*/ +extern int lwevent_epoll_fd; + + + +/*! \brief Initialise library. + +\retval 0 on success. +\retval -1 on error (and see \a errno). + +This function initialises the library, calling \c epoll_create(2) to set up the initial file +descriptor, and allocating memory for returned events, etc. The initialised file descriptor may be +found in lwevent_epoll_fd, although it is not recommended to use it directly. + +*/ +int lwevent_init(void); + + + /*! \brief Event loop exit flag. This flag, if set, signifies that lwevent_loop() should exit after its next iteration. It can be @@ -55,6 +80,13 @@ timeout, in milliseconds, occurs). If any events do occur, they will be dispatch callback objects. The final action of this function is to free the memory associated with any objects that are closed during the callbacks. +\a timeout_ms may be specified as a negative number to disable timeouts and wait forever, or as 0 to +return immediately even if no events are available. A positive number is a duration in milliseconds. + +\note If a signal is received while in \c epoll_wait(2), this function will return -1 and \a errno + will be set to \c EINTR. This is not a permanent error condition. lwevent_loop() will catch this + condition and continue to loop. + */ int lwevent_wait(int timeout_ms); diff --git a/src/liblwevent/300_fdevent.c b/src/liblwevent/300_fdevent.c new file mode 100644 index 0000000..8418b70 --- /dev/null +++ b/src/liblwevent/300_fdevent.c @@ -0,0 +1,91 @@ +/* liblwevent/src/liblwevent/300_fdevent.c + * + * (c)2007, Laurence Withers, . + * Released under the GNU GPLv2. See file COPYING or + * http://www.gnu.org/copyleft/gpl.html for details. +*/ + + + +/* _lwevent_activate() + * Activates the event `ev'. Called when creating a new event in lwevent_new() or when reactivating + * an event in lwevent_reactivate(). Calls epoll_ctl(EPOLL_CTL_ADD). + */ +static int _lwevent_activate(struct lwevent* ev) +{ + struct epoll_event ee; + + ee.events = ev->events; + ee.data.ptr = ev; + + return TEMP_FAILURE_RETRY( epoll_ctl(lwevent_epoll_fd, EPOLL_CTL_ADD, ev->fd, &ee) ); +} + + + +/* lwevent_new() + * Sets up a new event structure and registers it with epoll_ctl(EPOLL_CTL_ADD). + */ +struct lwevent* lwevent_new(int fd, int events, lwevent_callback callback) +{ + struct lwevent* ev; + + ev = malloc(sizeof(struct lwevent)); + if(!ev) return 0; + memset(ev, 0, sizeof(struct lwevent)); + + ev->fd = fd; + ev->events = events; + ev->callback = callback; + + if(_lwevent_activate(ev)) { + free(ev); + return 0; + } + + return ev; +} + + + +/* lwevent_free() + * Mark `ev' as invalid, closing its file descriptor and calling the destructor (if there is one). + * If the object is already invalid, or is null, do nothing. + */ +void lwevent_free(struct lwevent* ev) +{ + if(!ev || ev->fd == -1) return; + + /* call destructor, close file descriptor, mark as invalid */ + if(ev->dtor) ev->dtor(ev); + close(ev->fd); + _lwevent_invalid(ev); +} + + + +/* lwevent_deactivate() + * Temporarily deactivate `ev'. Calls epoll_ctl(EPOLL_CTL_DEL). + */ +int lwevent_deactivate(struct lwevent* ev) +{ + return TEMP_FAILURE_RETRY( epoll_ctl(lwevent_epoll_fd, EPOLL_CTL_DEL, ev->fd, 0) ); +} + + + +/* lwevent_reactivate() + * Activate `ev'. + */ +int lwevent_reactivate(struct lwevent* ev) +{ + return _lwevent_activate(ev); +} + + + +/*!@}*/ +/* options for text editors +kate: replace-trailing-space-save true; space-indent true; tab-width 4; +vim: expandtab:ts=4:sw=4 +*/ diff --git a/src/liblwevent/300_fdevent.h b/src/liblwevent/300_fdevent.h index 0e71f9d..a7ab780 100644 --- a/src/liblwevent/300_fdevent.h +++ b/src/liblwevent/300_fdevent.h @@ -69,8 +69,11 @@ Once a lwevent structure has been created for \a fd, \a fd should not be passed directly. Instead, when it is time to close the file descriptor, pass the associated lwevent structure to lwevent_free(). +\note See lwevent_set_events() for a discussion of valid flags for \a events. + */ -struct lwevent* lwevent_new(int fd, int events, lwevent_callback callback); +struct lwevent* lwevent_new(int fd, int events, lwevent_callback callback) + __attribute__((malloc, nonnull, warn_unused_result)); @@ -99,8 +102,34 @@ call to lwevent_wait(). */ void lwevent_free(struct lwevent* ev); -int lwevent_deactivate(struct lwevent* ev); -int lwevent_reactivate(struct lwevent* ev); + + +/*! \brief Temporarily deactivate an event structure. + +\param ev Event structure. +\retval 0 on success. +\retval -1 on error (and see \a errno). + +Sometimes, it is useful to temporarily disable event monitoring for an object, without affecting its +file descriptor. This function provides a method for achieving this. The object can later be +reactivated with lwevent_reactivate(). Deactivated objects may still be operated on and destroyed. + +*/ +int lwevent_deactivate(struct lwevent* ev) __attribute__((nonnull, warn_unused_result)); + + + +/*! \brief Reactivate an event structure after temporary deactivation. + +\param ev Deactivated event structure. +\retval 0 on success. +\retval -1 on error (and see \a errno). + +Reactivates event monitoring for an object that was temporarily deactivated with +lwevent_deactivate(). + +*/ +int lwevent_reactivate(struct lwevent* ev) __attribute__((nonnull, warn_unused_result)); diff --git a/src/liblwevent/350_fdparams.h b/src/liblwevent/350_fdparams.h index d8b7345..b97b3c4 100644 --- a/src/liblwevent/350_fdparams.h +++ b/src/liblwevent/350_fdparams.h @@ -7,23 +7,153 @@ -int lwevent_get_fd(const struct lwevent* ev); +/*! \defgroup fdparams File descriptor object parameters -int lwevent_set_events(struct lwevent* ev, int events, int* old_events); -int lwevent_get_events(const struct lwevent* ev); +The functions in this module allow the association of several parameters with each file descriptor +event object (struct lwevent). -void lwevent_set_callback(struct lwevent* ev, lwevent_callback callback, - lwevent_callback* old_callback); -lwevent_callback lwevent_get_callback(const struct lwevent* ev); +*/ +/*!@{*/ -void lwevent_set_user(struct lwevent* ev, void* user); -void* lwevent_get_user(const struct lwevent* ev); + +/*! \brief Event object destructor function pointer. + +\param ev Event object being destroyed. + +This type is a pointer to a destructor function suitable for cleaning up lwevent structures. The +destructor is called from within lwevent_free(). If no destructor is specified, no action is taken. + +*/ typedef void (*lwevent_dtor)(struct lwevent* ev); -void lwevent_set_dtor(struct lwevent* ev, lwevent_dtor dtor, lwevent_dtor* old_dtor); -lwevent_dtor lwevent_get_dtor(struct lwevent* ev); + +/*! \brief Flag: autodestroy object if \c EPOLLERR is received. */ +extern const int LWEVENT_AUTODESTROY_ERR; +/*! \brief Flag: autodestroy object if \c EPOLLRDHUP is received. */ +extern const int LWEVENT_AUTODESTROY_RDHUP; +/*! \brief Flag: autodestroy object if \c EPOLLHUP is received. */ +extern const int LWEVENT_AUTODESTROY_WRHUP; + + + +/*! \brief Retrieve file descriptor associated with object. */ +int lwevent_get_fd(const struct lwevent* ev) __attribute__((nonnull, warn_unused_result)); + +/*! \brief Retrieve bitmask of events being monitored. */ +int lwevent_get_events(const struct lwevent* ev) __attribute__((nonnull, warn_unused_result)); + +/*! \brief Retrieve pointer to callback function. */ +lwevent_callback lwevent_get_callback(const struct lwevent* ev) + __attribute__((nonnull, warn_unused_result)); + +/*! \brief Retrieve user pointer. */ +void* lwevent_get_user(const struct lwevent* ev) __attribute__((nonnull, warn_unused_result)); + +/*! \brief Retrieve pointer to destructor function. */ +lwevent_dtor lwevent_get_dtor(const struct lwevent* ev) __attribute__((nonnull, warn_unused_result)); + +/*! \brief Retrieve autodestroy events bitmask. */ +int lwevent_get_autodestroy(const struct lwevent* ev) __attribute__((nonnull, warn_unused_result)); + + + +/*! \brief Change monitored events. + +\param ev Event object. +\param events New bitmask of events to monitor (see \c epoll_ctl(2)). +\param[out] old_events Previous bitmask stored here. May be 0. +\retval 0 on success. +\retval -1 on error (and see \a errno). + +Changes the events being monitored for the file descriptor associated with \a ev. This calls +\c epoll_ctl(2) so may fail; a return value of 0 indicates success. If the application wishes to +retrieve the bitmask in force before the change, it may pass a pointer to an integer in +\a old_events; the previous value will be stored there. The pointer may be 0 if the previous value +is not required. + +Only some values are valid for the \a events bitmask (non-authoritative list: \c EPOLLIN, +\c EPOLLOUT, \c EPOLLRDHUP, \c EPOLLPRI, \c EPOLLET, \c EPOLLONESHOT). Returned events may have +values not specified in \a events (\c EPOLLERR, \c EPOLLHUP). See the \c epoll_ctl(2) man page for +details. + +\note Although \c EPOLLONESHOT is supported by the library, it must be used with care. Whenever an + object with this flag set returns an event, the object must be reactivated with the + lwevent_reactivate() function. + +*/ +int lwevent_set_events(struct lwevent* ev, int events, int* old_events) + __attribute__((warn_unused_result, nonnull(1))); + + + +/*! \brief Change callback function. + +\param ev Event object. +\param callback Pointer to new callback function. +\param[out] old_callback Previous callback function pointer stored here. May be 0. + +Changes the callback function associated with \a ev. If the program wishes to retrieve the previous +callback function pointer, it may pass a pointer-to-function-pointer in \a old_callback. This may be +left null if not required. + +*/ +void lwevent_set_callback(struct lwevent* ev, lwevent_callback callback, + lwevent_callback* old_callback) __attribute__((nonnull(1, 2))); + + + +/*! \brief Set user pointer. + +\param ev Event object. +\param user Pointer to new user object. May be 0 to clear. +\param[out] old_user Previous user object pointer stored here. May be 0. + +Changes the user pointer associated with \a ev. If the program wishes to retrieve the previous user +pointer, it may pass a pointer-to-pointer in \a old_user. This may be left null if not required. + +*/ +void lwevent_set_user(struct lwevent* ev, void* user, void** old_user) + __attribute__((nonnull(1))); + + + +/*! \brief Set destructor function. + +\param ev Event object. +\param dtor Pointer to destructor object to call when \a ev is freed. May be 0 to clear. +\param[out] old_dtor Previous destructor function pointer stored here. May be 0. + +Changes the destructor function associated with \a ev. The destructor function (if one has been +registered) is called from within lwevent_free(). There is no default destructor. It can be cleared +by passing \a dtor as 0. + +If the program wishes to retrieve the previous destructor function pointer, it may pass a +pointer-to-function-pointer in \a old_dtor. This may be left null if not required. + +*/ +void lwevent_set_dtor(struct lwevent* ev, lwevent_dtor dtor, lwevent_dtor* old_dtor) + __attribute__((nonnull(1))); + + + +/*! \brief Set autodestroy events bitmask. + +\param ev Event object. +\param autodestroy Bitmask of events which destroy object if received. +\param[out] old_autodestroy Previous bitmask stored here. May be 0. + +The autodestroy functionality causes the event object \a ev to be automatically passed to +lwevent_free() if any specified event occurs. You may pass ~0 to autodestroy on any error event. + +*/ +void lwevent_set_autodestroy(struct lwevent* ev, int autodestroy, int* old_autodestroy) + __attribute__((nonnull(1))); + + + +/*!@}*/ /* options for text editors kate: replace-trailing-space-save true; space-indent true; tab-width 4; vim: expandtab:ts=4:sw=4:syntax=c.doxygen diff --git a/src/liblwevent/build.lib b/src/liblwevent/build.lib index ab55743..c1326c5 100644 --- a/src/liblwevent/build.lib +++ b/src/liblwevent/build.lib @@ -12,9 +12,9 @@ then source src/liblwevent/soversion liblwevent="obj/${liblwevent_BASE}.so.${SOMAJOR}.${SOMICRO}" - liblwevent_DEP_CFLAGS="" # @TODO@ cflags - liblwevent_DEP_LIBS="" # @TODO@ libs - SO_EXTRA="${liblwevent_DEP_CFLAGS} ${liblwevent_DEP_LIBS} -lc" + liblwevent_DEP_CFLAGS="" + liblwevent_DEP_LIBS="" + SO_EXTRA="-D_GNU_SOURCE -std=c99 ${liblwevent_DEP_CFLAGS} ${liblwevent_DEP_LIBS} -lc" echo "Building library ${liblwevent}..."