pax_global_header 0000666 0000000 0000000 00000000064 13435347213 0014517 g ustar 00root root 0000000 0000000 52 comment=c63359ee0aa4fc416c336fae92d58129f315bb07
libverto-0.3.1/ 0000775 0000000 0000000 00000000000 13435347213 0013346 5 ustar 00root root 0000000 0000000 libverto-0.3.1/.autotools 0000664 0000000 0000000 00000002713 13435347213 0015403 0 ustar 00root root 0000000 0000000
libverto-0.3.1/.checkstyle 0000664 0000000 0000000 00000000437 13435347213 0015511 0 ustar 00root root 0000000 0000000
libverto-0.3.1/.cproject 0000664 0000000 0000000 00000064001 13435347213 0015161 0 ustar 00root root 0000000 0000000
makealltruetruefalsemakeam--refreshtruetruefalsemakechecktruetruefalsemakecleantruetruefalsemakeclean-libtooltruetruefalsemakectagstruetruefalsemakectags-recursivetruetruefalsemakedisttruetruefalsemakedist-alltruetruefalsemakedist-bzip2truetruefalsemakedist-gziptruetruefalsemakedist-lzmatruetruefalsemakedist-shartruetruefalsemakedist-tarZtruetruefalsemakedist-xztruetruefalsemakedist-ziptruetruefalsemakedistchecktruetruefalsemakedistcleantruetruefalsemakedistclean-libtooltruetruefalsemakedistclean-tagstruetruefalsemakedistcleanchecktruetruefalsemakedistdirtruetruefalsemakedistuninstallchecktruetruefalsemakedvitruetruefalsemakehtmltruetruefalsemakeinfotruetruefalsemakeinstalltruetruefalsemakeinstall-datatruetruefalsemakeinstall-dvitruetruefalsemakeinstall-exectruetruefalsemakeinstall-htmltruetruefalsemakeinstall-infotruetruefalsemakeinstall-mantruetruefalsemakeinstall-pdftruetruefalsemakeinstall-pkgconfigDATAtruetruefalsemakeinstall-pstruetruefalsemakeinstall-striptruetruefalsemakeinstallchecktruetruefalsemakeinstalldirstruetruefalsemakelibverto-glib.pctruetruefalsemakelibverto-libev.pctruetruefalsemakelibverto-libevent.pctruetruefalsemakelibverto-tevent.pctruetruefalsemakelibverto.pctruetruefalsemakemaintainer-cleantruetruefalsemakeMakefiletruetruefalsemakemostlycleantruetruefalsemakemostlyclean-libtooltruetruefalsemakepdftruetruefalsemakepstruetruefalsemaketagstruetruefalsemaketags-recursivetruetruefalsemakeuninstalltruetruefalsemakeuninstall-pkgconfigDATAtruetruefalse
libverto-0.3.1/.gitignore 0000664 0000000 0000000 00000000442 13435347213 0015336 0 ustar 00root root 0000000 0000000 .deps
.libs
aclocal.m4
autom4te.cache
config.guess
config.log
config.status
config.sub
configure
depcomp
install-sh
libtool
ltmain.sh
Makefile
Makefile.in
missing
test-driver
*.la
*.lo
*.o
*.log
*.pc
*.trs
tests/idle
tests/timeout
tests/child
tests/signal
tests/read
tests/write
INSTALL
libverto-0.3.1/.project 0000664 0000000 0000000 00000004150 13435347213 0015015 0 ustar 00root root 0000000 0000000
libvertoorg.eclipse.linuxtools.cdt.autotools.core.genmakebuilderV2org.eclipse.cdt.managedbuilder.core.genmakebuilderclean,full,incremental,?name?org.eclipse.cdt.make.core.append_environmenttrueorg.eclipse.cdt.make.core.buildArgumentsorg.eclipse.cdt.make.core.buildCommandmakeorg.eclipse.cdt.make.core.contentsorg.eclipse.cdt.make.core.activeConfigSettingsorg.eclipse.cdt.make.core.enableAutoBuildfalseorg.eclipse.cdt.make.core.enableCleanBuildtrueorg.eclipse.cdt.make.core.enableFullBuildtrueorg.eclipse.cdt.make.core.stopOnErrortrueorg.eclipse.cdt.make.core.useDefaultBuildCmdtrueorg.eclipse.cdt.managedbuilder.core.ScannerConfigBuilderfull,incremental,org.eclipse.cdt.core.cnatureorg.eclipse.cdt.managedbuilder.core.managedBuildNatureorg.eclipse.cdt.managedbuilder.core.ScannerConfigNatureorg.eclipse.linuxtools.cdt.autotools.core.autotoolsNatureV2
libverto-0.3.1/.settings/ 0000775 0000000 0000000 00000000000 13435347213 0015264 5 ustar 00root root 0000000 0000000 libverto-0.3.1/.settings/org.eclipse.cdt.core.prefs 0000664 0000000 0000000 00000030651 13435347213 0022244 0 ustar 00root root 0000000 0000000 #Thu Jun 09 17:23:01 EDT 2011
eclipse.preferences.version=1
org.eclipse.cdt.core.formatter.alignment_for_arguments_in_method_invocation=16
org.eclipse.cdt.core.formatter.alignment_for_base_clause_in_type_declaration=80
org.eclipse.cdt.core.formatter.alignment_for_compact_if=0
org.eclipse.cdt.core.formatter.alignment_for_conditional_expression=80
org.eclipse.cdt.core.formatter.alignment_for_declarator_list=16
org.eclipse.cdt.core.formatter.alignment_for_enumerator_list=48
org.eclipse.cdt.core.formatter.alignment_for_expression_list=0
org.eclipse.cdt.core.formatter.alignment_for_expressions_in_array_initializer=16
org.eclipse.cdt.core.formatter.alignment_for_parameters_in_method_declaration=18
org.eclipse.cdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
org.eclipse.cdt.core.formatter.brace_position_for_array_initializer=end_of_line
org.eclipse.cdt.core.formatter.brace_position_for_block=end_of_line
org.eclipse.cdt.core.formatter.brace_position_for_block_in_case=end_of_line
org.eclipse.cdt.core.formatter.brace_position_for_method_declaration=next_line
org.eclipse.cdt.core.formatter.brace_position_for_namespace_declaration=end_of_line
org.eclipse.cdt.core.formatter.brace_position_for_switch=end_of_line
org.eclipse.cdt.core.formatter.brace_position_for_type_declaration=end_of_line
org.eclipse.cdt.core.formatter.compact_else_if=true
org.eclipse.cdt.core.formatter.continuation_indentation=2
org.eclipse.cdt.core.formatter.continuation_indentation_for_array_initializer=2
org.eclipse.cdt.core.formatter.format_guardian_clause_on_one_line=false
org.eclipse.cdt.core.formatter.indent_access_specifier_compare_to_type_header=false
org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_access_specifier=true
org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_namespace_header=false
org.eclipse.cdt.core.formatter.indent_breaks_compare_to_cases=true
org.eclipse.cdt.core.formatter.indent_declaration_compare_to_template_header=false
org.eclipse.cdt.core.formatter.indent_empty_lines=false
org.eclipse.cdt.core.formatter.indent_statements_compare_to_block=true
org.eclipse.cdt.core.formatter.indent_statements_compare_to_body=true
org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_cases=true
org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_switch=false
org.eclipse.cdt.core.formatter.indentation.size=8
org.eclipse.cdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
org.eclipse.cdt.core.formatter.insert_new_line_after_template_declaration=do not insert
org.eclipse.cdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
org.eclipse.cdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
org.eclipse.cdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
org.eclipse.cdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
org.eclipse.cdt.core.formatter.insert_new_line_before_identifier_in_function_declaration=do not insert
org.eclipse.cdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
org.eclipse.cdt.core.formatter.insert_new_line_in_empty_block=insert
org.eclipse.cdt.core.formatter.insert_space_after_assignment_operator=insert
org.eclipse.cdt.core.formatter.insert_space_after_binary_operator=insert
org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_arguments=insert
org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_parameters=insert
org.eclipse.cdt.core.formatter.insert_space_after_closing_brace_in_block=insert
org.eclipse.cdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
org.eclipse.cdt.core.formatter.insert_space_after_colon_in_base_clause=insert
org.eclipse.cdt.core.formatter.insert_space_after_colon_in_case=insert
org.eclipse.cdt.core.formatter.insert_space_after_colon_in_conditional=insert
org.eclipse.cdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_base_types=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_declarator_list=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_expression_list=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_arguments=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_parameters=insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_arguments=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_parameters=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_bracket=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_exception_specification=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_postfix_operator=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_prefix_operator=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_question_in_conditional=insert
org.eclipse.cdt.core.formatter.insert_space_after_semicolon_in_for=insert
org.eclipse.cdt.core.formatter.insert_space_after_unary_operator=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_assignment_operator=insert
org.eclipse.cdt.core.formatter.insert_space_before_binary_operator=insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_arguments=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_parameters=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_bracket=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_exception_specification=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_base_clause=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_case=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_conditional=insert
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_default=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_base_types=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_declarator_list=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_expression_list=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_arguments=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_parameters=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_arguments=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_parameters=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_block=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_namespace_declaration=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_bracket=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_exception_specification=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_for=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_if=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_while=insert
org.eclipse.cdt.core.formatter.insert_space_before_postfix_operator=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_prefix_operator=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_question_in_conditional=insert
org.eclipse.cdt.core.formatter.insert_space_before_semicolon=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_unary_operator=do not insert
org.eclipse.cdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
org.eclipse.cdt.core.formatter.insert_space_between_empty_brackets=do not insert
org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_exception_specification=do not insert
org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
org.eclipse.cdt.core.formatter.keep_else_statement_on_same_line=false
org.eclipse.cdt.core.formatter.keep_empty_array_initializer_on_one_line=false
org.eclipse.cdt.core.formatter.keep_imple_if_on_one_line=false
org.eclipse.cdt.core.formatter.keep_then_statement_on_same_line=false
org.eclipse.cdt.core.formatter.lineSplit=80
org.eclipse.cdt.core.formatter.number_of_empty_lines_to_preserve=1
org.eclipse.cdt.core.formatter.put_empty_statement_on_new_line=true
org.eclipse.cdt.core.formatter.tabulation.char=space
org.eclipse.cdt.core.formatter.tabulation.size=4
org.eclipse.cdt.core.formatter.use_tabs_only_for_leading_indentations=false
libverto-0.3.1/.settings/org.eclipse.cdt.ui.prefs 0000664 0000000 0000000 00000000164 13435347213 0021725 0 ustar 00root root 0000000 0000000 #Thu Jun 09 15:51:38 EDT 2011
eclipse.preferences.version=1
formatter_profile=_FreeIPA
formatter_settings_version=1
libverto-0.3.1/.travis.sh 0000775 0000000 0000000 00000001533 13435347213 0015275 0 ustar 00root root 0000000 0000000 #!/bin/bash -ex
CFLAGS="-Werror"
if [ x$BUILTIN == xyes ]; then
CFLAGS+=" -DBUILTIN_MODULE=libev"
fi
if [ -f /etc/debian_version ]; then
apt-get update
apt-get -y install autoconf build-essential libtool $COMPILER \
lib{ev,event,glib2.0}-dev
elif [ -f /etc/fedora-release ]; then
# dnf has no update-only verb
dnf -y install autoconf automake libtool make which $COMPILER \
{glib2,libevent,libev}-devel --nogpgcheck --skip-broken
elif [ -f /etc/redhat-release ]; then
# rhel/centos
yum -y install autoconf automake libtool make which $COMPILER \
{glib2,libevent}-devel
# rhel doesn't have libev anyway
CFLAGS+=" -std=c89"
else
echo "Distro not found!"
false
fi
autoreconf -fiv
./configure CFLAGS="$CFLAGS" CC=$(which $COMPILER)
make
if [ x$BUILTIN != xyes ]; then
make check
fi
libverto-0.3.1/.travis.yml 0000664 0000000 0000000 00000000707 13435347213 0015463 0 ustar 00root root 0000000 0000000 sudo: required
# not necessary, but less confusing if defined
language: C
services:
- docker
env:
- DISTRO=debian:sid COMPILER=gcc
- DISTRO=debian:sid COMPILER=gcc BUILTIN=yes
- DISTRO=fedora:latest COMPILER=gcc
- DISTRO=fedora:latest COMPILER=clang
- DISTRO=centos:7 COMPILER=gcc
script:
- >
docker run
-v `pwd`:/tmp/build
-w /tmp/build
-e COMPILER=$COMPILER
-e BUILTIN=$BUILTIN
$DISTRO /bin/bash -ex .travis.sh
libverto-0.3.1/AUTHORS 0000664 0000000 0000000 00000000053 13435347213 0014414 0 ustar 00root root 0000000 0000000 Nathaniel McCallum
libverto-0.3.1/COPYING 0000664 0000000 0000000 00000002036 13435347213 0014402 0 ustar 00root root 0000000 0000000 Copyright 2011 Red Hat, Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
libverto-0.3.1/ChangeLog 0000664 0000000 0000000 00000002653 13435347213 0015126 0 ustar 00root root 0000000 0000000 2012-08-25 Nathaniel McCallum
* == Release 0.2.5 ==
* fix libev's set_flags() implementation
* add AIX dlopen() support
* export symbols based on symbol list files
* add support for building in a static module
* add support for specifying default module
2012-02-09 Nathaniel McCallum
* == Release 0.2.4 ==
* add verto_set_flags()
2012-02-08 Nathaniel McCallum
* == Release 0.2.3 ==
* add external allocator support
* add extern "C" to all headers
* support getting fd state in callbacks
* support getting ctx from ev
* add support for auto-closing file descriptors
* fix a bug where we wrote to free'd memory
2011-11-11 Nathaniel McCallum
* == Release 0.2.2 ==
* Remove trailing uses of types starting with _
* Documentation fix
2011-11-10 Nathaniel McCallum
* == Release 0.2.1 ==
* Build system fix for broken 0.2.0 release
2011-11-10 Nathaniel McCallum
* == Release 0.2.0 ==
* Fix inconsistent verto_default() singleton state
* Give modules unique table names
* Remove signal table verification magic (no longer needed)
* Give verto_reinitialize() an error condition (int return value)
* Add (optional) pthread locking around our global state
* Cleanup the build system arguments
2011-09-30 Nathaniel McCallum
* Initial release
libverto-0.3.1/Makefile.am 0000664 0000000 0000000 00000000533 13435347213 0015403 0 ustar 00root root 0000000 0000000 pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libverto.pc
if MODULE_GLIB
pkgconfig_DATA += libverto-glib.pc
endif
if MODULE_LIBEV
pkgconfig_DATA += libverto-libev.pc
endif
if MODULE_LIBEVENT
pkgconfig_DATA += libverto-libevent.pc
endif
if MODULE_TEVENT
pkgconfig_DATA += libverto-tevent.pc
endif
ACLOCAL_AMFLAGS=-I m4
SUBDIRS=src tests
libverto-0.3.1/NEWS 0000664 0000000 0000000 00000000047 13435347213 0014046 0 ustar 00root root 0000000 0000000 Sample NEWS file for libverto project.
libverto-0.3.1/README 0000664 0000000 0000000 00000001151 13435347213 0014224 0 ustar 00root root 0000000 0000000 libverto
===============================================================================
libverto exists to solve an important problem: many applications and libraries
are unable to write asynchronous code because they are unable to pick an event
loop. This is particularly true of libraries who want to be useful to many
applications who use loops that do not integrate with one another or which
use home-grown loops. libverto provides a loop-neutral async api which allows
the library to expose asynchronous interfaces and offload the choice of the
main loop to the application.
libverto-0.3.1/configure.ac 0000664 0000000 0000000 00000015723 13435347213 0015644 0 ustar 00root root 0000000 0000000 dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.59)
AC_INIT(libverto, 0.3.1)
m4_ifdef([AC_USE_SYSTEM_EXTENSIONS],
[AC_USE_SYSTEM_EXTENSIONS],
[AC_GNU_SOURCE])
AC_PROG_CC_C99
for flag in -Wall -Wextra -Wno-cast-function-type; do
OLD_CFLAGS=$CFLAGS
CFLAGS="$CFLAGS $flag"
AC_TRY_COMPILE(, [return 0;], [], [CFLAGS=$OLD_CFLAGS])
done
AC_CANONICAL_SYSTEM
AM_INIT_AUTOMAKE([1.11])
AC_PROG_LIBTOOL
AC_CONFIG_MACRO_DIR([m4])
m4_ifdef([AM_SILENT_RULES], [
AM_SILENT_RULES([yes])
], [
AM_DEFAULT_VERBOSITY=1
AC_SUBST(AM_DEFAULT_VERBOSITY)
])
PKG_PROG_PKG_CONFIG
AC_CHECK_LIB([dl],[dlopen])
AC_ARG_WITH([pthread],
[AS_HELP_STRING([--with-pthread],
[build pthread support @<:@default: automatic@:>@])],
[case $withval in
no) WITH_PTHREAD=no;;
yes) WITH_PTHREAD=yes;;
*) WITH_PTHREAD=auto;;
esac], [WITH_PTHREAD=auto])
BUILD_PTHREAD=no
if test x$WITH_PTHREAD != xno; then
AX_PTHREAD([PTHREAD_CFLAGS="$PTHREAD_CFLAGS -DHAVE_PTHREAD=1";
CC="$PTHREAD_CC";
BUILD_PTHREAD=yes],
[test x$WITH_PTHREAD = xyes && AC_MSG_ERROR("pthread not found")])
fi
AC_ARG_WITH([glib],
[AS_HELP_STRING([--with-glib],
[build the glib library @<:@default: automatic@:>@])],
[case $withval in
no) WITH_GLIB=no;;
yes) WITH_GLIB=yes;;
default) WITH_GLIB=default;;
builtin) WITH_GLIB=builtin;;
*) WITH_GLIB=auto;;
esac], [WITH_GLIB=auto])
AC_ARG_WITH([libev],
[AS_HELP_STRING([--with-libev],
[build the libev library @<:@default: automatic@:>@])],
[case $withval in
no) WITH_LIBEV=no;;
yes) WITH_LIBEV=yes;;
default) WITH_LIBEV=default;;
builtin) WITH_LIBEV=builtin;;
*) WITH_LIBEV=auto;;
esac], [WITH_LIBEV=auto])
AC_ARG_WITH([libevent],
[AS_HELP_STRING([--with-libevent],
[build the libevent library @<:@default: automatic@:>@])],
[case $withval in
no) WITH_LIBEVENT=no;;
yes) WITH_LIBEVENT=yes;;
default) WITH_LIBEVENT=default;;
builtin) WITH_LIBEVENT=builtin;;
*) WITH_LIBEVENT=auto;;
esac], [WITH_LIBEVENT=auto])
AC_ARG_WITH([tevent],
[AS_HELP_STRING([--with-tevent],
[build the tevent library @<:@default: automatic@:>@])],
[case $withval in
no) WITH_TEVENT=no;;
yes) WITH_TEVENT=yes;;
*) WITH_TEVENT=auto;;
esac], [WITH_TEVENT=auto])
# Ensure that if a builtin is chosen only one is built
BUILTIN_MODULE=
if test x$WITH_GLIB == xbuiltin; then
BUILTIN_MODULE=glib
WITH_LIBEV=no
WITH_LIBEVENT=no
WITH_TEVENT=no
elif test x$WITH_LIBEV == xbuiltin; then
BUILTIN_MODULE=libev
WITH_LIBGLIB=no
WITH_LIBEVENT=no
WITH_TEVENT=no
elif test x$WITH_LIBEVENT == xbuiltin; then
BUILTIN_MODULE=libevent
WITH_LIBGLIB=no
WITH_LIBEV=no
WITH_TEVENT=no
elif test x$WITH_TEVENT == xbuiltin; then
BUILTIN_MODULE=tevent
WITH_GLIB=no
WITH_LIBEV=no
WITH_LIBEVENT=no
fi
AC_SUBST([BUILTIN_MODULE], $BUILTIN_MODULE)
if test x$BUILTIN_MODULE != x; then
AC_DEFINE_UNQUOTED([BUILTIN_MODULE], $BUILTIN_MODULE)
fi
# Ensure that there is only one default (convert duplicate default to yes)
if test x$WITH_GLIB == xdefault; then
AC_DEFINE([DEFUALT_MODULE], [glib])
test x$WITH_LIBEV == xdefault && WITH_LIBEV=yes
test x$WITH_LIBEVENT == xdefault && WITH_LIBEVENT=yes
test x$WITH_TEVENT == xdefault && WITH_TEVENT=yes
fi
if test x$WITH_LIBEV == xdefault; then
AC_DEFINE([DEFUALT_MODULE], [libev])
test x$WITH_LIBGLIB == xdefault && WITH_GLIB=yes
test x$WITH_LIBEVENT == xdefault && WITH_LIBEVENT=yes
test x$WITH_TEVENT == xdefault && WITH_TEVENT=yes
fi
if test x$WITH_LIBEVENT == xdefault; then
AC_DEFINE([DEFUALT_MODULE], [libevent])
test x$WITH_GLIB == xdefault && WITH_GLIB=yes
test x$WITH_LIBEV == xdefault && WITH_LIBEV=yes
test x$WITH_TEVENT == xdefault && WITH_TEVENT=yes
fi
if test x$WITH_TEVENT == xdefault; then
AC_DEFINE([DEFUALT_MODULE], [tevent])
test x$WITH_GLIB == xdefault && WITH_GLIB=yes
test x$WITH_LIBEV == xdefault && WITH_LIBEV=yes
test x$WITH_LIBEVENT == xdefault && WITH_LIBEVENT=yes
fi
BUILD_GLIB=no
BUILD_LIBEV=no
BUILD_LIBEVENT=no
BUILD_TEVENT=no
if test x$WITH_GLIB != xno; then
PKG_CHECK_MODULES([glib], [glib-2.0], [BUILD_GLIB=$WITH_GLIB],
[test x$WITH_GLIB != xauto && AC_MSG_ERROR("glib not found")])
if test x$BUILD_GLIB == xauto; then
BUILD_GLIB=yes
fi
fi
if test x$WITH_LIBEV != xno; then
AC_CHECK_HEADER(
[ev.h],
AC_CHECK_LIB(
[ev], [ev_loop_new], [BUILD_LIBEV=$WITH_LIBEV],
[test x$WITH_LIBEV != xauto && AC_MSG_ERROR("libev not found")]
),
[test x$WITH_LIBEV != xauto && AC_MSG_ERROR("ev.h not found")]
)
if test x$BUILD_LIBEV == xauto; then
BUILD_LIBEV=yes
fi
fi
if test x$WITH_LIBEVENT != xno; then
PKG_CHECK_MODULES([libevent], [libevent >= 2.0], [BUILD_LIBEVENT=$WITH_LIBEVENT],
[test x$WITH_LIBEVENT != xauto && AC_MSG_ERROR("libevent not found")])
if test x$BUILD_LIBEVENT == xauto; then
BUILD_LIBEVENT=yes
fi
fi
if test x$WITH_TEVENT != xno; then
PKG_CHECK_MODULES([tevent], [tevent], [BUILD_TEVENT=$WITH_TEVENT],
[test x$WITH_TEVENT != xauto && AC_MSG_ERROR("tevent not found")])
if test x$BUILD_TEVENT == xauto; then
BUILD_TEVENT=yes
fi
fi
AM_CONDITIONAL([MODULE_GLIB], [test x$BUILTIN_MODULE == x && test x$BUILD_GLIB != xno])
AM_CONDITIONAL([MODULE_LIBEV], [test x$BUILTIN_MODULE == x && test x$BUILD_LIBEV != xno])
AM_CONDITIONAL([MODULE_LIBEVENT], [test x$BUILTIN_MODULE == x && test x$BUILD_LIBEVENT != xno])
AM_CONDITIONAL([MODULE_TEVENT], [test x$BUILTIN_MODULE == x && test x$BUILD_TEVENT != xno])
AM_CONDITIONAL([BUILTIN_GLIB], [test x$BUILTIN_MODULE == xglib])
AM_CONDITIONAL([BUILTIN_LIBEV], [test x$BUILTIN_MODULE == xlibev])
AM_CONDITIONAL([BUILTIN_LIBEVENT], [test x$BUILTIN_MODULE == xlibevent])
AM_CONDITIONAL([BUILTIN_TEVENT], [test x$BUILTIN_MODULE == xtevent])
AC_MSG_NOTICE()
AC_MSG_NOTICE([BUILD CONFIGURATION])
AC_MSG_NOTICE(AS_HELP_STRING([pthread], [$BUILD_PTHREAD]))
AC_MSG_NOTICE(AS_HELP_STRING([glib], [$BUILD_GLIB]))
AC_MSG_NOTICE(AS_HELP_STRING([libev], [$BUILD_LIBEV]))
AC_MSG_NOTICE(AS_HELP_STRING([libevent], [$BUILD_LIBEVENT]))
AC_MSG_NOTICE(AS_HELP_STRING([tevent], [$BUILD_TEVENT]))
AC_MSG_NOTICE()
AC_CONFIG_FILES(Makefile
src/Makefile
tests/Makefile
libverto-glib.pc
libverto-libev.pc
libverto-libevent.pc
libverto-tevent.pc
libverto.pc)
AC_OUTPUT
libverto-0.3.1/libverto-glib.pc.in 0000664 0000000 0000000 00000000411 13435347213 0017034 0 ustar 00root root 0000000 0000000 prefix=@prefix@
libdir=@libdir@
includedir=@includedir@
exec_prefix=@exec_prefix@
Name: libverto-glib
Description: Event loop abstraction interface (glib module)
Version: @VERSION@
Libs: -L${libdir} -lverto-glib
Cflags: -I${includedir}
Requires.private: libverto
libverto-0.3.1/libverto-libev.pc.in 0000664 0000000 0000000 00000000414 13435347213 0017223 0 ustar 00root root 0000000 0000000 prefix=@prefix@
libdir=@libdir@
includedir=@includedir@
exec_prefix=@exec_prefix@
Name: libverto-libev
Description: Event loop abstraction interface (libev module)
Version: @VERSION@
Libs: -L${libdir} -lverto-libev
Cflags: -I${includedir}
Requires.private: libverto
libverto-0.3.1/libverto-libevent.pc.in 0000664 0000000 0000000 00000000425 13435347213 0017734 0 ustar 00root root 0000000 0000000 prefix=@prefix@
libdir=@libdir@
includedir=@includedir@
exec_prefix=@exec_prefix@
Name: libverto-libevent
Description: Event loop abstraction interface (libevent module)
Version: @VERSION@
Libs: -L${libdir} -lverto-libevent
Cflags: -I${includedir}
Requires.private: libverto
libverto-0.3.1/libverto-tevent.pc.in 0000664 0000000 0000000 00000000417 13435347213 0017432 0 ustar 00root root 0000000 0000000 prefix=@prefix@
libdir=@libdir@
includedir=@includedir@
exec_prefix=@exec_prefix@
Name: libverto-tevent
Description: Event loop abstraction interface (tevent module)
Version: @VERSION@
Libs: -L${libdir} -lverto-tevent
Cflags: -I${includedir}
Requires.private: libverto
libverto-0.3.1/libverto.pc.in 0000664 0000000 0000000 00000000353 13435347213 0016126 0 ustar 00root root 0000000 0000000 prefix=@prefix@
libdir=@libdir@
includedir=@includedir@
exec_prefix=@exec_prefix@
Name: libverto
Description: Event loop abstraction interface
Version: @VERSION@
Libs: -L${libdir} -lverto
Cflags: -I${includedir}
Libs.private: @LIBS@
libverto-0.3.1/m4/ 0000775 0000000 0000000 00000000000 13435347213 0013666 5 ustar 00root root 0000000 0000000 libverto-0.3.1/m4/.gitignore 0000664 0000000 0000000 00000000016 13435347213 0015653 0 ustar 00root root 0000000 0000000 *
!.gitignore
libverto-0.3.1/m4/ax_pthread.m4 0000664 0000000 0000000 00000030161 13435347213 0016250 0 ustar 00root root 0000000 0000000 # ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_pthread.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
#
# DESCRIPTION
#
# This macro figures out how to build C programs using POSIX threads. It
# sets the PTHREAD_LIBS output variable to the threads library and linker
# flags, and the PTHREAD_CFLAGS output variable to any special C compiler
# flags that are needed. (The user can also force certain compiler
# flags/libs to be tested by setting these environment variables.)
#
# Also sets PTHREAD_CC to any special C compiler that is needed for
# multi-threaded programs (defaults to the value of CC otherwise). (This
# is necessary on AIX to use the special cc_r compiler alias.)
#
# NOTE: You are assumed to not only compile your program with these flags,
# but also link it with them as well. e.g. you should link with
# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
#
# If you are only building threads programs, you may wish to use these
# variables in your default LIBS, CFLAGS, and CC:
#
# LIBS="$PTHREAD_LIBS $LIBS"
# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# CC="$PTHREAD_CC"
#
# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
# (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
#
# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
# PTHREAD_PRIO_INHERIT symbol is defined when compiling with
# PTHREAD_CFLAGS.
#
# ACTION-IF-FOUND is a list of shell commands to run if a threads library
# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
# is not found. If ACTION-IF-FOUND is not specified, the default action
# will define HAVE_PTHREAD.
#
# Please let the authors know if this macro fails on any platform, or if
# you have any other suggestions or comments. This macro was based on work
# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
# Alejandro Forero Cuervo to the autoconf macro repository. We are also
# grateful for the helpful feedback of numerous users.
#
# Updated for Autoconf 2.68 by Daniel Richard G.
#
# LICENSE
#
# Copyright (c) 2008 Steven G. Johnson
# Copyright (c) 2011 Daniel Richard G.
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see .
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 16
AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
AC_DEFUN([AX_PTHREAD], [
AC_REQUIRE([AC_CANONICAL_HOST])
AC_LANG_PUSH([C])
ax_pthread_ok=no
# We used to check for pthread.h first, but this fails if pthread.h
# requires special compiler flags (e.g. on True64 or Sequent).
# It gets checked for in the link test anyway.
# First of all, check if the user has set any of the PTHREAD_LIBS,
# etcetera environment variables, and if threads linking works using
# them:
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes)
AC_MSG_RESULT($ax_pthread_ok)
if test x"$ax_pthread_ok" = xno; then
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
fi
# We must check for the threads library under a number of different
# names; the ordering is very important because some systems
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
# libraries is broken (non-POSIX).
# Create a list of thread flags to try. Items starting with a "-" are
# C compiler flags, and other items are library names, except for "none"
# which indicates that we try without any flags at all, and "pthread-config"
# which is a program returning the flags for the Pth emulation library.
ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
# pthreads: AIX (must check this before -lpthread)
# none: in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
# -pthreads: Solaris/gcc
# -mthreads: Mingw32/gcc, Lynx/gcc
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads too;
# also defines -D_REENTRANT)
# ... -mt is also the pthreads flag for HP/aCC
# pthread: Linux, etcetera
# --thread-safe: KAI C++
# pthread-config: use pthread-config program (for GNU Pth library)
case "${host_cpu}-${host_os}" in
*solaris*)
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (We need to link with -pthreads/-mt/
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
# a function called by this macro, so we could check for that, but
# who knows whether they'll stub that too in a future libc.) So,
# we'll just look for -pthreads and -lpthread first:
ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
;;
*-darwin*)
ax_pthread_flags="-pthread $ax_pthread_flags"
;;
esac
if test x"$ax_pthread_ok" = xno; then
for flag in $ax_pthread_flags; do
case $flag in
none)
AC_MSG_CHECKING([whether pthreads work without any flags])
;;
-*)
AC_MSG_CHECKING([whether pthreads work with $flag])
PTHREAD_CFLAGS="$flag"
;;
pthread-config)
AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no)
if test x"$ax_pthread_config" = xno; then continue; fi
PTHREAD_CFLAGS="`pthread-config --cflags`"
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
;;
*)
AC_MSG_CHECKING([for the pthreads library -l$flag])
PTHREAD_LIBS="-l$flag"
;;
esac
save_LIBS="$LIBS"
save_CFLAGS="$CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
# need a special flag -Kthread to make this header compile.)
# We check for pthread_join because it is in -lpthread on IRIX
# while pthread_create is in libc. We check for pthread_attr_init
# due to DEC craziness with -lpthreads. We check for
# pthread_cleanup_push because it is one of the few pthread
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include
static void routine(void *a) { a = 0; }
static void *start_routine(void *a) { return a; }],
[pthread_t th; pthread_attr_t attr;
pthread_create(&th, 0, start_routine, 0);
pthread_join(th, 0);
pthread_attr_init(&attr);
pthread_cleanup_push(routine, 0);
pthread_cleanup_pop(0) /* ; */])],
[ax_pthread_ok=yes],
[])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
AC_MSG_RESULT($ax_pthread_ok)
if test "x$ax_pthread_ok" = xyes; then
break;
fi
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
done
fi
# Various other checks:
if test "x$ax_pthread_ok" = xyes; then
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
AC_MSG_CHECKING([for joinable pthread attribute])
attr_name=unknown
for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ],
[int attr = $attr; return attr /* ; */])],
[attr_name=$attr; break],
[])
done
AC_MSG_RESULT($attr_name)
if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
[Define to necessary symbol if this constant
uses a non-standard name on your system.])
fi
AC_MSG_CHECKING([if more special flags are required for pthreads])
flag=no
case "${host_cpu}-${host_os}" in
*-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
*solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
esac
AC_MSG_RESULT(${flag})
if test "x$flag" != xno; then
PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
fi
AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
ax_cv_PTHREAD_PRIO_INHERIT, [
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT;]])],
[ax_cv_PTHREAD_PRIO_INHERIT=yes],
[ax_cv_PTHREAD_PRIO_INHERIT=no])
])
AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.]))
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
# More AIX lossage: must compile with xlc_r or cc_r
if test x"$GCC" != xyes; then
AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
else
PTHREAD_CC=$CC
fi
else
PTHREAD_CC="$CC"
fi
AC_SUBST(PTHREAD_LIBS)
AC_SUBST(PTHREAD_CFLAGS)
AC_SUBST(PTHREAD_CC)
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test x"$ax_pthread_ok" = xyes; then
ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
:
else
ax_pthread_ok=no
$2
fi
AC_LANG_POP
])dnl AX_PTHREAD
libverto-0.3.1/src/ 0000775 0000000 0000000 00000000000 13435347213 0014135 5 ustar 00root root 0000000 0000000 libverto-0.3.1/src/Makefile.am 0000664 0000000 0000000 00000004454 13435347213 0016200 0 ustar 00root root 0000000 0000000 AM_CFLAGS = -Wall -Wdeclaration-after-statement
AM_LDFLAGS = -version-info 1:0:0
EXTRA_DIST = libverto.symbols libverto-glib.symbols libverto-libev.symbols \
libverto-libevent.symbols libverto-tevent.symbols
include_HEADERS = verto.h verto-module.h
noinst_HEADERS = module.h
lib_LTLIBRARIES = libverto.la
libverto_la_SOURCES = verto.c module.c verto.h
libverto_la_CFLAGS = $(AM_CFLAGS) $($(BUILTIN_MODULE)_CFLAGS) $(PTHREAD_CFLAGS)
libverto_la_LDFLAGS = $(AM_LDFLAGS) $($(BUILTIN_MODULE)_LIBS) $(PTHREAD_LIBS) $(LIBS) \
-export-symbols $(srcdir)/libverto.symbols
if BUILTIN_GLIB
libverto_la_SOURCES += verto-glib.c
endif
if BUILTIN_LIBEV
libverto_la_SOURCES += verto-libev.c
endif
if BUILTIN_LIBEVENT
libverto_la_SOURCES += verto-libevent.c
endif
if BUILTIN_TEVENT
libverto_la_SOURCES += verto-tevent.c
endif
if MODULE_GLIB
lib_LTLIBRARIES += libverto-glib.la
include_HEADERS += verto-glib.h
libverto_glib_la_SOURCES = verto-glib.c
libverto_glib_la_LIBADD = libverto.la
libverto_glib_la_CFLAGS = $(AM_CFLAGS) $(glib_CFLAGS)
libverto_glib_la_LDFLAGS = $(AM_LDFLAGS) $(glib_LIBS) \
-export-symbols $(srcdir)/libverto-glib.symbols
endif
if MODULE_LIBEV
lib_LTLIBRARIES += libverto-libev.la
include_HEADERS += verto-libev.h
libverto_libev_la_SOURCES = verto-libev.c
libverto_libev_la_LIBADD = libverto.la
libverto_libev_la_CFLAGS = $(AM_CFLAGS)
libverto_libev_la_LDFLAGS = $(AM_LDFLAGS) -lev \
-export-symbols $(srcdir)/libverto-libev.symbols
endif
if MODULE_LIBEVENT
lib_LTLIBRARIES += libverto-libevent.la
include_HEADERS += verto-libevent.h
libverto_libevent_la_SOURCES = verto-libevent.c
libverto_libevent_la_LIBADD = libverto.la
libverto_libevent_la_CFLAGS = $(AM_CFLAGS) $(libevent_CFLAGS)
libverto_libevent_la_LDFLAGS = $(AM_LDFLAGS) $(libevent_LIBS) \
-export-symbols $(srcdir)/libverto-libevent.symbols
endif
if MODULE_TEVENT
lib_LTLIBRARIES += libverto-tevent.la
include_HEADERS += verto-tevent.h
libverto_tevent_la_SOURCES = verto-tevent.c
libverto_tevent_la_LIBADD = libverto.la
libverto_tevent_la_CFLAGS = $(AM_CFLAGS) $(tevent_CFLAGS)
libverto_tevent_la_LDFLAGS = $(AM_LDFLAGS) $(tevent_LIBS) \
-export-symbols $(srcdir)/libverto-tevent.symbols
endif
libverto-0.3.1/src/libverto-glib.symbols 0000664 0000000 0000000 00000000115 13435347213 0020305 0 ustar 00root root 0000000 0000000 verto_convert_glib
verto_default_glib
verto_module_table_glib
verto_new_glib
libverto-0.3.1/src/libverto-libev.symbols 0000664 0000000 0000000 00000000121 13435347213 0020466 0 ustar 00root root 0000000 0000000 verto_convert_libev
verto_default_libev
verto_module_table_libev
verto_new_libev
libverto-0.3.1/src/libverto-libevent.symbols 0000664 0000000 0000000 00000000135 13435347213 0021202 0 ustar 00root root 0000000 0000000 verto_convert_libevent
verto_default_libevent
verto_module_table_libevent
verto_new_libevent
libverto-0.3.1/src/libverto-tevent.symbols 0000664 0000000 0000000 00000000125 13435347213 0020676 0 ustar 00root root 0000000 0000000 verto_convert_tevent
verto_default_tevent
verto_module_table_tevent
verto_new_tevent
libverto-0.3.1/src/libverto.symbols 0000664 0000000 0000000 00000001025 13435347213 0017373 0 ustar 00root root 0000000 0000000 verto_add_child
verto_add_idle
verto_add_io
verto_add_signal
verto_add_timeout
verto_break
verto_cleanup
verto_convert_module
verto_default
verto_del
verto_fire
verto_free
verto_get_ctx
verto_get_fd
verto_get_fd_state
verto_get_flags
verto_get_interval
verto_get_private
verto_get_proc
verto_get_proc_status
verto_get_signal
verto_get_supported_types
verto_get_type
verto_new
verto_reinitialize
verto_run
verto_run_once
verto_set_allocator
verto_set_default
verto_set_fd_state
verto_set_flags
verto_set_private
verto_set_proc_status
libverto-0.3.1/src/module.c 0000664 0000000 0000000 00000013121 13435347213 0015564 0 ustar 00root root 0000000 0000000 /*
* Copyright 2011 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifdef WIN32
#include
#define dlltype HMODULE
static char *
dllerror(void) {
char *amsg;
LPTSTR msg;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &msg, 0, NULL);
amsg = strdup((const char*) msg);
LocalFree(msg);
return amsg;
}
#elif defined(aix)
#include "sys/ldr.h"
struct Dl_info {
const char* dli_fname;
};
static int
dladdr(void* s, Dl_info* i)
{
static const size_t bufSize = 4096;
G__FastAllocString buf(bufSize);
char* pldi = buf;
int r;
r = loadquery(L_GETINFO, pldi, bufSize);
if (r == -1) {
i->dli_fname = NULL;
return 0;
}
for (ld_info* ldi = (ld_info*) buf;
ldi->ldinfo_next;
ldi += ldi->ldinfo_next) {
char* textBegin = (char*) ldi->ldinfo_textorg;
if (textBegin < s) {
char* textEnd = textBegin + ldi->ldinfo_textsize;
if (textEnd > s) {
i->dli_fname = ldi->ldinfo_filename;
return 1;
}
}
}
// First is main(), skip.
ld_info* ldi = (ld_info*) pldi;
while (ldi->ldinfo_next) {
pldi += ldi->ldinfo_next;
ldi = (ld_info*) pldi;
}
i->dli_fname = NULL;
return 0;
}
#else
#include
#include
#include
#define dlltype void *
#define dllerror() strdup(dlerror())
#endif
int
module_symbol_is_present(const char *modname, const char *symbname)
{
#ifdef WIN32
return (GetProcAddress(GetModuleHandle(modname), symbname) != NULL ||
GetProcAddress(GetModuleHandle(NULL), symbname) != NULL);
#else /* WIN32 */
void *mod;
(void) modname;
mod = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL);
if (mod) {
void* sym = dlsym(mod, symbname);
dlclose(mod);
return sym != NULL;
}
#endif /* WIN32 */
return 0;
}
int
module_get_filename_for_symbol(void *addr, char **filename)
{
#ifdef WIN32
MEMORY_BASIC_INFORMATION info;
HMODULE mod;
char tmp[MAX_PATH];
if (!VirtualQuery(addr, &info, sizeof(info)))
return 0;
mod = (HMODULE) info.AllocationBase;
if (!GetModuleFileNameA(mod, tmp, MAX_PATH))
return 0;
#else
const char *tmp;
Dl_info dlinfo;
if (!dladdr(addr, &dlinfo))
return 0;
tmp = dlinfo.dli_fname;
#endif
if (filename) {
*filename = strdup(tmp);
if (!*filename)
return 0;
}
return 1;
}
void
module_close(void *dll)
{
if (!dll)
return;
#ifdef WIN32
FreeLibrary((dlltype) dll);
#else /* WIN32 */
dlclose((dlltype) dll);
#endif /* WIN32 */
}
char *
module_load(const char *filename, const char *symbname,
int (*shouldload)(void *symb, void *misc, char **err), void *misc,
void **dll, void **symb)
{
dlltype intdll = NULL;
void * intsym = NULL;
char * interr = NULL;
if (dll)
*dll = NULL;
if (symb)
*symb = NULL;
/* Open the module library */
#ifdef WIN32
/* NOTE: DONT_RESOLVE_DLL_REFERENCES is evil. Don't use this in your own
* code. However, our design pattern avoids all the issues surrounding a
* more general use of this evil flag. */
intdll = LoadLibraryEx(filename, NULL, DONT_RESOLVE_DLL_REFERENCES);
#else /* WIN32 */
intdll = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
#endif /* WIN32 */
if (!intdll)
goto fail;
/* Get the module symbol */
#ifdef WIN32
intsym = (void *) GetProcAddress(intdll, symbname);
#else /* WIN32 */
intsym = dlsym(intdll, symbname);
#endif /* WIN32 */
if (!intsym)
goto fail;
/* Figure out whether or not to load this module */
if (!shouldload(intsym, misc, &interr))
goto fail;
/* Re-open the module */
module_close(intdll);
#ifdef WIN32
intdll = LoadLibrary(filename);
#else /* WIN32 */
intdll = dlopen(filename, RTLD_NOW | RTLD_LOCAL);
#endif /* WIN32 */
if (!intdll)
goto fail;
/* Get the symbol again */
#ifdef WIN32
intsym = (void *) GetProcAddress(intdll, symbname);
#else /* WIN32 */
intsym = dlsym(intdll, symbname);
#endif /* WIN32 */
if (!intsym)
goto fail;
if (dll)
*dll = intdll;
if (symb)
*symb = intsym;
return NULL;
fail:
if (!interr)
interr = dllerror();
module_close(intdll);
return interr;
}
libverto-0.3.1/src/module.h 0000664 0000000 0000000 00000006342 13435347213 0015600 0 ustar 00root root 0000000 0000000 /*
* Copyright 2011 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/* Determines if a symbol is present in a given module.
*
* @param modname The name of the module.
* @param symbname The name of the symbol.
* @return Non-zero if found, zero if not found.
*/
int
module_symbol_is_present(const char *modname, const char *symbname);
/* Finds the file for a given symbol.
*
* If filename is non-null, the name of the file will be stored. This must
* be freed with free().
*
* @param addr The address to resolve.
* @param filename Where to store the name of the file.
* @return 0 on error, non-zero on success.
*/
int
module_get_filename_for_symbol(void *addr, char **filename);
/* Closes a module.
*
* Does nothing if dll is NULL.
*
* @param dll The module to close.
*/
void
module_close(void *dll);
/* Loads a module and extracts the given symbol.
*
* This function loads the module specified by filename, but does not resolve
* any of its symbol dependencies. Next is gets the symbol symbname and calls
* shouldload(). If shouldload() returns non-zero, the module is reloaded
* with full symbol resolution and stores the results in dll and symb.
*
* The job of shouldload() is to determine, based on the metadata in the
* symbol fetched, if the module should be fully loaded. The shouldload()
* callback MUST NOT attempt to call any functions in the module. This will
* crash on WIN32.
*
* If an error occurs, an error string will be allocated and returned. If
* allocation of this string fails, NULL will be returned. Since this is the
* same as the non-error case, you should additionally check if dll or symb
* is NULL.
*
* @param filename Path to the module
* @param symbname Symbol name to load from the file and pass to shouldload()
* @param shouldload Callback to determine whether to fullly load the module
* @param misc Opaque pointer to pass to shouldload()
* @param dll Where the module will be stored (can be NULL)
* @param symb Where the symbol will be stored (can be NULL)
* @return An error string.
*/
char *
module_load(const char *filename, const char *symbname,
int (*shouldload)(void *symb, void *misc, char **err), void *misc,
void **dll, void **symb);
libverto-0.3.1/src/verto-glib.c 0000664 0000000 0000000 00000021606 13435347213 0016360 0 ustar 00root root 0000000 0000000 /*
* Copyright 2011 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include
#include
#define VERTO_MODULE_TYPES
typedef struct {
GMainContext *context;
GMainLoop *loop;
} verto_mod_ctx;
typedef GSource verto_mod_ev;
#include
/* While glib has signal support in >=2.29, it does not support many
common signals (like USR*). Therefore, signal support is disabled
until they support them (should be soonish) */
#if GLIB_MAJOR_VERSION >= 999
#if GLIB_MINOR_VERSION >= 29
#ifdef G_OS_UNIX /* Not supported on Windows */
#include
#define HAS_SIGNAL VERTO_EV_TYPE_SIGNAL
#endif
#endif /* GLIB_MINOR_VERSION >= 29 */
#endif /* GLIB_MAJOR_VERSION >= 2 */
#ifndef HAS_SIGNAL
#define HAS_SIGNAL 0
#endif
#define VERTO_GLIB_SUPPORTED_TYPES (VERTO_EV_TYPE_IO \
| VERTO_EV_TYPE_TIMEOUT \
| VERTO_EV_TYPE_IDLE \
| HAS_SIGNAL \
| VERTO_EV_TYPE_CHILD)
typedef gboolean
(*GIOCallback)(gpointer data, GIOCondition condition);
typedef struct GIOSource {
GSource source;
GPollFD fd;
gboolean autoclose;
} GIOSource;
static gboolean
prepare(GSource *source, gint *timeout)
{
(void) source;
*timeout = -1;
return FALSE;
}
static gboolean
check(GSource *source)
{
GIOSource *src = (GIOSource*) source;
return src->fd.revents & src->fd.events;
}
static gboolean
dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
{
GIOSource *src = (GIOSource*) source;
return ((GIOCallback) callback)(user_data, src->fd.revents);
}
static void
finalize(GSource *source)
{
GIOSource *src = (GIOSource*) source;
if (src->autoclose)
close(src->fd.fd);
}
static GSourceFuncs funcs = { prepare, check, dispatch, finalize, NULL, NULL };
static void *
glib_convert_(GMainContext *mc, GMainLoop *ml)
{
verto_mod_ctx *l = NULL;
l = g_new0(verto_mod_ctx, 1);
if (l) {
if (mc) {
/* Steal references */
l->context = mc;
l->loop = ml ? ml : g_main_loop_new(l->context, FALSE);
if (g_main_context_default() == mc)
g_main_context_ref(mc);
} else {
l->context = g_main_context_ref(g_main_context_default());
l->loop = g_main_loop_new(l->context, FALSE);
}
} else {
g_main_loop_unref(ml);
g_main_context_unref(mc);
}
return l;
}
static verto_mod_ctx *
glib_ctx_new(void) {
return glib_convert_(g_main_context_new(), NULL);
}
static verto_mod_ctx *
glib_ctx_default(void) {
return glib_convert_(g_main_context_default(), NULL);
}
static void
glib_ctx_free(verto_mod_ctx *ctx)
{
g_main_loop_unref(ctx->loop);
g_main_context_unref(ctx->context);
g_free(ctx);
}
static void
glib_ctx_run(verto_mod_ctx *ctx)
{
g_main_loop_run(ctx->loop);
}
static void
glib_ctx_run_once(verto_mod_ctx *ctx)
{
g_main_context_iteration(ctx->context, TRUE);
}
static gboolean
break_callback(gpointer loop)
{
g_main_loop_quit(loop);
return FALSE;
}
static void
glib_ctx_break(verto_mod_ctx *ctx)
{
GSource *src = g_timeout_source_new(0);
g_assert(src);
g_source_set_callback(src, break_callback, ctx->loop, NULL);
g_source_set_priority(src, G_PRIORITY_HIGH);
g_assert(g_source_attach(src, ctx->context) != 0);
g_source_unref(src);
}
static gboolean
glib_callback(gpointer data)
{
gboolean persists = verto_get_flags(data) & VERTO_EV_FLAG_PERSIST;
verto_fire(data);
return persists;
}
static gboolean
glib_callback_io(gpointer data, GIOCondition condition)
{
verto_ev_flag state = VERTO_EV_FLAG_NONE;
if (condition & (G_IO_IN | G_IO_PRI))
state |= VERTO_EV_FLAG_IO_READ;
if (condition & G_IO_OUT)
state |= VERTO_EV_FLAG_IO_WRITE;
if (condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
state |= VERTO_EV_FLAG_IO_ERROR;
verto_set_fd_state(data, state);
return glib_callback(data);
}
static void
glib_callback_child(GPid pid, gint status, gpointer data)
{
(void) pid;
verto_set_proc_status(data, status);
verto_fire(data);
}
static void
glib_ctx_set_flags(verto_mod_ctx *ctx, const verto_ev *ev, verto_mod_ev *evpriv)
{
(void) ctx;
if (verto_get_flags(ev) & VERTO_EV_FLAG_PRIORITY_HIGH)
g_source_set_priority(evpriv, G_PRIORITY_HIGH);
else if (verto_get_flags(ev) & VERTO_EV_FLAG_PRIORITY_MEDIUM)
g_source_set_priority(evpriv, G_PRIORITY_DEFAULT_IDLE);
else if (verto_get_flags(ev) & VERTO_EV_FLAG_PRIORITY_LOW)
g_source_set_priority(evpriv, G_PRIORITY_LOW);
if (verto_get_type(ev) == VERTO_EV_TYPE_IO) {
((GIOSource*) evpriv)->fd.events = 0;
if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_READ)
((GIOSource*) evpriv)->fd.events |= G_IO_IN | G_IO_PRI | G_IO_ERR |
G_IO_HUP | G_IO_NVAL;
if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_WRITE)
((GIOSource*) evpriv)->fd.events |= G_IO_OUT | G_IO_ERR |
G_IO_HUP | G_IO_NVAL;
}
}
static verto_mod_ev *
glib_ctx_add(verto_mod_ctx *ctx, const verto_ev *ev, verto_ev_flag *flags)
{
verto_mod_ev *evpriv = NULL;
verto_ev_type type = verto_get_type(ev);
*flags |= verto_get_flags(ev) & VERTO_EV_FLAG_PERSIST;
*flags |= verto_get_flags(ev) & VERTO_EV_FLAG_IO_CLOSE_FD;
switch (type) {
case VERTO_EV_TYPE_IO:
evpriv = g_source_new(&funcs, sizeof(GIOSource));
if (evpriv) {
((GIOSource*) evpriv)->fd.fd = verto_get_fd(ev);
((GIOSource*) evpriv)->autoclose =
*flags & VERTO_EV_FLAG_IO_CLOSE_FD;
g_source_add_poll(evpriv, &((GIOSource*) evpriv)->fd);
}
break;
case VERTO_EV_TYPE_TIMEOUT:
evpriv = g_timeout_source_new(verto_get_interval(ev));
break;
case VERTO_EV_TYPE_IDLE:
evpriv = g_idle_source_new();
break;
case VERTO_EV_TYPE_CHILD:
evpriv = g_child_watch_source_new(verto_get_proc(ev));
break;
case VERTO_EV_TYPE_SIGNAL:
/* While glib has signal support in >=2.29, it does not support many
common signals (like USR*). Therefore, signal support is disabled
until they support them (should be soonish) */
#if GLIB_MAJOR_VERSION >= 999
#if GLIB_MINOR_VERSION >= 29
#ifdef G_OS_UNIX /* Not supported on Windows */
evpriv = g_unix_signal_source_new(verto_get_signal(ev));
break;
#endif
#endif /* GLIB_MINOR_VERSION >= 29 */
#endif /* GLIB_MAJOR_VERSION >= 2 */
default:
return NULL; /* Not supported */
}
if (!evpriv)
goto error;
if (type == VERTO_EV_TYPE_IO)
g_source_set_callback(evpriv, (GSourceFunc) glib_callback_io,
(void *) ev, NULL);
else if (type == VERTO_EV_TYPE_CHILD)
g_source_set_callback(evpriv, (GSourceFunc) glib_callback_child,
(void *) ev, NULL);
else
g_source_set_callback(evpriv, glib_callback, (void *) ev, NULL);
glib_ctx_set_flags(ctx, ev, evpriv);
g_source_set_can_recurse(evpriv, FALSE);
if (g_source_attach(evpriv, ctx->context) == 0)
goto error;
return evpriv;
error:
if (evpriv) {
g_source_destroy(evpriv);
g_source_unref(evpriv);
}
return NULL;
}
static void
glib_ctx_del(verto_mod_ctx *ctx, const verto_ev *ev, verto_mod_ev *evpriv)
{
(void) ctx;
if (!ev)
return;
g_source_destroy(evpriv);
g_source_unref(evpriv);
}
#define glib_ctx_reinitialize NULL
VERTO_MODULE(glib, g_main_context_default, VERTO_GLIB_SUPPORTED_TYPES);
verto_ctx *
verto_convert_glib(GMainContext *mc, GMainLoop *ml)
{
return verto_convert(glib, 0, glib_convert_(mc, ml));
}
libverto-0.3.1/src/verto-glib.h 0000664 0000000 0000000 00000003213 13435347213 0016357 0 ustar 00root root 0000000 0000000 /*
* Copyright 2011 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef VERTO_GLIB_H_
#define VERTO_GLIB_H_
#include
#include
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
verto_ctx *
verto_new_glib(void);
verto_ctx *
verto_default_glib(void);
/**
* mc == NULL, ml == NULL -- Use the default main loop
*
* If mc is specified, a reference is stolen unless mc is the default loop.
* A reference is always stolen for ml.
*/
verto_ctx *
verto_convert_glib(GMainContext *mc, GMainLoop *ml);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* VERTO_GLIB_H_ */
libverto-0.3.1/src/verto-libev.c 0000664 0000000 0000000 00000012662 13435347213 0016546 0 ustar 00root root 0000000 0000000 /*
* Copyright 2011 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include
#include
#include
#include
#define VERTO_MODULE_TYPES
typedef struct ev_loop verto_mod_ctx;
typedef ev_watcher verto_mod_ev;
#include
static verto_mod_ctx *
libev_ctx_new(void)
{
return ev_loop_new(EVFLAG_AUTO);
}
static verto_mod_ctx *
libev_ctx_default(void)
{
return ev_default_loop(EVFLAG_AUTO);
}
static void
libev_ctx_free(verto_mod_ctx *ctx)
{
if (ctx != EV_DEFAULT)
ev_loop_destroy(ctx);
}
static void
libev_ctx_run(verto_mod_ctx *ctx)
{
ev_run(ctx, 0);
}
static void
libev_ctx_run_once(verto_mod_ctx *ctx)
{
ev_run(ctx, EVRUN_ONCE);
}
static void
libev_ctx_break(verto_mod_ctx *ctx)
{
ev_break(ctx, EVBREAK_ONE);
}
static void
libev_ctx_reinitialize(verto_mod_ctx *ctx)
{
ev_loop_fork(ctx);
}
static void
libev_callback(EV_P_ ev_watcher *w, int revents)
{
verto_ev_flag state = VERTO_EV_FLAG_NONE;
#if EV_MULTIPLICITY
/* Match the check in ev.h, which doesn't mark this unused */
(void) EV_A;
#endif
if (verto_get_type(w->data)== VERTO_EV_TYPE_CHILD)
verto_set_proc_status(w->data, ((ev_child*) w)->rstatus);
if (revents & EV_READ)
state |= VERTO_EV_FLAG_IO_READ;
if (revents & EV_WRITE)
state |= VERTO_EV_FLAG_IO_WRITE;
if (revents & EV_ERROR)
state |= VERTO_EV_FLAG_IO_ERROR;
verto_set_fd_state(w->data, state);
verto_fire(w->data);
}
static void
libev_ctx_set_flags(verto_mod_ctx *ctx, const verto_ev *ev,
verto_mod_ev *evpriv)
{
if (verto_get_type(ev) == VERTO_EV_TYPE_IO) {
int events = EV_NONE;
if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_READ)
events |= EV_READ;
if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_WRITE)
events |= EV_WRITE;
ev_io_stop(ctx, (ev_io*) evpriv);
ev_io_set(((ev_io*) evpriv), verto_get_fd(ev), events);
ev_io_start(ctx, (ev_io*) evpriv);
}
}
#define setuptype(type, ...) \
w.type = malloc(sizeof(ev_ ## type)); \
if (w.type) { \
ev_ ## type ## _init(w.type, (EV_CB(type, (*))) __VA_ARGS__); \
ev_ ## type ## _start(ctx, w.type); \
} \
break
static verto_mod_ev *
libev_ctx_add(verto_mod_ctx *ctx, const verto_ev *ev, verto_ev_flag *flags)
{
union {
ev_watcher *watcher;
ev_io *io;
ev_timer *timer;
ev_idle *idle;
ev_signal *signal;
ev_child *child;
} w;
ev_tstamp interval;
w.watcher = NULL;
*flags |= VERTO_EV_FLAG_PERSIST;
switch (verto_get_type(ev)) {
case VERTO_EV_TYPE_IO:
setuptype(io, libev_callback, verto_get_fd(ev), EV_NONE);
case VERTO_EV_TYPE_TIMEOUT:
interval = ((ev_tstamp) verto_get_interval(ev)) / 1000.0;
setuptype(timer, libev_callback, interval, interval);
case VERTO_EV_TYPE_IDLE:
setuptype(idle, libev_callback);
case VERTO_EV_TYPE_SIGNAL:
setuptype(signal, libev_callback, verto_get_signal(ev));
case VERTO_EV_TYPE_CHILD:
*flags &= ~VERTO_EV_FLAG_PERSIST; /* Child events don't persist */
setuptype(child, libev_callback, verto_get_proc(ev), 0);
default:
break; /* Not supported */
}
if (w.watcher) {
w.watcher->data = (void*) ev;
libev_ctx_set_flags(ctx, ev, w.watcher);
}
return w.watcher;
}
static void
libev_ctx_del(verto_mod_ctx *ctx, const verto_ev *ev, verto_mod_ev *evpriv)
{
switch (verto_get_type(ev)) {
case VERTO_EV_TYPE_IO:
ev_io_stop(ctx, (ev_io*) evpriv);
break;
case VERTO_EV_TYPE_TIMEOUT:
ev_timer_stop(ctx, (ev_timer*) evpriv);
break;
case VERTO_EV_TYPE_IDLE:
ev_idle_stop(ctx, (ev_idle*) evpriv);
break;
case VERTO_EV_TYPE_SIGNAL:
ev_signal_stop(ctx, (ev_signal*) evpriv);
break;
case VERTO_EV_TYPE_CHILD:
ev_child_stop(ctx, (ev_child*) evpriv);
break;
default:
break;
}
free(evpriv);
}
VERTO_MODULE(libev, ev_loop_new,
VERTO_EV_TYPE_IO |
VERTO_EV_TYPE_TIMEOUT |
VERTO_EV_TYPE_IDLE |
VERTO_EV_TYPE_SIGNAL |
VERTO_EV_TYPE_CHILD);
verto_ctx *
verto_convert_libev(struct ev_loop* loop)
{
return verto_convert(libev, 0, loop);
}
libverto-0.3.1/src/verto-libev.h 0000664 0000000 0000000 00000002716 13435347213 0016552 0 ustar 00root root 0000000 0000000 /*
* Copyright 2011 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef VERTO_LIBEV_H_
#define VERTO_LIBEV_H_
#include
#include
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
verto_ctx *
verto_new_libev(void);
verto_ctx *
verto_default_libev(void);
verto_ctx *
verto_convert_libev(struct ev_loop* loop);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* VERTO_LIBEV_H_ */
libverto-0.3.1/src/verto-libevent.c 0000664 0000000 0000000 00000012036 13435347213 0017250 0 ustar 00root root 0000000 0000000 /*
* Copyright 2011 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include
#include
#include
#include
#define VERTO_MODULE_TYPES
typedef struct event_base verto_mod_ctx;
typedef struct event verto_mod_ev;
#include
#include
/* This is technically not exposed in any headers, but it is exported from
* the binary. Without it, we can't provide compatibility with libevent's
* sense of "global." */
extern struct event_base *event_global_current_base_;
static verto_mod_ctx *
libevent_ctx_new(void)
{
struct event_base *eb;
eb = event_base_new();
event_base_priority_init(eb, 3);
return eb;
}
static verto_mod_ctx *
libevent_ctx_default(void)
{
if (!event_global_current_base_)
event_global_current_base_ = event_init();
event_base_priority_init(event_global_current_base_, 3);
return event_global_current_base_;
}
static void
libevent_ctx_free(verto_mod_ctx *ctx)
{
event_base_free(ctx);
}
static void
libevent_ctx_run(verto_mod_ctx *ctx)
{
event_base_dispatch(ctx);
}
static void
libevent_ctx_run_once(verto_mod_ctx *ctx)
{
event_base_loop(ctx, EVLOOP_ONCE);
}
static void
libevent_ctx_break(verto_mod_ctx *ctx)
{
event_base_loopbreak(ctx);
}
static void
libevent_ctx_reinitialize(verto_mod_ctx *ctx)
{
event_reinit(ctx);
}
static void
libevent_callback(evutil_socket_t socket, short type, void *data)
{
verto_ev_flag state = VERTO_EV_FLAG_NONE;
(void) socket;
if (type & EV_READ)
state |= VERTO_EV_FLAG_IO_READ;
if (type & EV_WRITE)
state |= VERTO_EV_FLAG_IO_WRITE;
#ifdef EV_ERROR
if (type & EV_ERROR)
state |= VERTO_EV_FLAG_IO_ERROR;
#endif
verto_set_fd_state(data, state);
verto_fire(data);
}
static verto_mod_ev *
libevent_ctx_add(verto_mod_ctx *ctx, const verto_ev *ev, verto_ev_flag *flags)
{
struct event *priv = NULL;
struct timeval *timeout = NULL;
struct timeval tv;
int libeventflags = 0;
*flags |= verto_get_flags(ev) & VERTO_EV_FLAG_PERSIST;
if (verto_get_flags(ev) & VERTO_EV_FLAG_PERSIST)
libeventflags |= EV_PERSIST;
switch (verto_get_type(ev)) {
case VERTO_EV_TYPE_IO:
if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_READ)
libeventflags |= EV_READ;
if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_WRITE)
libeventflags |= EV_WRITE;
priv = event_new(ctx, verto_get_fd(ev), libeventflags,
libevent_callback, (void *) ev);
break;
case VERTO_EV_TYPE_TIMEOUT:
timeout = &tv;
tv.tv_sec = verto_get_interval(ev) / 1000;
tv.tv_usec = verto_get_interval(ev) % 1000 * 1000;
priv = event_new(ctx, -1, EV_TIMEOUT | libeventflags,
libevent_callback, (void *) ev);
break;
case VERTO_EV_TYPE_SIGNAL:
priv = event_new(ctx, verto_get_signal(ev),
EV_SIGNAL | libeventflags,
libevent_callback, (void *) ev);
break;
case VERTO_EV_TYPE_IDLE:
case VERTO_EV_TYPE_CHILD:
default:
return NULL; /* Not supported */
}
if (!priv)
return NULL;
if (verto_get_flags(ev) & VERTO_EV_FLAG_PRIORITY_HIGH)
event_priority_set(priv, 0);
else if (verto_get_flags(ev) & VERTO_EV_FLAG_PRIORITY_MEDIUM)
event_priority_set(priv, 1);
else if (verto_get_flags(ev) & VERTO_EV_FLAG_PRIORITY_LOW)
event_priority_set(priv, 2);
event_add(priv, timeout);
return priv;
}
static void
libevent_ctx_del(verto_mod_ctx *ctx, const verto_ev *ev, verto_mod_ev *evpriv)
{
(void) ctx;
(void) ev;
event_del(evpriv);
event_free(evpriv);
}
#define libevent_ctx_set_flags NULL
VERTO_MODULE(libevent, event_base_init,
VERTO_EV_TYPE_IO |
VERTO_EV_TYPE_TIMEOUT |
VERTO_EV_TYPE_SIGNAL);
verto_ctx *
verto_convert_libevent(struct event_base* base)
{
event_base_priority_init(base, 3);
return verto_convert(libevent, 0, base);
}
libverto-0.3.1/src/verto-libevent.h 0000664 0000000 0000000 00000002756 13435347213 0017265 0 ustar 00root root 0000000 0000000 /*
* Copyright 2011 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef VERTO_LIBEVENT_H_
#define VERTO_LIBEVENT_H_
#include
#include
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
verto_ctx *
verto_new_libevent(void);
verto_ctx *
verto_default_libevent(void);
verto_ctx *
verto_convert_libevent(struct event_base *ebase);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* VERTO_LIBEVENT_H_ */
libverto-0.3.1/src/verto-module.h 0000664 0000000 0000000 00000014760 13435347213 0016740 0 ustar 00root root 0000000 0000000 /*
* Copyright 2011 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/*** THE FOLLOWING ARE FOR IMPLEMENTATION MODULES ONLY ***/
#ifndef VERTO_MODULE_H_
#define VERTO_MODULE_H_
#include
#ifndef VERTO_MODULE_TYPES
#define VERTO_MODULE_TYPES
typedef void verto_mod_ctx;
typedef void verto_mod_ev;
#endif
#define VERTO_MODULE_VERSION 3
#define VERTO_MODULE_TABLE(name) verto_module_table_ ## name
#define VERTO_MODULE(name, symb, types) \
static verto_ctx_funcs name ## _funcs = { \
name ## _ctx_new, \
name ## _ctx_default, \
name ## _ctx_free, \
name ## _ctx_run, \
name ## _ctx_run_once, \
name ## _ctx_break, \
name ## _ctx_reinitialize, \
name ## _ctx_set_flags, \
name ## _ctx_add, \
name ## _ctx_del \
}; \
verto_module VERTO_MODULE_TABLE(name) = { \
VERTO_MODULE_VERSION, \
# name, \
# symb, \
types, \
&name ## _funcs, \
}; \
verto_ctx * \
verto_new_ ## name() \
{ \
return verto_convert(name, 0, NULL); \
} \
verto_ctx * \
verto_default_ ## name() \
{ \
return verto_convert(name, 1, NULL); \
}
typedef struct {
/* Required */ verto_mod_ctx *(*ctx_new)();
/* Optional */ verto_mod_ctx *(*ctx_default)();
/* Required */ void (*ctx_free)(verto_mod_ctx *ctx);
/* Optional */ void (*ctx_run)(verto_mod_ctx *ctx);
/* Required */ void (*ctx_run_once)(verto_mod_ctx *ctx);
/* Optional */ void (*ctx_break)(verto_mod_ctx *ctx);
/* Optional */ void (*ctx_reinitialize)(verto_mod_ctx *ctx);
/* Optional */ void (*ctx_set_flags)(verto_mod_ctx *ctx,
const verto_ev *ev,
verto_mod_ev *modev);
/* Required */ verto_mod_ev *(*ctx_add)(verto_mod_ctx *ctx,
const verto_ev *ev,
verto_ev_flag *flags);
/* Required */ void (*ctx_del)(verto_mod_ctx *ctx,
const verto_ev *ev,
verto_mod_ev *modev);
} verto_ctx_funcs;
typedef struct {
unsigned int vers;
const char *name;
const char *symb;
verto_ev_type types;
verto_ctx_funcs *funcs;
} verto_module;
/**
* Converts an existing implementation specific loop to a verto_ctx.
*
* This function also sets the internal default implementation so that future
* calls to verto_new(NULL) or verto_default(NULL) will use this specific
* implementation if it was not already set.
*
* @param name The name of the module (unquoted)
* @param deflt Whether the ctx is the default context or not
* @param ctx The context to store
* @return A new verto_ctx, or NULL on error. Call verto_free() when done.
*/
#define verto_convert(name, deflt, ctx) \
verto_convert_module(&VERTO_MODULE_TABLE(name), deflt, ctx)
/**
* Converts an existing implementation specific loop to a verto_ctx.
*
* If you are a module implementation, you probably want the macro above. This
* function is generally used directly only when an application is attempting
* to expose a home-grown event loop to verto.
*
* If deflt is non-zero and a default ctx was already defined for this module
* and ctx is not NULL, than ctx will be free'd and the previously defined
* default will be returned.
*
* If ctx is non-NULL, than the pre-existing verto_mod_ctx will be converted to
* to a verto_ctx; if deflt is non-zero than this verto_mod_ctx will also be
* marked as the default loop for this process. If ctx is NULL, than the
* appropriate constructor will be called: either module->ctx_new() or
* module->ctx_default() depending on the boolean value of deflt. If
* module->ctx_default is NULL and deflt is non-zero, than module->ctx_new()
* will be called and the resulting verto_mod_ctx will be utilized as the
* default.
*
* This function also sets the internal default implementation so that future
* calls to verto_new(NULL) or verto_default(NULL) will use this specific
* implementation if it was not already set.
*
* @param name The name of the module (unquoted)
* @param ctx The context private to store
* @return A new verto_ctx, or NULL on error. Call verto_free() when done.
*/
verto_ctx *
verto_convert_module(const verto_module *module, int deflt, verto_mod_ctx *ctx);
/**
* Calls the callback of the verto_ev and then frees it via verto_del().
*
* The verto_ev is not freed (verto_del() is not called) if it is a signal event.
*
* @see verto_add_read()
* @see verto_add_write()
* @see verto_add_timeout()
* @see verto_add_idle()
* @see verto_add_signal()
* @see verto_add_child()
* @see verto_del()
* @param ev The verto_ev
*/
void
verto_fire(verto_ev *ev);
/**
* Sets the status of the pid/handle which caused this event to fire.
*
* This function does nothing if the verto_ev is not a child type.
*
* @see verto_add_child()
* @param ev The verto_ev to set the status in.
* @param status The pid/handle status.
*/
void
verto_set_proc_status(verto_ev *ev, verto_proc_status status);
/**
* Sets the state of the fd which caused this event to fire.
*
* This function does nothing if the verto_ev is not a io type.
*
* Only the flags VERTO_EV_FLAG_IO_(READ|WRITE|ERROR) are supported. All other
* flags are unset.
*
* @see verto_add_io()
* @param ev The verto_ev to set the state in.
* @param state The fd state.
*/
void
verto_set_fd_state(verto_ev *ev, verto_ev_flag state);
#endif /* VERTO_MODULE_H_ */
libverto-0.3.1/src/verto-tevent.c 0000664 0000000 0000000 00000011251 13435347213 0016743 0 ustar 00root root 0000000 0000000 /*
* Copyright 2011 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include
#include
#include
#include
#define VERTO_MODULE_TYPES
typedef struct tevent_context verto_mod_ctx;
typedef void verto_mod_ev;
#include
#ifndef TEVENT_FD_ERROR
#define TEVENT_FD_ERROR 0
#endif /* TEVENT_FD_ERROR */
static verto_mod_ctx *
tevent_ctx_new(void)
{
return tevent_context_init(NULL);
}
static void
tevent_ctx_free(verto_mod_ctx *ctx)
{
talloc_free(ctx);
}
static void
tevent_ctx_run_once(verto_mod_ctx *ctx)
{
tevent_loop_once(ctx);
}
static void
tevent_ctx_reinitialize(verto_mod_ctx *ctx)
{
tevent_re_initialise(ctx);
}
static void
tevent_fd_cb(struct tevent_context *c, struct tevent_fd *e,
uint16_t fl, void *data)
{
verto_ev_flag state = VERTO_EV_FLAG_NONE;
if (fl & TEVENT_FD_READ)
state |= VERTO_EV_FLAG_IO_READ;
if (fl & TEVENT_FD_WRITE)
state |= VERTO_EV_FLAG_IO_WRITE;
if (fl & TEVENT_FD_ERROR)
state |= VERTO_EV_FLAG_IO_ERROR;
verto_set_fd_state(data, state);
verto_fire(data);
}
static void
tevent_timer_cb(struct tevent_context *c, struct tevent_timer *e,
struct timeval ct, void *data)
{
verto_fire(data);
}
static void
tevent_signal_cb(struct tevent_context *c, struct tevent_signal *e,
int signum, int count, void *siginfo, void *data)
{
verto_fire(data);
}
static void
tevent_ctx_set_flags(verto_mod_ctx *ctx, const verto_ev *ev,
verto_mod_ev *evpriv)
{
if (verto_get_type(ev) == VERTO_EV_TYPE_IO) {
uint16_t teventflags = TEVENT_FD_ERROR;
if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_READ)
teventflags |= TEVENT_FD_READ;
if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_WRITE)
teventflags |= TEVENT_FD_WRITE;
tevent_fd_set_flags(evpriv, teventflags);
}
}
static verto_mod_ev *
tevent_ctx_add(verto_mod_ctx *ctx, const verto_ev *ev, verto_ev_flag *flags)
{
time_t interval;
struct timeval tv;
struct tevent_fd *tfde;
*flags |= VERTO_EV_FLAG_PERSIST;
switch (verto_get_type(ev)) {
case VERTO_EV_TYPE_IO:
tfde = tevent_add_fd(ctx, ctx, verto_get_fd(ev), TEVENT_FD_ERROR,
tevent_fd_cb, (void *) ev);
if (tfde) {
tevent_ctx_set_flags(ctx, ev, tfde);
if (verto_get_flags(ev) & VERTO_EV_FLAG_IO_CLOSE_FD) {
*flags |= VERTO_EV_FLAG_IO_CLOSE_FD;
tevent_fd_set_auto_close(tfde);
}
}
return tfde;
case VERTO_EV_TYPE_TIMEOUT:
*flags &= ~VERTO_EV_FLAG_PERSIST; /* Timeout events don't persist */
interval = verto_get_interval(ev);
tv = tevent_timeval_current_ofs(interval / 1000, interval % 1000 * 1000);
return tevent_add_timer(ctx, ctx, tv,
tevent_timer_cb, (void *) ev);
case VERTO_EV_TYPE_SIGNAL:
return tevent_add_signal(ctx, ctx, verto_get_signal(ev),
0, tevent_signal_cb, (void *) ev);
case VERTO_EV_TYPE_IDLE:
case VERTO_EV_TYPE_CHILD:
default:
return NULL; /* Not supported */
}
}
static void
tevent_ctx_del(verto_mod_ctx *priv, const verto_ev *ev, verto_mod_ev *evpriv)
{
talloc_free(evpriv);
}
#define tevent_ctx_break NULL
#define tevent_ctx_run NULL
#define tevent_ctx_default NULL
VERTO_MODULE(tevent, tevent_context_init,
VERTO_EV_TYPE_IO |
VERTO_EV_TYPE_TIMEOUT |
VERTO_EV_TYPE_SIGNAL);
verto_ctx *
verto_convert_tevent(struct tevent_context *context)
{
return verto_convert(tevent, 0, context);
}
libverto-0.3.1/src/verto-tevent.h 0000664 0000000 0000000 00000002742 13435347213 0016755 0 ustar 00root root 0000000 0000000 /*
* Copyright 2011 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef VERTO_TEVENT_H_
#define VERTO_TEVENT_H_
#include
#include
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
verto_ctx *
verto_new_tevent(void);
verto_ctx *
verto_default_tevent(void);
verto_ctx *
verto_convert_tevent(struct tevent_context *context);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* VERTO_TEVENT_H_ */
libverto-0.3.1/src/verto.c 0000664 0000000 0000000 00000062417 13435347213 0015452 0 ustar 00root root 0000000 0000000 /*
* Copyright 2011 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef HAVE_PTHREAD
#include
#endif
#include
#include "module.h"
#define _str(s) # s
#define __str(s) _str(s)
#define MUTABLE(flags) (flags & _VERTO_EV_FLAG_MUTABLE_MASK)
/* Remove flags we can emulate */
#define make_actual(flags) ((flags) & ~(VERTO_EV_FLAG_PERSIST|VERTO_EV_FLAG_IO_CLOSE_FD))
struct verto_ctx {
size_t ref;
verto_mod_ctx *ctx;
const verto_module *module;
verto_ev *events;
int deflt;
int exit;
};
typedef struct {
verto_proc proc;
verto_proc_status status;
} verto_child;
typedef struct {
int fd;
verto_ev_flag state;
} verto_io;
struct verto_ev {
verto_ev *next;
verto_ctx *ctx;
verto_ev_type type;
verto_callback *callback;
verto_callback *onfree;
void *priv;
verto_mod_ev *ev;
verto_ev_flag flags;
verto_ev_flag actual;
size_t depth;
int deleted;
union {
verto_io io;
int signal;
time_t interval;
verto_child child;
} option;
};
typedef struct module_record module_record;
struct module_record {
module_record *next;
const verto_module *module;
void *dll;
char *filename;
verto_ctx *defctx;
};
#ifdef BUILTIN_MODULE
#define _MODTABLE(n) verto_module_table_ ## n
#define MODTABLE(n) _MODTABLE(n)
/*
* This symbol can be used when embedding verto.c in a library along with a
* built-in private module, to preload the module instead of dynamically
* linking it in later. Define to .
*/
extern verto_module MODTABLE(BUILTIN_MODULE);
static module_record builtin_record = {
NULL, &MODTABLE(BUILTIN_MODULE), NULL, "", NULL
};
static module_record *loaded_modules = &builtin_record;
#else
static module_record *loaded_modules;
#endif
static void *(*resize_cb)(void *mem, size_t size);
static int resize_cb_hierarchical;
#ifdef HAVE_PTHREAD
static pthread_mutex_t loaded_modules_mutex = PTHREAD_MUTEX_INITIALIZER;
#ifndef NDEBUG
#define mutex_lock(x) { \
int c = pthread_mutex_lock(x); \
if (c != 0) { \
fprintf(stderr, "pthread_mutex_lock returned %d (%s) in %s", \
c, strerror(c), __FUNCTION__); \
} \
assert(c == 0); \
}
#define mutex_unlock(x) { \
int c = pthread_mutex_unlock(x); \
if (c != 0) { \
fprintf(stderr, "pthread_mutex_unlock returned %d (%s) in %s", \
c, strerror(c), __FUNCTION__); \
} \
assert(c == 0); \
}
#define mutex_destroy(x) { \
int c = pthread_mutex_destroy(x); \
if (c != 0) { \
fprintf(stderr, "pthread_mutex_destroy returned %d (%s) in %s", \
c, strerror(c), __FUNCTION__); \
} \
assert(c == 0); \
}
#else /* NDEBUG */
#define mutex_lock pthread_mutex_lock
#define mutex_unlock pthread_mutex_unlock
#define mutex_destroy pthread_mutex_destroy
#endif /* NDEBUG */
#else /* HAVE_PTHREAD */
#define mutex_lock(x)
#define mutex_unlock(x)
#define mutex_destroy(x)
#endif /* HAVE_PTHREAD */
#define vfree(mem) vresize(mem, 0)
static void *
vresize(void *mem, size_t size)
{
if (!resize_cb)
resize_cb = &realloc;
if (size == 0 && resize_cb == &realloc) {
/* Avoid memleak as realloc(X, 0) can return a free-able pointer. */
free(mem);
return NULL;
}
return (*resize_cb)(mem, size);
}
#ifndef BUILTIN_MODULE
static char *
string_aconcat(const char *first, const char *second, const char *third) {
char *ret;
size_t len;
len = strlen(first) + strlen(second);
if (third)
len += strlen(third);
ret = malloc(len + 1);
if (!ret)
return NULL;
strncpy(ret, first, strlen(first));
strncpy(ret + strlen(first), second, strlen(second));
if (third)
strncpy(ret + strlen(first) + strlen(second), third, strlen(third));
ret[len] = '\0';
return ret;
}
static char *
int_get_table_name_from_filename(const char *filename)
{
char *bn = NULL, *tmp = NULL;
if (!filename)
return NULL;
tmp = strdup(filename);
if (!tmp)
return NULL;
bn = basename(tmp);
if (bn)
bn = strdup(bn);
free(tmp);
if (!bn)
return NULL;
tmp = strchr(bn, '-');
if (tmp) {
if (strchr(tmp+1, '.')) {
*strchr(tmp+1, '.') = '\0';
tmp = string_aconcat(__str(VERTO_MODULE_TABLE()), tmp + 1, NULL);
} else
tmp = NULL;
}
free(bn);
return tmp;
}
typedef struct {
int reqsym;
verto_ev_type reqtypes;
} shouldload_data;
static int
shouldload(void *symb, void *misc, char **err)
{
verto_module *table = (verto_module*) symb;
shouldload_data *data = (shouldload_data*) misc;
/* Make sure we have the proper version */
if (table->vers != VERTO_MODULE_VERSION) {
if (err)
*err = strdup("Invalid module version!");
return 0;
}
/* Check to make sure that we have our required symbol if reqsym == true */
if (table->symb && data->reqsym
&& !module_symbol_is_present(NULL, table->symb)) {
if (err)
*err = string_aconcat("Symbol not found: ", table->symb, "!");
return 0;
}
/* Check to make sure that this module supports our required features */
if (data->reqtypes != VERTO_EV_TYPE_NONE
&& (table->types & data->reqtypes) != data->reqtypes) {
if (err)
*err = strdup("Module does not support required features!");
return 0;
}
return 1;
}
static int
do_load_file(const char *filename, int reqsym, verto_ev_type reqtypes,
module_record **record)
{
char *tblname = NULL, *error = NULL;
module_record *tmp;
shouldload_data data = { reqsym, reqtypes };
/* Check the loaded modules to see if we already loaded one */
mutex_lock(&loaded_modules_mutex);
for (*record = loaded_modules ; *record ; *record = (*record)->next) {
if (!strcmp((*record)->filename, filename)) {
mutex_unlock(&loaded_modules_mutex);
return 1;
}
}
mutex_unlock(&loaded_modules_mutex);
/* Create our module record */
tmp = *record = vresize(NULL, sizeof(module_record));
if (!tmp)
return 0;
memset(tmp, 0, sizeof(module_record));
tmp->filename = strdup(filename);
if (!tmp->filename) {
vfree(tmp);
return 0;
}
/* Get the name of the module struct in the library */
tblname = int_get_table_name_from_filename(filename);
if (!tblname) {
free(tblname);
free(tmp->filename);
vfree(tmp);
return 0;
}
/* Load the module */
error = module_load(filename, tblname, shouldload, &data, &tmp->dll,
(void **) &tmp->module);
if (error || !tmp->dll || !tmp->module) {
/*if (error)
fprintf(stderr, "%s\n", error);*/
free(error);
module_close(tmp->dll);
free(tblname);
free(tmp->filename);
vfree(tmp);
return 0;
}
/* Append the new module to the end of the loaded modules */
mutex_lock(&loaded_modules_mutex);
for (tmp = loaded_modules ; tmp && tmp->next; tmp = tmp->next)
continue;
if (tmp)
tmp->next = *record;
else
loaded_modules = *record;
mutex_unlock(&loaded_modules_mutex);
free(tblname);
return 1;
}
static int
do_load_dir(const char *dirname, const char *prefix, const char *suffix,
int reqsym, verto_ev_type reqtypes, module_record **record)
{
DIR *dir;
struct dirent *ent = NULL;
*record = NULL;
dir = opendir(dirname);
if (!dir)
return 0;
while ((ent = readdir(dir))) {
char *tmp = NULL;
int success;
size_t flen, slen;
flen = strlen(ent->d_name);
slen = strlen(suffix);
if (!strcmp(".", ent->d_name) || !strcmp("..", ent->d_name))
continue;
if (strstr(ent->d_name, prefix) != ent->d_name)
continue;
if (flen < slen || strcmp(ent->d_name + flen - slen, suffix))
continue;
tmp = string_aconcat(dirname, "/", ent->d_name);
if (!tmp)
continue;
success = do_load_file(tmp, reqsym, reqtypes, record);
free(tmp);
if (success)
break;
*record = NULL;
}
closedir(dir);
return *record != NULL;
}
#endif
static int
load_module(const char *impl, verto_ev_type reqtypes, module_record **record)
{
int success = 0;
#ifndef BUILTIN_MODULE
char *prefix = NULL;
char *suffix = NULL;
char *tmp = NULL;
#endif
/* Check the cache */
mutex_lock(&loaded_modules_mutex);
if (impl) {
for (*record = loaded_modules ; *record ; *record = (*record)->next) {
if ((strchr(impl, '/') && !strcmp(impl, (*record)->filename))
|| !strcmp(impl, (*record)->module->name)) {
mutex_unlock(&loaded_modules_mutex);
return 1;
}
}
} else if (loaded_modules) {
for (*record = loaded_modules ; *record ; *record = (*record)->next) {
if (reqtypes == VERTO_EV_TYPE_NONE
|| ((*record)->module->types & reqtypes) == reqtypes) {
mutex_unlock(&loaded_modules_mutex);
return 1;
}
}
}
mutex_unlock(&loaded_modules_mutex);
#ifndef BUILTIN_MODULE
if (!module_get_filename_for_symbol(verto_convert_module, &prefix))
return 0;
/* Example output:
* prefix == /usr/lib/libverto-
* impl == glib
* suffix == .so.0
* Put them all together: /usr/lib/libverto-glib.so.0 */
tmp = strdup(prefix);
if (!tmp) {
free(prefix);
return 0;
}
suffix = basename(tmp);
suffix = strchr(suffix, '.');
if (!suffix || strlen(suffix) < 1 || !(suffix = strdup(suffix))) {
free(prefix);
free(tmp);
return 0;
}
strcpy(prefix + strlen(prefix) - strlen(suffix), "-");
free(tmp);
if (impl) {
/* Try to do a load by the path */
if (!success && strchr(impl, '/'))
success = do_load_file(impl, 0, reqtypes, record);
if (!success) {
/* Try to do a load by the name */
tmp = string_aconcat(prefix, impl, suffix);
if (tmp) {
success = do_load_file(tmp, 0, reqtypes, record);
free(tmp);
}
}
} else {
/* NULL was passed, so we will use the dirname of
* the prefix to try and find any possible plugins */
tmp = strdup(prefix);
if (tmp) {
char *dname = strdup(dirname(tmp));
free(tmp);
tmp = strdup(basename(prefix));
free(prefix);
prefix = tmp;
if (dname && prefix) {
/* Attempt to find a module we are already linked to */
success = do_load_dir(dname, prefix, suffix, 1, reqtypes,
record);
if (!success) {
#ifdef DEFAULT_MODULE
/* Attempt to find the default module */
success = load_module(DEFAULT_MODULE, reqtypes, record);
if (!success)
#endif /* DEFAULT_MODULE */
/* Attempt to load any plugin (we're desperate) */
success = do_load_dir(dname, prefix, suffix, 0,
reqtypes, record);
}
}
free(dname);
}
}
free(suffix);
free(prefix);
#endif /* BUILTIN_MODULE */
return success;
}
static verto_ev *
make_ev(verto_ctx *ctx, verto_callback *callback,
verto_ev_type type, verto_ev_flag flags)
{
verto_ev *ev = NULL;
if (!ctx || !callback)
return NULL;
ev = vresize(NULL, sizeof(verto_ev));
if (ev) {
memset(ev, 0, sizeof(verto_ev));
ev->ctx = ctx;
ev->type = type;
ev->callback = callback;
ev->flags = flags;
}
return ev;
}
static void
push_ev(verto_ctx *ctx, verto_ev *ev)
{
verto_ev *tmp;
if (!ctx || !ev)
return;
tmp = ctx->events;
ctx->events = ev;
ctx->events->next = tmp;
}
static void
remove_ev(verto_ev **origin, verto_ev *item)
{
if (!origin || !*origin || !item)
return;
if (*origin == item)
*origin = (*origin)->next;
else
remove_ev(&((*origin)->next), item);
}
static void
signal_ignore(verto_ctx *ctx, verto_ev *ev)
{
(void) ctx;
(void) ev;
}
verto_ctx *
verto_new(const char *impl, verto_ev_type reqtypes)
{
module_record *mr = NULL;
if (!load_module(impl, reqtypes, &mr))
return NULL;
return verto_convert_module(mr->module, 0, NULL);
}
verto_ctx *
verto_default(const char *impl, verto_ev_type reqtypes)
{
module_record *mr = NULL;
if (!load_module(impl, reqtypes, &mr))
return NULL;
return verto_convert_module(mr->module, 1, NULL);
}
int
verto_set_default(const char *impl, verto_ev_type reqtypes)
{
module_record *mr;
mutex_lock(&loaded_modules_mutex);
if (loaded_modules || !impl) {
mutex_unlock(&loaded_modules_mutex);
return 0;
}
mutex_unlock(&loaded_modules_mutex);
return load_module(impl, reqtypes, &mr);
}
int
verto_set_allocator(void *(*resize)(void *mem, size_t size),
int hierarchical)
{
if (resize_cb || !resize)
return 0;
resize_cb = resize;
resize_cb_hierarchical = hierarchical;
return 1;
}
void
verto_free(verto_ctx *ctx)
{
if (!ctx)
return;
ctx->ref = ctx->ref > 0 ? ctx->ref - 1 : 0;
if (ctx->ref > 0)
return;
/* Cancel all pending events */
while (ctx->events)
verto_del(ctx->events);
/* Free the private */
if (!ctx->deflt || !ctx->module->funcs->ctx_default)
ctx->module->funcs->ctx_free(ctx->ctx);
vfree(ctx);
}
void
verto_cleanup(void)
{
module_record *record;
mutex_lock(&loaded_modules_mutex);
for (record = loaded_modules; record; record = record->next) {
module_close(record->dll);
free(record->filename);
}
vfree(loaded_modules);
loaded_modules = NULL;
mutex_unlock(&loaded_modules_mutex);
mutex_destroy(&loaded_modules_mutex);
}
void
verto_run(verto_ctx *ctx)
{
if (!ctx)
return;
if (ctx->module->funcs->ctx_break && ctx->module->funcs->ctx_run)
ctx->module->funcs->ctx_run(ctx->ctx);
else {
while (!ctx->exit)
ctx->module->funcs->ctx_run_once(ctx->ctx);
ctx->exit = 0;
}
}
void
verto_run_once(verto_ctx *ctx)
{
if (!ctx)
return;
ctx->module->funcs->ctx_run_once(ctx->ctx);
}
void
verto_break(verto_ctx *ctx)
{
if (!ctx)
return;
if (ctx->module->funcs->ctx_break && ctx->module->funcs->ctx_run)
ctx->module->funcs->ctx_break(ctx->ctx);
else
ctx->exit = 1;
}
int
verto_reinitialize(verto_ctx *ctx)
{
verto_ev *tmp, *next;
int error = 1;
if (!ctx)
return 0;
/* Delete all events, but keep around the forkable ev structs */
for (tmp = ctx->events; tmp; tmp = next) {
next = tmp->next;
if (tmp->flags & VERTO_EV_FLAG_REINITIABLE)
ctx->module->funcs->ctx_del(ctx->ctx, tmp, tmp->ev);
else
verto_del(tmp);
}
/* Reinit the loop */
if (ctx->module->funcs->ctx_reinitialize)
ctx->module->funcs->ctx_reinitialize(ctx->ctx);
/* Recreate events that were marked forkable */
for (tmp = ctx->events; tmp; tmp = tmp->next) {
tmp->actual = make_actual(tmp->flags);
tmp->ev = ctx->module->funcs->ctx_add(ctx->ctx, tmp, &tmp->actual);
if (!tmp->ev)
error = 0;
}
return error;
}
#define doadd(ev, set, type) \
ev = make_ev(ctx, callback, type, flags); \
if (ev) { \
set; \
ev->actual = make_actual(ev->flags); \
ev->ev = ctx->module->funcs->ctx_add(ctx->ctx, ev, &ev->actual); \
if (!ev->ev) { \
vfree(ev); \
return NULL; \
} \
push_ev(ctx, ev); \
}
verto_ev *
verto_add_io(verto_ctx *ctx, verto_ev_flag flags,
verto_callback *callback, int fd)
{
verto_ev *ev;
if (fd < 0 || !(flags & (VERTO_EV_FLAG_IO_READ | VERTO_EV_FLAG_IO_WRITE)))
return NULL;
doadd(ev, ev->option.io.fd = fd, VERTO_EV_TYPE_IO);
return ev;
}
verto_ev *
verto_add_timeout(verto_ctx *ctx, verto_ev_flag flags,
verto_callback *callback, time_t interval)
{
verto_ev *ev;
doadd(ev, ev->option.interval = interval, VERTO_EV_TYPE_TIMEOUT);
return ev;
}
verto_ev *
verto_add_idle(verto_ctx *ctx, verto_ev_flag flags,
verto_callback *callback)
{
verto_ev *ev;
doadd(ev,, VERTO_EV_TYPE_IDLE);
return ev;
}
verto_ev *
verto_add_signal(verto_ctx *ctx, verto_ev_flag flags,
verto_callback *callback, int signal)
{
verto_ev *ev;
if (signal < 0)
return NULL;
#ifndef WIN32
if (signal == SIGCHLD)
return NULL;
#endif
if (callback == VERTO_SIG_IGN) {
callback = signal_ignore;
if (!(flags & VERTO_EV_FLAG_PERSIST))
return NULL;
}
doadd(ev, ev->option.signal = signal, VERTO_EV_TYPE_SIGNAL);
return ev;
}
verto_ev *
verto_add_child(verto_ctx *ctx, verto_ev_flag flags,
verto_callback *callback, verto_proc proc)
{
verto_ev *ev;
if (flags & VERTO_EV_FLAG_PERSIST) /* persist makes no sense */
return NULL;
#ifdef WIN32
if (proc == NULL)
#else
if (proc < 1)
#endif
return NULL;
doadd(ev, ev->option.child.proc = proc, VERTO_EV_TYPE_CHILD);
return ev;
}
void
verto_set_private(verto_ev *ev, void *priv, verto_callback *free)
{
if (!ev)
return;
if (ev->onfree && free)
ev->onfree(ev->ctx, ev);
ev->priv = priv;
ev->onfree = free;
}
void *
verto_get_private(const verto_ev *ev)
{
return ev->priv;
}
verto_ev_type
verto_get_type(const verto_ev *ev)
{
return ev->type;
}
verto_ev_flag
verto_get_flags(const verto_ev *ev)
{
return ev->flags;
}
void
verto_set_flags(verto_ev *ev, verto_ev_flag flags)
{
if (!ev)
return;
/* No modification is needed, so do nothing. */
if (MUTABLE(ev->flags) == MUTABLE(flags))
return;
ev->flags &= ~_VERTO_EV_FLAG_MUTABLE_MASK;
ev->flags |= MUTABLE(flags);
/* If setting flags isn't supported, just rebuild the event */
if (!ev->ctx->module->funcs->ctx_set_flags) {
ev->ctx->module->funcs->ctx_del(ev->ctx->ctx, ev, ev->ev);
ev->actual = make_actual(ev->flags);
ev->ev = ev->ctx->module->funcs->ctx_add(ev->ctx->ctx, ev, &ev->actual);
assert(ev->ev); /* Here is the main reason why modules should */
return; /* implement set_flags(): we cannot fail gracefully. */
}
ev->actual &= ~_VERTO_EV_FLAG_MUTABLE_MASK;
ev->actual |= MUTABLE(flags);
ev->ctx->module->funcs->ctx_set_flags(ev->ctx->ctx, ev, ev->ev);
}
int
verto_get_fd(const verto_ev *ev)
{
if (ev && (ev->type == VERTO_EV_TYPE_IO))
return ev->option.io.fd;
return -1;
}
verto_ev_flag
verto_get_fd_state(const verto_ev *ev)
{
return ev->option.io.state;
}
time_t
verto_get_interval(const verto_ev *ev)
{
if (ev && (ev->type == VERTO_EV_TYPE_TIMEOUT))
return ev->option.interval;
return 0;
}
int
verto_get_signal(const verto_ev *ev)
{
if (ev && (ev->type == VERTO_EV_TYPE_SIGNAL))
return ev->option.signal;
return -1;
}
verto_proc
verto_get_proc(const verto_ev *ev) {
if (ev && ev->type == VERTO_EV_TYPE_CHILD)
return ev->option.child.proc;
return (verto_proc) 0;
}
verto_proc_status
verto_get_proc_status(const verto_ev *ev)
{
return ev->option.child.status;
}
verto_ctx *
verto_get_ctx(const verto_ev *ev)
{
return ev->ctx;
}
void
verto_del(verto_ev *ev)
{
if (!ev)
return;
/* If the event is freed in the callback, we just set a flag so that
* verto_fire() can actually do the delete when the callback completes.
*
* If we don't do this, than verto_fire() will access freed memory. */
if (ev->depth > 0) {
ev->deleted = 1;
return;
}
if (ev->onfree)
ev->onfree(ev->ctx, ev);
ev->ctx->module->funcs->ctx_del(ev->ctx->ctx, ev, ev->ev);
remove_ev(&(ev->ctx->events), ev);
if ((ev->type == VERTO_EV_TYPE_IO) &&
(ev->flags & VERTO_EV_FLAG_IO_CLOSE_FD) &&
!(ev->actual & VERTO_EV_FLAG_IO_CLOSE_FD))
close(ev->option.io.fd);
vfree(ev);
}
verto_ev_type
verto_get_supported_types(verto_ctx *ctx)
{
return ctx->module->types;
}
/*** THE FOLLOWING ARE FOR IMPLEMENTATION MODULES ONLY ***/
verto_ctx *
verto_convert_module(const verto_module *module, int deflt, verto_mod_ctx *mctx)
{
verto_ctx *ctx = NULL;
module_record *mr;
if (!module)
return NULL;
if (deflt) {
mutex_lock(&loaded_modules_mutex);
for (mr = loaded_modules ; mr ; mr = mr->next) {
verto_ctx *tmp;
if (mr->module == module && mr->defctx) {
if (mctx)
module->funcs->ctx_free(mctx);
tmp = mr->defctx;
tmp->ref++;
mutex_unlock(&loaded_modules_mutex);
return tmp;
}
}
mutex_unlock(&loaded_modules_mutex);
}
if (!mctx) {
mctx = deflt
? (module->funcs->ctx_default
? module->funcs->ctx_default()
: module->funcs->ctx_new())
: module->funcs->ctx_new();
if (!mctx)
goto error;
}
ctx = vresize(NULL, sizeof(verto_ctx));
if (!ctx)
goto error;
memset(ctx, 0, sizeof(verto_ctx));
ctx->ref = 1;
ctx->ctx = mctx;
ctx->module = module;
ctx->deflt = deflt;
if (deflt) {
module_record **tmp;
mutex_lock(&loaded_modules_mutex);
tmp = &loaded_modules;
for (mr = loaded_modules ; mr ; mr = mr->next) {
if (mr->module == module) {
assert(mr->defctx == NULL);
mr->defctx = ctx;
mutex_unlock(&loaded_modules_mutex);
return ctx;
}
if (!mr->next) {
tmp = &mr->next;
break;
}
}
mutex_unlock(&loaded_modules_mutex);
*tmp = vresize(NULL, sizeof(module_record));
if (!*tmp) {
vfree(ctx);
goto error;
}
memset(*tmp, 0, sizeof(module_record));
(*tmp)->defctx = ctx;
(*tmp)->module = module;
}
return ctx;
error:
if (mctx)
module->funcs->ctx_free(mctx);
return NULL;
}
void
verto_fire(verto_ev *ev)
{
void *priv;
ev->depth++;
ev->callback(ev->ctx, ev);
ev->depth--;
if (ev->depth == 0) {
if (!(ev->flags & VERTO_EV_FLAG_PERSIST) || ev->deleted)
verto_del(ev);
else {
if (!(ev->actual & VERTO_EV_FLAG_PERSIST)) {
ev->actual = make_actual(ev->flags);
priv = ev->ctx->module->funcs->ctx_add(ev->ctx->ctx, ev, &ev->actual);
assert(priv); /* TODO: create an error callback */
ev->ctx->module->funcs->ctx_del(ev->ctx->ctx, ev, ev->ev);
ev->ev = priv;
}
if (ev->type == VERTO_EV_TYPE_IO)
ev->option.io.state = VERTO_EV_FLAG_NONE;
if (ev->type == VERTO_EV_TYPE_CHILD)
ev->option.child.status = 0;
}
}
}
void
verto_set_proc_status(verto_ev *ev, verto_proc_status status)
{
if (ev && ev->type == VERTO_EV_TYPE_CHILD)
ev->option.child.status = status;
}
void
verto_set_fd_state(verto_ev *ev, verto_ev_flag state)
{
/* Filter out only the io flags */
state = state & (VERTO_EV_FLAG_IO_READ |
VERTO_EV_FLAG_IO_WRITE |
VERTO_EV_FLAG_IO_ERROR);
/* Don't report read/write if the socket is closed */
if (state & VERTO_EV_FLAG_IO_ERROR)
state = VERTO_EV_FLAG_IO_ERROR;
if (ev && ev->type == VERTO_EV_TYPE_IO)
ev->option.io.state = state;
}
libverto-0.3.1/src/verto.h 0000664 0000000 0000000 00000045755 13435347213 0015465 0 ustar 00root root 0000000 0000000 /*
* Copyright 2011 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef VERTO_H_
#define VERTO_H_
#include /* For time_t */
#include /* For pid_t */
#ifdef WIN32
#include
typedef HANDLE verto_proc;
typedef DWORD verto_proc_status;
#else
#include
typedef pid_t verto_proc;
typedef int verto_proc_status;
#endif
#define VERTO_SIG_IGN ((verto_callback *) 1)
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
typedef struct verto_ctx verto_ctx;
typedef struct verto_ev verto_ev;
typedef enum {
VERTO_EV_TYPE_NONE = 0,
VERTO_EV_TYPE_IO = 1,
VERTO_EV_TYPE_TIMEOUT = 1 << 1,
VERTO_EV_TYPE_IDLE = 1 << 2,
VERTO_EV_TYPE_SIGNAL = 1 << 3,
VERTO_EV_TYPE_CHILD = 1 << 4
} verto_ev_type;
typedef enum {
VERTO_EV_FLAG_NONE = 0,
VERTO_EV_FLAG_PERSIST = 1,
VERTO_EV_FLAG_PRIORITY_LOW = 1 << 1,
VERTO_EV_FLAG_PRIORITY_MEDIUM = 1 << 2,
VERTO_EV_FLAG_PRIORITY_HIGH = 1 << 3,
VERTO_EV_FLAG_IO_READ = 1 << 4,
VERTO_EV_FLAG_IO_WRITE = 1 << 5,
VERTO_EV_FLAG_IO_ERROR = 1 << 7,
VERTO_EV_FLAG_IO_CLOSE_FD = 1 << 8,
VERTO_EV_FLAG_REINITIABLE = 1 << 6,
_VERTO_EV_FLAG_MUTABLE_MASK = VERTO_EV_FLAG_PRIORITY_LOW
| VERTO_EV_FLAG_PRIORITY_MEDIUM
| VERTO_EV_FLAG_PRIORITY_HIGH
| VERTO_EV_FLAG_IO_READ
| VERTO_EV_FLAG_IO_WRITE,
_VERTO_EV_FLAG_MAX = VERTO_EV_FLAG_IO_CLOSE_FD
} verto_ev_flag;
typedef void (verto_callback)(verto_ctx *ctx, verto_ev *ev);
/**
* Creates a new event context using an optionally specified implementation
* and/or optionally specified required features.
*
* If you are an application that has already decided on using a particular
* event loop implementation, you should not call this function, but instead
* import the verto-NAME.h header and link against the verto-NAME.so, where
* NAME is the implementation you wish to use.
*
* If you are a library, you should generally avoid creating event contexts
* on your own but allow applications to pass in a verto_ctx you can use.
*
* There are two cases where you should use this function. The first is
* where you have a need to choose an implementation at run time, usually
* for testing purposes. The second and more common is when you simply
* wish to remain implementation agnostic. In this later case, you should
* always call like this: verto_new(NULL, ...). This lets verto choose the best
* implementation to use.
*
* If impl is not NULL, a new context is returned which is backed by the
* implementation specified. If the implementation specified is not
* available or if the required types (reqtypes) are not provided by the
* named implementation, NULL is returned. The parameter 'impl' can specify:
* * The full path to an implementation library
* * The name of the implementation library (i.e. - "glib" or "libev")
*
* If impl is NULL, verto will attempt to automatically determine the
* best implementation to use.
*
* First, verto will attempt to use an existing, previously loaded
* implementation. This is handled automatically by internal caching of either
* the first implementation loaded or the one specified by verto_set_default().
*
* Second, verto will attempt to discern if you are already linked to any
* of the supported implementations (to avoid wasting memory by loading
* extra unnecessary libraries). If you are linked to one supported
* implementation, that implementation will be chosen. If you are linked
* to more than one supported implementation one of the ones linked to
* will be chosen, but the order of the particular choice is undefined.
*
* Third, verto will attempt to load the compile-time default, if defined at
* build time and available at runtime.
*
* Last, verto will attempt to load any implementation installed. The specific
* order of this step is undefined.
*
* In all cases above, if the implementation does not support all the specified
* features (reqtypes), it will be skipped and processing will continue from
* where it left off. This means that if verto_new() returns non-NULL it is
* guaranteed to support the features you specified.
*
* @see verto_set_default()
* @param impl The implementation to use, or NULL.
* @param reqtypes A bitwise or'd list of required event type features.
* @return A new verto_ctx, or NULL on error. Call verto_free() when done.
*/
verto_ctx *
verto_new(const char *impl, verto_ev_type reqtypes);
/**
* Gets the default event context using an optionally specified implementation.
*
* This function is essentially a singleton version of verto_new(). However,
* since this function must return the same loop as the *_default() call of
* the underlying implementation (if such a function exists), it is NOT a
* global singleton, but a per-implementation singleton. For this reason, you
* must call verto_free() when you are done with this loop. Even after calling
* verto_free() on the default verto_ctx, you can safely call verto_default()
* again and receive a new reference to the same (internally default) loop.
*
* In all other respects, verto_default() acts exactly like verto_new().
*
* @see verto_new()
* @see verto_free()
* @param impl The implementation to use, or NULL.
* @param reqtypes A bitwise or'd list of required event type features.
* @return The default verto_ctx, or NULL on error. Call verto_free() when done.
*/
verto_ctx *
verto_default(const char *impl, verto_ev_type reqtypes);
/**
* Sets the default implementation to use by its name.
*
* This function returns 1 on success and 0 on failure. It can fail for the
* following reasons:
* 1. The default implementation was already set via verto_set_default().
* 2. The implementation specified could not be found.
* 3. The implementation specified didn't support the features specified.
* 4. The impl argument was NULL.
* 5. verto_new() was already called.
* 6. verto_default() was already called.
* 7. verto_new_NAME() was already called.
* 8. verto_default_NAME() was already called.
* 9. verto_convert_NAME() was already called.
*
* @see verto_new()
* @see verto_default()
* @param impl The implementation to use.
* @param reqtypes A bitwise or'd list of required event type features.
* @return The default verto_ctx, or NULL on error. Call verto_free() when done.
*/
int
verto_set_default(const char *impl, verto_ev_type reqtypes);
/**
* Sets the allocator to use for verto_ctx and verto_ev objects.
*
* If you plan to set the allocator, you MUST call this function before any
* other verto_*() calls.
*
* @see verto_new()
* @see verto_default()
* @see verto_add_io()
* @see verto_add_timeout()
* @see verto_add_idle()
* @see verto_add_signal()
* @see verto_add_child()
* @param resize The allocator to use (behaves like realloc();
* resize(ptr, 0) must free memory at ptr.)
* @param hierarchical Zero if the allocator is not hierarchical
*/
int
verto_set_allocator(void *(*resize)(void *mem, size_t size), int hierarchical);
/**
* Frees a verto_ctx.
*
* When called on a default verto_ctx, the reference will be freed but the
* internal default loop will still be available via another call to
* verto_default().
*
* @see verto_new()
* @see verto_default()
* @param ctx The verto_ctx to free.
*/
void
verto_free(verto_ctx *ctx);
/**
* Frees global state.
*
* Remove and free all allocated global state. Call only when no further
* contexts exist and all threads have exited.
*
* @see verto_new()
* @see verto_free()
* @see verto_default()
*/
void
verto_cleanup(void);
/**
* Run the verto_ctx forever, or at least until verto_break() is called.
*
* @see verto_break()
* @param ctx The verto_ctx to run.
*/
void
verto_run(verto_ctx *ctx);
/**
* Run the verto_ctx once. May block.
*
* @param ctx The verto_ctx to run once.
*/
void
verto_run_once(verto_ctx *ctx);
/**
* Exits the currently running verto_ctx.
*
* @see verto_run()
* @param ctx The verto_ctx to exit.
*/
void
verto_break(verto_ctx *ctx);
/**
* Re-initializes the verto_ctx.
*
* This function deletes all events, except those which have set the
* VERTO_EV_FLAG_REINITIABLE flag. If you fork(), you MUST call this in the
* child process after the fork!
*
* If this function fails it indicates that at least one
* VERTO_EV_FLAG_REINITIABLE event was not rearmed or that ctx was NULL.
*
* @see verto_new()
* @see verto_default()
* @param ctx The verto_ctx to re-initialize.
* @return Non-zero on success, 0 on error.
*/
int
verto_reinitialize(verto_ctx *ctx);
/**
* Adds a callback executed when a file descriptor is ready to be read/written.
*
* All verto_ev events are automatically freed when their parent verto_ctx is
* freed. You do not need to free them manually. If VERTO_EV_FLAG_PERSIST is
* provided, the event will repeat until verto_del() is called. If
* VERTO_EV_FLAG_PERSIST is not provided, the event will be freed automatically
* after its execution. In either case, you may call verto_del() at any time
* to prevent the event from executing.
* If VERTO_EV_FLAG_IO_CLOSE_FD is provided the passed in fd is automatically
* closed when the event is freed with verto_del()
*
* NOTE: On Windows, the underlying select() only works with sockets. As such,
* any attempt to add a non-socket io event on Windows will produce undefined
* results and may even crash.
*
* @see verto_del()
* @param ctx The verto_ctx which will fire the callback.
* @param flags The flags to set (at least one VERTO_EV_FLAG_IO* required).
* @param callback The callback to fire.
* @param fd The file descriptor to watch for reads.
* @return The verto_ev registered with the event context or NULL on error.
*/
verto_ev *
verto_add_io(verto_ctx *ctx, verto_ev_flag flags,
verto_callback *callback, int fd);
/**
* Adds a callback executed after a period of time.
*
* All verto_ev events are automatically freed when their parent verto_ctx is
* freed. You do not need to free them manually. If VERTO_EV_FLAG_PERSIST is
* provided, the event will repeat until verto_del() is called. If
* VERTO_EV_FLAG_PERSIST is not provided, the event will be freed automatically
* after its execution. In either case, you may call verto_del() at any time
* to prevent the event from executing.
*
* @see verto_del()
* @param ctx The verto_ctx which will fire the callback.
* @param flags The flags to set.
* @param callback The callback to fire.
* @param interval Time period to wait before firing (in milliseconds).
* @return The verto_ev registered with the event context.
*/
verto_ev *
verto_add_timeout(verto_ctx *ctx, verto_ev_flag flags,
verto_callback *callback, time_t interval);
/**
* Adds a callback executed when there is nothing else to do.
*
* All verto_ev events are automatically freed when their parent verto_ctx is
* freed. You do not need to free them manually. If VERTO_EV_FLAG_PERSIST is
* provided, the event will repeat until verto_del() is called. If
* VERTO_EV_FLAG_PERSIST is not provided, the event will be freed automatically
* after its execution. In either case, you may call verto_del() at any time
* to prevent the event from executing.
*
* @see verto_del()
* @param ctx The verto_ctx which will fire the callback.
* @param flags The flags to set.
* @param callback The callback to fire.
* @return The verto_ev registered with the event context.
*/
verto_ev *
verto_add_idle(verto_ctx *ctx, verto_ev_flag flags,
verto_callback *callback);
/**
* Adds a callback executed when a signal is received.
*
* All verto_ev events are automatically freed when their parent verto_ctx is
* freed. You do not need to free them manually. If VERTO_EV_FLAG_PERSIST is
* provided, the event will repeat until verto_del() is called. If
* VERTO_EV_FLAG_PERSIST is not provided, the event will be freed automatically
* after its execution. In either case, you may call verto_del() at any time
* to prevent the event from executing.
*
* NOTE: If you attempt to ignore a signal without the VERTO_EV_FLAG_PERSIST
* flag, this function fails.
*
* NOTE: SIGCHLD is expressly not supported. If you want this notification,
* please use verto_add_child().
*
* WARNNIG: Signal events can only be reliably received in the default verto_ctx
* in some implementations. Attempting to receive signal events in non-default
* loops may result in assert() failures.
*
* WARNING: While verto does its best to protect you from crashes, there is
* essentially no way to do signal events if you mix multiple implementations in
* a single process. Attempting to do so will result in undefined behavior,
* and potentially even a crash. You have been warned.
*
* @see verto_add_child()
* @see verto_repeat()
* @see verto_del()
* @param ctx The verto_ctx which will fire the callback.
* @param flags The flags to set.
* @param callback The callback to fire.
* @param signal The signal to watch for.
* @return The verto_ev registered with the event context.
*/
verto_ev *
verto_add_signal(verto_ctx *ctx, verto_ev_flag flags,
verto_callback *callback, int signal);
/**
* Adds a callback executed when a child process exits.
*
* This event will be freed automatically after its execution. Due to the
* nature of a process' life-cycle, child events cannot persist (processes only
* exit once). This function returns NULL if you attempt to use
* VERTO_EV_FLAG_PERSIST. You may, of course, call verto_del() at any time to
* prevent the callback from firing.
*
* @see verto_del()
* @param ctx The verto_ctx which will fire the callback.
* @param flags The flags to set.
* @param callback The callback to fire.
* @param child The pid (POSIX) or handle (Win32) of the child to watch for.
* @return The verto_ev registered with the event context.
*/
verto_ev *
verto_add_child(verto_ctx *ctx, verto_ev_flag flags,
verto_callback *callback, verto_proc proc);
/**
* Sets the private pointer of the verto_ev.
*
* The free callback will be called in two cases:
* 1. When the event is deleted (manually or automatically)
* 2. When verto_set_private() is called again, unless
* free is NULL.
*
* @see verto_get_private()
* @param ev The verto_ev
* @param priv The private value to store
* @param free The callback used to free the data or NULL
*/
void
verto_set_private(verto_ev *ev, void *priv, verto_callback *free);
/**
* Gets the private pointer of the verto_ev.
*
* @see verto_set_private()
* @param ev The verto_ev
* @return The verto_ev private pointer
*/
void *
verto_get_private(const verto_ev *ev);
/**
* Gets the type of the verto_ev.
*
* @see verto_add_io()
* @see verto_add_timeout()
* @see verto_add_idle()
* @see verto_add_signal()
* @see verto_add_child()
* @param ev The verto_ev
* @return The verto_ev type
*/
verto_ev_type
verto_get_type(const verto_ev *ev);
/**
* Gets the flags associated with the given verto_ev.
*
* @see verto_add_io()
* @see verto_add_timeout()
* @see verto_add_idle()
* @see verto_add_signal()
* @see verto_add_child()
* @see verto_set_flags()
* @param ev The verto_ev
* @return The verto_ev type
*/
verto_ev_flag
verto_get_flags(const verto_ev *ev);
/**
* Sets the flags associated with the given verto_ev.
*
* See _VERTO_EV_FLAG_MUTABLE_MASK for the flags that can be changed
* with this function. All others will be ignored. If the flags specified
* are the same as the flags the event already has, this function is a no-op.
*
* @see verto_add_io()
* @see verto_add_timeout()
* @see verto_add_idle()
* @see verto_add_signal()
* @see verto_add_child()
* @see verto_get_flags()
* @param ev The verto_ev
* @param flags The flags for the event
*/
void
verto_set_flags(verto_ev *ev, verto_ev_flag flags);
/**
* Gets the file descriptor associated with a read/write verto_ev.
*
* @see verto_add_io()
* @param ev The verto_ev to retrieve the file descriptor from.
* @return The file descriptor, or -1 if not a read/write event.
*/
int
verto_get_fd(const verto_ev *ev);
/**
* Gets the file descriptor state from when the event fires.
*
* @see verto_add_io()
* @param ev The verto_ev to retrieve the fd state from.
* @return The fd state.
*/
verto_ev_flag
verto_get_fd_state(const verto_ev *ev);
/**
* Gets the interval associated with a timeout verto_ev.
*
* @see verto_add_timeout()
* @param ev The verto_ev to retrieve the interval from.
* @return The interval, or 0 if not a timeout event.
*/
time_t
verto_get_interval(const verto_ev *ev);
/**
* Gets the signal associated with a signal verto_ev.
*
* @see verto_add_signal()
* @param ev The verto_ev to retrieve the signal from.
* @return The signal, or -1 if not a signal event.
*/
int
verto_get_signal(const verto_ev *ev);
/**
* Gets the process associated with a child verto_ev.
*
* @see verto_add_child()
* @param ev The verto_ev to retrieve the process from.
* @return The pid/handle, or 0/NULL if not a child event (POSIX/Win32).
*/
verto_proc
verto_get_proc(const verto_ev *ev);
/**
* Gets the status of the process which caused this event to fire.
*
* @see verto_add_child()
* @param ev The verto_ev to retrieve the status from.
* @return The pid/handle status.
*/
verto_proc_status
verto_get_proc_status(const verto_ev *ev);
/**
* Gets the verto_ctx associated with a verto_ev.
*
* This is a borrowed reference, don't attempt to free it!
*
* @param ev The verto_ev to retrieve the verto_ctx from.
* @return The verto_ctx.
*/
verto_ctx *
verto_get_ctx(const verto_ev *ev);
/**
* Removes an event from from the event context and frees it.
*
* The event and its contents cannot be used after this call.
*
* @see verto_add_io()
* @see verto_add_timeout()
* @see verto_add_idle()
* @see verto_add_signal()
* @see verto_add_child()
* @param ev The event to delete.
*/
void
verto_del(verto_ev *ev);
/**
* Returns the event types supported by this implementation.
*
* @param ctx The verto_ctx to query.
* @return The event types supported.
*/
verto_ev_type
verto_get_supported_types(verto_ctx *ctx);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* VERTO_H_ */
libverto-0.3.1/tests/ 0000775 0000000 0000000 00000000000 13435347213 0014510 5 ustar 00root root 0000000 0000000 libverto-0.3.1/tests/Makefile.am 0000664 0000000 0000000 00000000763 13435347213 0016552 0 ustar 00root root 0000000 0000000 AUTOMAKE_OPTIONS = parallel-tests color-tests
LDADD = $(abs_top_builddir)/src/libverto.la
AM_LDFLAGS = -rpath $(abs_top_builddir)/src/.libs
AM_CFLAGS = -Wall -I$(abs_top_srcdir)/src
if MODULE_GLIB
AM_CFLAGS += -DHAVE_GLIB=1
endif
if MODULE_LIBEV
AM_CFLAGS += -DHAVE_LIBEV=1
endif
if MODULE_LIBEVENT
AM_CFLAGS += -DHAVE_LIBEVENT=1
endif
if MODULE_TEVENT
AM_CFLAGS += -DHAVE_TEVENT=1
endif
check_PROGRAMS = timeout idle child signal read write
EXTRA_DIST = test.h
TESTS = $(check_PROGRAMS)
libverto-0.3.1/tests/child.c 0000664 0000000 0000000 00000004773 13435347213 0015752 0 ustar 00root root 0000000 0000000 /*
* Copyright 2011 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include
#include
#include
#include "test.h"
#define EXITCODE 17
static int exitstatus;
static int freed;
void
exit_cb(verto_ctx *ctx, verto_ev *ev)
{
(void) ctx;
(void) ev;
if (WEXITSTATUS(exitstatus) != EXITCODE) {
printf("ERROR: Child event never fired!\n");
retval = 1;
}
if (!freed) {
printf("ERROR: On free never fired!\n");
retval = 1;
}
verto_break(ctx);
}
void
onfree(verto_ctx *ctx, verto_ev *ev)
{
(void) ctx;
(void) ev;
freed = 1;
}
void
cb(verto_ctx *ctx, verto_ev *ev)
{
(void) ctx;
(void) ev;
exitstatus = verto_get_proc_status(ev);
}
int
do_test(verto_ctx *ctx)
{
pid_t pid;
verto_ev *ev;
exitstatus = 0;
freed = 0;
if (!(verto_get_supported_types(ctx) & VERTO_EV_TYPE_CHILD)) {
printf("WARNING: Child not supported!\n");
verto_break(ctx);
return 0;
}
pid = fork();
if (pid < 0)
return 1;
else if (pid == 0) {
usleep(50000); /* 0.05 seconds */
exit(EXITCODE);
}
/* Persist makes no sense for children events */
assert(!verto_add_child(ctx, VERTO_EV_FLAG_PERSIST, cb, pid));
assert(verto_add_timeout(ctx, VERTO_EV_FLAG_NONE, exit_cb, 1000));
ev = verto_add_child(ctx, VERTO_EV_FLAG_NONE, cb, pid);
assert(ev);
verto_set_private(ev, NULL, onfree);
return 0;
}
libverto-0.3.1/tests/idle.c 0000664 0000000 0000000 00000004700 13435347213 0015572 0 ustar 00root root 0000000 0000000 /*
* Copyright 2011 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "test.h"
static int callcount;
void
exit_cb(verto_ctx *ctx, verto_ev *ev)
{
(void) ctx;
(void) ev;
retval = 1;
switch (callcount) {
case 0:
printf("ERROR: Idle (persist) did not fire!\n");
break;
case 1:
printf("ERROR: Idle (persist) did not recur!\n");
break;
case 2:
printf("ERROR: Idle (non-persist) did not fire!\n");
break;
case 3:
printf("ERROR: Idle on free did not fire!\n");
break;
case 4:
retval = 0;
break;
default:
break;
}
verto_break(ctx);
}
void
onfree(verto_ctx *ctx, verto_ev *ev) {
(void) ctx;
(void) ev;
++callcount;
}
void
cb(verto_ctx *ctx, verto_ev *ev)
{
if (++callcount == 2) {
verto_ev *newev = verto_add_idle(ctx, VERTO_EV_FLAG_NONE, cb);
verto_set_private(newev, NULL, onfree);
assert(newev);
verto_del(ev);
}
}
int
do_test(verto_ctx *ctx)
{
callcount = 0;
if (!(verto_get_supported_types(ctx) & VERTO_EV_TYPE_IDLE)) {
printf("WARNING: Idle not supported!\n");
verto_break(ctx);
return 0;
}
assert(verto_add_idle(ctx, VERTO_EV_FLAG_PERSIST, cb));
assert(verto_add_timeout(ctx, VERTO_EV_FLAG_NONE, exit_cb, 1000));
return 0;
}
libverto-0.3.1/tests/read.c 0000664 0000000 0000000 00000005177 13435347213 0015601 0 ustar 00root root 0000000 0000000 /*
* Copyright 2011 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include
#include
#include
#include
#include
#include
#include
#include "test.h"
#define DATA "hello"
#define DATALEN 5
static int fds[2];
static int callcount = 0;
static void
timeout_cb(verto_ctx *ctx, verto_ev *ev)
{
(void) ev;
printf("ERROR: Timeout!\n");
if (fds[0] >= 0)
close(fds[0]);
if (fds[1] >= 0)
close(fds[1]);
retval = 1;
verto_break(ctx);
}
static void
cb(verto_ctx *ctx, verto_ev *ev)
{
unsigned char buff[DATALEN];
int fd = 0;
ssize_t bytes = 0;
fd = verto_get_fd(ev);
assert(fd == fds[0]);
bytes = read(fd, buff, DATALEN);
if (callcount++ == 0) {
assert(verto_get_fd_state(ev) & VERTO_EV_FLAG_IO_READ);
assert(bytes == DATALEN);
close(fds[1]);
fds[1] = -1;
}
else {
if (!(verto_get_fd_state(ev) & VERTO_EV_FLAG_IO_ERROR))
printf("WARNING: VERTO_EV_FLAG_IO_ERROR not supported!\n");
assert(bytes != DATALEN);
close(fd);
fds[0] = -1;
verto_del(ev);
verto_break(ctx);
}
}
int
do_test(verto_ctx *ctx)
{
callcount = 0;
fds[0] = -1;
fds[1] = -1;
assert(verto_get_supported_types(ctx) & VERTO_EV_TYPE_IO);
assert(pipe(fds) == 0);
assert(verto_add_timeout(ctx, VERTO_EV_FLAG_NONE, timeout_cb, 1000));
assert(verto_add_io(ctx, VERTO_EV_FLAG_PERSIST | VERTO_EV_FLAG_IO_READ, cb, fds[0]));
assert(write(fds[1], DATA, DATALEN) == DATALEN);
return 0;
}
libverto-0.3.1/tests/signal.c 0000664 0000000 0000000 00000005503 13435347213 0016134 0 ustar 00root root 0000000 0000000 /*
* Copyright 2011 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include
#include
#include
#include
#include
#include "test.h"
static int count;
void
exit_cb(verto_ctx *ctx, verto_ev *ev)
{
if ((pid_t) (uintptr_t) verto_get_private(ev) != 0)
waitpid((pid_t) (uintptr_t) verto_get_private(ev), NULL, 0);
switch (count) {
case 0:
printf("ERROR: Signal callback never fired!\n");
break;
case 1:
printf("ERROR: Signal MUST recur!\n");
break;
default:
break;
}
retval = count != 2;
verto_break(ctx);
}
void
cb(verto_ctx *ctx, verto_ev *ev)
{
(void) ctx;
(void) ev;
count++;
}
int
do_test(verto_ctx *ctx)
{
verto_ev *ev;
pid_t pid = 0;
count = 0;
if (!(verto_get_supported_types(ctx) & VERTO_EV_TYPE_SIGNAL)) {
printf("WARNING: Signal not supported!\n");
verto_break(ctx);
return 0;
}
/* We should get a failure when trying to create a non-persistent ignore */
assert(!verto_add_signal(ctx, VERTO_EV_FLAG_NONE, VERTO_SIG_IGN, SIGUSR2));
assert(verto_add_signal(ctx, VERTO_EV_FLAG_PERSIST, cb, SIGUSR1));
assert(verto_add_signal(ctx, VERTO_EV_FLAG_PERSIST, VERTO_SIG_IGN, SIGUSR2));
pid = fork();
if (pid < 0)
return 1;
else if (pid == 0) {
usleep(10000); /* 0.01 seconds */
kill(getppid(), SIGUSR1);
usleep(10000); /* 0.01 seconds */
kill(getppid(), SIGUSR1);
usleep(10000); /* 0.01 seconds */
kill(getppid(), SIGUSR2);
exit(0);
}
ev = verto_add_timeout(ctx, VERTO_EV_FLAG_NONE, exit_cb, 1000);
assert(ev);
verto_set_private(ev, (void *) (uintptr_t) pid, NULL);
return 0;
}
libverto-0.3.1/tests/test.h 0000664 0000000 0000000 00000004573 13435347213 0015651 0 ustar 00root root 0000000 0000000 /*
* Copyright 2011 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include
#include
#include
#include
#include
#include
#include
static char *MODULES[] = {
#ifdef BUILTIN_MODULE
#define __str(s) #s
#define _str(s) __str(s)
_str(BUILTIN_MODULE),
#undef _str
#undef __str
#endif
#ifdef HAVE_GLIB
"glib",
#endif
#ifdef HAVE_LIBEV
"libev",
#endif
#ifdef HAVE_LIBEVENT
"libevent",
#endif
#ifdef HAVE_TEVENT
"tevent",
#endif
NULL,
NULL,
};
int do_test(verto_ctx *ctx);
static int retval = 0;
int
main(int argc, char **argv)
{
int i;
verto_ctx *ctx;
if (argc == 2) {
MODULES[0] = argv[1];
MODULES[1] = NULL;
}
for (i=0 ; MODULES[i] ; i++) {
printf("Module: %s\n", MODULES[i]);
assert((ctx = verto_default(MODULES[i], VERTO_EV_TYPE_NONE)));
retval = do_test(ctx);
if (retval != 0) {
verto_free(ctx);
return retval;
}
verto_run(ctx);
verto_free(ctx);
if (retval != 0)
break;
}
verto_cleanup();
return retval;
}
void *passert(void *p) {
assert(p);
return p;
}
#define new0(type) _new0(sizeof(type))
void * _new0(ssize_t size) {
void *p = malloc(size);
return passert(p ? memset(p, 0, size) : p);
}
libverto-0.3.1/tests/timeout.c 0000664 0000000 0000000 00000004716 13435347213 0016352 0 ustar 00root root 0000000 0000000 /*
* Copyright 2011 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include
#include "test.h"
/* The glib timer will subtract a perterbation of up to 10ms based on your
* DBUS session or HOSTNAME (see g_timeout_set_expiration). */
#define SLEEP 10
#define SLEEP_MIN (SLEEP-10)
#define SLEEP_MAX (SLEEP*4)
#define M2U(m) ((m) * 1000)
static int callcount;
struct timeval starttime;
static char
elapsed(time_t min, time_t max)
{
struct timeval tv;
long long diff;
assert(gettimeofday(&tv, NULL) == 0);
diff = (tv.tv_sec - starttime.tv_sec) * M2U(1000)
+ tv.tv_usec - starttime.tv_usec;
assert(gettimeofday(&starttime, NULL) == 0);
if (diff < M2U(min) || diff > M2U(max)) {
printf("ERROR: Timeout is out-of-bounds!\n");
return 0;
}
return 1;
}
static void
exit_cb(verto_ctx *ctx, verto_ev *ev)
{
(void) ev;
assert(callcount == 3);
verto_break(ctx);
}
static void
cb(verto_ctx *ctx, verto_ev *ev)
{
assert(elapsed(SLEEP_MIN, SLEEP_MAX));
if (++callcount == 3)
assert(verto_add_timeout(ctx, VERTO_EV_FLAG_NONE, exit_cb, SLEEP*2));
else if (callcount == 2) {
assert(verto_add_timeout(ctx, VERTO_EV_FLAG_NONE, cb, SLEEP));
verto_del(ev);
}
}
int
do_test(verto_ctx *ctx)
{
callcount = 0;
assert(gettimeofday(&starttime, NULL) == 0);
assert(verto_add_timeout(ctx, VERTO_EV_FLAG_PERSIST, cb, SLEEP));
return 0;
}
libverto-0.3.1/tests/write.c 0000664 0000000 0000000 00000005723 13435347213 0016015 0 ustar 00root root 0000000 0000000 /*
* Copyright 2011 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include
#include
#include
#include
#include
#include
#include
#include "test.h"
#define DATA "hello"
#define DATALEN 5
static int fds[2];
static int callcount = 0;
static void
timeout_cb(verto_ctx *ctx, verto_ev *ev)
{
(void) ev;
printf("ERROR: Timeout!\n");
if (fds[0] >= 0)
close(fds[0]);
if (fds[1] >= 0)
close(fds[1]);
retval = 1;
verto_break(ctx);
}
static void
error_cb(verto_ctx *ctx, verto_ev *ev)
{
int fd = 0;
/* When we get here, the fd should be closed, so an error should occur */
fd = verto_get_fd(ev);
if (!(verto_get_fd_state(ev) & VERTO_EV_FLAG_IO_ERROR))
printf("WARNING: VERTO_EV_FLAG_IO_ERROR not supported!\n");
assert(write(fd, DATA, DATALEN) != DATALEN);
close(fd);
fds[1] = -1;
verto_break(ctx);
}
static void
read_cb(verto_ctx *ctx, verto_ev *ev)
{
unsigned char buff[DATALEN];
int fd = verto_get_fd(ev);
assert(read(fd, buff, DATALEN) == DATALEN);
close(fd);
fds[0] = -1;
assert(verto_add_io(ctx, VERTO_EV_FLAG_IO_WRITE, error_cb, fds[1]));
}
static void
write_cb(verto_ctx *ctx, verto_ev *ev)
{
int fd = 0;
fd = verto_get_fd(ev);
assert(verto_get_fd_state(ev) & VERTO_EV_FLAG_IO_WRITE);
assert(write(fd, DATA, DATALEN) == DATALEN);
assert(verto_add_io(ctx, VERTO_EV_FLAG_IO_READ, read_cb, fds[0]));
}
int
do_test(verto_ctx *ctx)
{
callcount = 0;
fds[0] = -1;
fds[1] = -1;
assert(verto_get_supported_types(ctx) & VERTO_EV_TYPE_IO);
if (!verto_add_signal(ctx, VERTO_EV_FLAG_NONE, VERTO_SIG_IGN, SIGPIPE))
signal(SIGPIPE, SIG_IGN);
assert(pipe(fds) == 0);
assert(verto_add_timeout(ctx, VERTO_EV_FLAG_NONE, timeout_cb, 1000));
assert(verto_add_io(ctx, VERTO_EV_FLAG_IO_WRITE, write_cb, fds[1]));
return 0;
}