WIP
This commit is contained in:
parent
a4fe0f1cb4
commit
938852afd3
|
@ -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
|
|
@ -140,12 +140,13 @@ PERLMOD_LATEX = NO
|
||||||
PERLMOD_PRETTY = YES
|
PERLMOD_PRETTY = YES
|
||||||
PERLMOD_MAKEVAR_PREFIX =
|
PERLMOD_MAKEVAR_PREFIX =
|
||||||
ENABLE_PREPROCESSING = YES
|
ENABLE_PREPROCESSING = YES
|
||||||
MACRO_EXPANSION = NO
|
MACRO_EXPANSION = YES
|
||||||
EXPAND_ONLY_PREDEF = NO
|
EXPAND_ONLY_PREDEF = YES
|
||||||
SEARCH_INCLUDES = YES
|
SEARCH_INCLUDES = YES
|
||||||
INCLUDE_PATH =
|
INCLUDE_PATH =
|
||||||
INCLUDE_FILE_PATTERNS =
|
INCLUDE_FILE_PATTERNS =
|
||||||
PREDEFINED = DOXYGEN
|
PREDEFINED = DOXYGEN \
|
||||||
|
__attribute__()=
|
||||||
EXPAND_AS_DEFINED =
|
EXPAND_AS_DEFINED =
|
||||||
SKIP_FUNCTION_MACROS = YES
|
SKIP_FUNCTION_MACROS = YES
|
||||||
TAGFILES =
|
TAGFILES =
|
||||||
|
|
|
@ -8,6 +8,11 @@
|
||||||
#include "lwevent.h"
|
#include "lwevent.h"
|
||||||
|
|
||||||
/* Below are all the includes used throughout the library. */
|
/* Below are all the includes used throughout the library. */
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/epoll.h>
|
||||||
|
|
||||||
/* options for text editors
|
/* options for text editors
|
||||||
kate: replace-trailing-space-save true; space-indent true; tab-width 4;
|
kate: replace-trailing-space-save true; space-indent true; tab-width 4;
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
/* liblwevent/src/liblwevent/100_struct_lwevent.c
|
||||||
|
*
|
||||||
|
* (c)2007, Laurence Withers, <l@lwithers.me.uk>.
|
||||||
|
* 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
|
||||||
|
*/
|
|
@ -0,0 +1,149 @@
|
||||||
|
/* liblwevent/src/liblwevent/200_eventloop.c
|
||||||
|
*
|
||||||
|
* (c)2007, Laurence Withers, <l@lwithers.me.uk>.
|
||||||
|
* 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
|
||||||
|
*/
|
|
@ -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.
|
/*! \brief Event loop exit flag.
|
||||||
|
|
||||||
This flag, if set, signifies that lwevent_loop() should exit after its next iteration. It can be
|
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
|
callback objects. The final action of this function is to free the memory associated with any
|
||||||
objects that are closed during the callbacks.
|
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);
|
int lwevent_wait(int timeout_ms);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
/* liblwevent/src/liblwevent/300_fdevent.c
|
||||||
|
*
|
||||||
|
* (c)2007, Laurence Withers, <l@lwithers.me.uk>.
|
||||||
|
* 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
|
||||||
|
*/
|
|
@ -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
|
directly. Instead, when it is time to close the file descriptor, pass the associated lwevent
|
||||||
structure to lwevent_free().
|
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);
|
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));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
The functions in this module allow the association of several parameters with each file descriptor
|
||||||
int lwevent_get_events(const struct lwevent* ev);
|
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);
|
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
|
/* options for text editors
|
||||||
kate: replace-trailing-space-save true; space-indent true; tab-width 4;
|
kate: replace-trailing-space-save true; space-indent true; tab-width 4;
|
||||||
vim: expandtab:ts=4:sw=4:syntax=c.doxygen
|
vim: expandtab:ts=4:sw=4:syntax=c.doxygen
|
||||||
|
|
|
@ -12,9 +12,9 @@ then
|
||||||
source src/liblwevent/soversion
|
source src/liblwevent/soversion
|
||||||
|
|
||||||
liblwevent="obj/${liblwevent_BASE}.so.${SOMAJOR}.${SOMICRO}"
|
liblwevent="obj/${liblwevent_BASE}.so.${SOMAJOR}.${SOMICRO}"
|
||||||
liblwevent_DEP_CFLAGS="" # @TODO@ cflags
|
liblwevent_DEP_CFLAGS=""
|
||||||
liblwevent_DEP_LIBS="" # @TODO@ libs
|
liblwevent_DEP_LIBS=""
|
||||||
SO_EXTRA="${liblwevent_DEP_CFLAGS} ${liblwevent_DEP_LIBS} -lc"
|
SO_EXTRA="-D_GNU_SOURCE -std=c99 ${liblwevent_DEP_CFLAGS} ${liblwevent_DEP_LIBS} -lc"
|
||||||
|
|
||||||
echo "Building library ${liblwevent}..."
|
echo "Building library ${liblwevent}..."
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue