зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1360264 - Update libevent to 2.1.8-stable. r=billm
--HG-- extra : rebase_source : 82d7bf7e67e822cb8d09a30d52c89516673dcc55
This commit is contained in:
Родитель
9daa8bb478
Коммит
64fe0d9416
|
@ -0,0 +1,63 @@
|
|||
---
|
||||
Language: Cpp
|
||||
BasedOnStyle: LLVM
|
||||
|
||||
AccessModifierOffset: -4
|
||||
|
||||
AlignAfterOpenBracket: DontAlign
|
||||
AlignEscapedNewlinesLeft: true
|
||||
# AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
|
||||
AlwaysBreakAfterDefinitionReturnType: All
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: false
|
||||
|
||||
# BinPackArguments: false
|
||||
# BinPackParameters: true
|
||||
|
||||
BreakBeforeBinaryOperators: false
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping: { AfterFunction: true }
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: true
|
||||
|
||||
ColumnLimit: 80
|
||||
|
||||
ContinuationIndentWidth: 4
|
||||
|
||||
DerivePointerAlignment: false #XXX
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false #XXX
|
||||
ForEachMacros: [ LIST_FOREACH, SIMPLEQ_FOREACH, CIRCLEQ_FOREACH, TAILQ_FOREACH, TAILQ_FOREACH_REVERSE, HT_FOREACH ]
|
||||
|
||||
IndentCaseLabels: false
|
||||
IndentFunctionDeclarationAfterType: false
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
MaxEmptyLinesToKeep: 2
|
||||
|
||||
PointerAlignment: Right #XXX
|
||||
|
||||
# SpaceAfterCStyleCast: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
Standard: Cpp03
|
||||
TabWidth: 4
|
||||
UseTab: Always
|
||||
SortIncludes: false
|
||||
...
|
|
@ -0,0 +1,149 @@
|
|||
### These files should get ignored no matter where they appear.
|
||||
|
||||
# Editors leave these lying around
|
||||
\#*\#
|
||||
.#*
|
||||
*~
|
||||
*.swp
|
||||
|
||||
# C stuff
|
||||
*.o
|
||||
|
||||
# Windows stuff
|
||||
*.obj
|
||||
*.exe
|
||||
*.lib
|
||||
|
||||
# Patch leaves these lying arround
|
||||
*.orig
|
||||
*.rej
|
||||
|
||||
# gcov stuff
|
||||
*.gcno
|
||||
*.gcov
|
||||
*.gcda
|
||||
|
||||
# gdb stuff
|
||||
.gdb_history
|
||||
|
||||
# Autotools stuff
|
||||
.deps
|
||||
.dirstamp
|
||||
Makefile
|
||||
Makefile.in
|
||||
|
||||
# Libtool stuff
|
||||
.libs
|
||||
*.lo
|
||||
*.la
|
||||
|
||||
# ctags stuff
|
||||
TAGS
|
||||
tags
|
||||
|
||||
# cscope stuff
|
||||
cscope*
|
||||
|
||||
# Stuff made by our makefiles
|
||||
*.pc
|
||||
*.log
|
||||
*.trs
|
||||
|
||||
## The initial / makes these files only get ignored in particular directories.
|
||||
/autom4te.cache
|
||||
|
||||
# configure in progress
|
||||
/.cyg*
|
||||
/confdefs.*
|
||||
/conftest.*
|
||||
|
||||
# Libtool adds these, at least sometimes
|
||||
/m4/libtool.m4
|
||||
/m4/ltoptions.m4
|
||||
/m4/ltsugar.m4
|
||||
/m4/ltversion.m4
|
||||
/m4/lt~obsolete.m4
|
||||
|
||||
/aclocal.m4
|
||||
/compile
|
||||
/doxygen
|
||||
/config.cache
|
||||
/config.guess
|
||||
/config.log
|
||||
/config.status
|
||||
/config.sub
|
||||
/configure
|
||||
/configure.lineno
|
||||
/depcomp
|
||||
/config.h
|
||||
/config.h.in
|
||||
/install-sh
|
||||
/libtool
|
||||
/ltmain.sh
|
||||
/missing
|
||||
/stamp-h1
|
||||
/stamp-h2
|
||||
|
||||
/include/event2/event-config.h
|
||||
/evconfig-private.h
|
||||
|
||||
/sample/dns-example
|
||||
/sample/event-read-fifo
|
||||
/sample/hello-world
|
||||
/sample/http-server
|
||||
/sample/http-connect
|
||||
/sample/le-proxy
|
||||
/sample/https-client
|
||||
/sample/signal-test
|
||||
/sample/time-test
|
||||
/sample/event-test
|
||||
|
||||
/test-driver
|
||||
/test/bench
|
||||
/test/bench_cascade
|
||||
/test/bench_http
|
||||
/test/bench_httpclient
|
||||
/test/regress
|
||||
/test/regress.gen.c
|
||||
/test/regress.gen.h
|
||||
/test/rpcgen-attempted
|
||||
/test/test-dumpevents
|
||||
/test/test-eof
|
||||
/test/test-closed
|
||||
/test/test-init
|
||||
/test/test-ratelim
|
||||
/test/test-script.sh
|
||||
/test/test-time
|
||||
/test/test-weof
|
||||
/test/test-changelist
|
||||
/test/test-fdleak
|
||||
|
||||
|
||||
# Files generated by cmake
|
||||
/CMakeCache.txt
|
||||
/CMakeFiles/
|
||||
/CTestTestfile.cmake
|
||||
/DartConfiguration.tcl
|
||||
/LibeventConfig.cmake
|
||||
/LibeventConfigVersion.cmake
|
||||
/LibeventTargets.cmake
|
||||
/bin/
|
||||
/cmake_install.cmake
|
||||
/include/evconfig-private.h
|
||||
/lib/
|
||||
/tmp/
|
||||
/verify_tests.sh
|
||||
/verify_tests.bat
|
||||
/event.dir
|
||||
/event_core.dir
|
||||
/event_extra.dir
|
||||
*.vcxproj
|
||||
*.sln
|
||||
*.filters
|
||||
|
||||
# make dist
|
||||
/COPYING
|
||||
/INSTALL
|
||||
/*.tar.gz
|
||||
|
||||
/.vagrant
|
|
@ -0,0 +1,100 @@
|
|||
os:
|
||||
- linux
|
||||
- osx
|
||||
sudo: false
|
||||
dist: trusty
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- EVENT_BUILD_METHOD=cmake EVENT_CMAKE_OPTIONS="-DEVENT__COVERAGE=ON -DCMAKE_BUILD_TYPE=debug" COVERALLS=yes
|
||||
- EVENT_BUILD_METHOD=cmake EVENT_CMAKE_OPTIONS=""
|
||||
- EVENT_BUILD_METHOD=cmake EVENT_CMAKE_OPTIONS="-DEVENT__DISABLE_OPENSSL=ON"
|
||||
- EVENT_BUILD_METHOD=cmake EVENT_CMAKE_OPTIONS="-DEVENT__DISABLE_THREAD_SUPPORT=ON"
|
||||
- EVENT_BUILD_METHOD=cmake EVENT_CMAKE_OPTIONS="-DEVENT__DISABLE_DEBUG_MODE=ON"
|
||||
- EVENT_BUILD_METHOD=cmake EVENT_CMAKE_OPTIONS="-DEVENT__DISABLE_MM_REPLACEMENT=ON"
|
||||
- EVENT_BUILD_METHOD=cmake EVENT_CMAKE_OPTIONS="-DEVENT__ENABLE_VERBOSE_DEBUG=ON"
|
||||
- EVENT_BUILD_METHOD=autotools EVENT_CONFIGURE_OPTIONS=""
|
||||
- EVENT_BUILD_METHOD=autotools EVENT_CONFIGURE_OPTIONS="--disable-openssl"
|
||||
- EVENT_BUILD_METHOD=autotools EVENT_CONFIGURE_OPTIONS="--disable-thread-support"
|
||||
- EVENT_BUILD_METHOD=autotools EVENT_CONFIGURE_OPTIONS="--disable-debug-mode"
|
||||
- EVENT_BUILD_METHOD=autotools EVENT_CONFIGURE_OPTIONS="--disable-malloc-replacement"
|
||||
|
||||
language: c
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
|
||||
before_install:
|
||||
- if [ -n "$COVERALLS" ]; then
|
||||
pip install --user cpp-coveralls;
|
||||
fi
|
||||
- export JOBS=20
|
||||
- export TIMEOUT=50
|
||||
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then
|
||||
brew update;
|
||||
brew uninstall libtool && brew install libtool;
|
||||
brew install openssl;
|
||||
brew install lcov;
|
||||
if [ "$CC" == "gcc" ]; then
|
||||
export CC=$(ls -t /usr/local/bin/gcc-?.?);
|
||||
fi
|
||||
|
||||
export OPENSSL_ROOT=$(echo /usr/local/Cellar/openssl/*);
|
||||
export
|
||||
CMAKE_INCLUDE_PATH=$OPENSSL_ROOT/include
|
||||
CMAKE_LIBRARY_PATH=$OPENSSL_ROOT/lib;
|
||||
export
|
||||
CFLAGS=-I$CMAKE_INCLUDE_PATH
|
||||
LDFLAGS=-L$CMAKE_LIBRARY_PATH;
|
||||
|
||||
export JOBS=4;
|
||||
fi
|
||||
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- xenial
|
||||
- sourceline: 'deb http://archive.ubuntu.com/ubuntu xenial main'
|
||||
packages:
|
||||
- zlib1g-dev
|
||||
- libssl-dev
|
||||
- build-essential
|
||||
- automake
|
||||
- autoconf
|
||||
- cmake
|
||||
- lcov
|
||||
|
||||
script:
|
||||
- if [ "$EVENT_BUILD_METHOD" = "autotools" ]; then
|
||||
./autogen.sh &&
|
||||
./configure $EVENT_CONFIGURE_OPTIONS &&
|
||||
make &&
|
||||
travis_wait $TIMEOUT make -j $JOBS verify;
|
||||
fi
|
||||
- if [ "$EVENT_BUILD_METHOD" = "cmake" ]; then
|
||||
export
|
||||
CTEST_PARALLEL_LEVEL=$JOBS
|
||||
CTEST_OUTPUT_ON_FAILURE=1;
|
||||
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake .. $EVENT_CMAKE_OPTIONS &&
|
||||
travis_wait $TIMEOUT
|
||||
cmake --build . --target verify;
|
||||
fi
|
||||
|
||||
after_script:
|
||||
- if [ -n "$COVERALLS" ]; then
|
||||
coveralls
|
||||
--build-root .
|
||||
--root ..
|
||||
--exclude test
|
||||
--exclude sample
|
||||
--exclude cmake
|
||||
--exclude build/CMakeFiles/CheckTypeSize
|
||||
--exclude build/CMakeFiles/CompilerIdC
|
||||
--gcov-options '\-lp';
|
||||
fi
|
||||
|
||||
notifications:
|
||||
irc: "irc.oftc.net#libevent"
|
|
@ -0,0 +1,55 @@
|
|||
input_tab_size = 8
|
||||
output_tab_size = 8
|
||||
indent_with_tabs = 2
|
||||
indent_cmt_with_tabs = false
|
||||
indent_brace_parent = false
|
||||
indent_func_call_param = true
|
||||
indent_func_def_param = true
|
||||
sp_enum_before_assign = add
|
||||
sp_enum_after_assign = add
|
||||
sp_inside_paren = remove
|
||||
sp_paren_brace = add
|
||||
sp_before_ptr_star = add
|
||||
sp_before_unnamed_ptr_star = add
|
||||
sp_between_ptr_star = remove
|
||||
sp_after_ptr_star = remove
|
||||
sp_after_ptr_star_func = add
|
||||
sp_before_ptr_star_func = add
|
||||
sp_before_sparen = add
|
||||
sp_inside_sparen = remove
|
||||
sp_inside_sparen_close = remove
|
||||
sp_after_sparen = add
|
||||
sp_sparen_brace = add
|
||||
sp_special_semi = remove
|
||||
sp_before_semi_for = remove
|
||||
sp_after_comma = add
|
||||
sp_after_cast = remove
|
||||
sp_inside_braces_struct = add
|
||||
sp_type_func = remove
|
||||
sp_func_def_paren = remove
|
||||
sp_inside_fparen = remove
|
||||
sp_fparen_brace = add
|
||||
sp_func_call_paren = remove
|
||||
sp_else_brace = add
|
||||
sp_after_oc_block_caret = remove
|
||||
align_keep_tabs = true
|
||||
align_with_tabs = true
|
||||
align_on_tabstop = true
|
||||
nl_fcall_brace = remove
|
||||
nl_enum_brace = remove
|
||||
nl_struct_brace = remove
|
||||
nl_union_brace = remove
|
||||
nl_if_brace = remove
|
||||
nl_brace_else = remove
|
||||
nl_elseif_brace = remove
|
||||
nl_else_brace = remove
|
||||
nl_else_if = remove
|
||||
nl_for_brace = remove
|
||||
sp_after_semi_for_empty = remove
|
||||
nl_while_brace = remove
|
||||
nl_do_brace = remove
|
||||
nl_brace_while = remove
|
||||
nl_switch_brace = remove
|
||||
nl_func_type_name = add
|
||||
nl_fdef_brace = add
|
||||
mod_paren_on_return = ignore
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,35 @@
|
|||
# Contributing to the libevent
|
||||
|
||||
## Coding style
|
||||
|
||||
First and most generic rule: **just look around**.
|
||||
|
||||
But, we have a script for checking patches/files/git-refs:
|
||||
```shell
|
||||
# Chech HEAD git ref
|
||||
./checkpatch.sh -r
|
||||
./checkpatch.sh -r HEAD
|
||||
|
||||
# Check patch
|
||||
git format-patch --stdout -1 | ./checkpatch.sh -p
|
||||
git show -1 | ./checkpatch.sh -p
|
||||
|
||||
# Or via regular files
|
||||
git format-patch --stdout -2
|
||||
./checkpatch.sh *.patch
|
||||
|
||||
# Over a file
|
||||
./checkpatch.sh -d event.c
|
||||
./checkpatch.sh -d < event.c
|
||||
|
||||
# And print the whole file not only summary
|
||||
./checkpatch.sh -f event.c
|
||||
./checkpatch.sh -f < event.c
|
||||
|
||||
# See
|
||||
./checkpatch.sh -h
|
||||
```
|
||||
|
||||
## Testing
|
||||
- Write new unit test in `test/regress_{MORE_SUITABLE_FOR_YOU}.c`
|
||||
- `make verify`
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,231 @@
|
|||
Changes in 1.4.14b-stable
|
||||
o Set the VERSION_INFO correctly for 1.4.14
|
||||
|
||||
Changes in 1.4.14-stable
|
||||
o Add a .gitignore file for the 1.4 branch. (d014edb)
|
||||
o Backport evbuffer_readln(). (b04cc60 Nicholas Marriott)
|
||||
o Make the evbuffer_readln backport follow the current API (c545485)
|
||||
o Valgrind fix: Clear struct kevent before checking for OSX bug. (5713d5d William Ahern)
|
||||
o Fix a crash when reading badly formatted resolve.conf (5b10d00 Yasuoka Masahiko)
|
||||
o Fix memory-leak of signal handler array with kqueue. [backport] (01f3775)
|
||||
o Update sample/signal-test.c to use newer APIs and not leak. (891765c Evan Jones)
|
||||
o Correct all versions in 1.4 branch (ac0d213)
|
||||
o Make evutil_make_socket_nonblocking() leave any other flags alone. (81c26ba Jardel Weyrich)
|
||||
o Adjusted fcntl() retval comparison on evutil_make_socket_nonblocking(). (5f2e250 Jardel Weyrich)
|
||||
o Correct a debug message in evhttp_parse_request_line (35df59e)
|
||||
o Merge branch 'readln-backport' into patches-1.4 (8771d5b)
|
||||
o Do not send an HTTP error when we've already closed or responded. (4fd2dd9 Pavel Plesov)
|
||||
o Re-add event_siglcb; some old code _was_ still using it. :( (bd03d06)
|
||||
o Make Libevent 1.4 build on win32 with Unicode enabled. (bce58d6 Brodie Thiesfield)
|
||||
o Distribute nmake makefile for 1.4 (20d706d)
|
||||
o do not fail while sending on http connections the client closed. (5c8b446)
|
||||
o make evhttp_send() safe against terminated connections, too (01ea0c5)
|
||||
o Fix a free(NULL) in min_heap.h (2458934)
|
||||
o Fix memory leak when setting up priorities; reported by Alexander Drozdov (cb1a722)
|
||||
o Clean up properly when adding a signal handler fails. (ae6ece0 Gilad Benjamini)
|
||||
o Do not abort HTTP requests missing a reason string. (29d7b32 Pierre Phaneuf)
|
||||
o Fix compile warning in http.c (906d573)
|
||||
o Define _REENTRANT as needed on Solaris, elsewhere (6cbea13)
|
||||
|
||||
|
||||
Changes in 1.4.13-stable:
|
||||
o If the kernel tells us that there are a negative number of bytes to read from a socket, do not believe it. Fixes bug 2841177; found by Alexander Pronchenkov.
|
||||
o Do not allocate the maximum event queue and fd array for the epoll backend at startup. Instead, start out accepting 32 events at a time, and double the queue's size when it seems that the OS is generating events faster than we're requesting them. Saves up to 512K per epoll-based event_base. Resolves bug 2839240.
|
||||
o Fix compilation on Android, which forgot to define fd_mask in its sys/select.h
|
||||
o Do not drop data from evbuffer when out of memory; reported by Jacek Masiulaniec
|
||||
o Rename our replacement compat/sys/_time.h header to avoid build a conflict on HPUX; reported by Kathryn Hogg.
|
||||
o Build kqueue.c correctly on GNU/kFreeBSD platforms. Patch pulled upstream from Debian.
|
||||
o Fix a problem with excessive memory allocation when using multiple event priorities.
|
||||
o When running set[ug]id, don't check the environment. Based on a patch from OpenBSD.
|
||||
|
||||
|
||||
Changes in 1.4.12-stable:
|
||||
o Try to contain degree of failure when running on a win32 version so heavily firewalled that we can't fake a socketpair.
|
||||
o Fix an obscure timing-dependent, allocator-dependent crash in the evdns code.
|
||||
o Use __VA_ARGS__ syntax for varargs macros in event_rpcgen when compiler is not GCC.
|
||||
o Activate fd events in a pseudorandom order with O(N) backends, so that we don't systematically favor low fds (select) or earlier-added fds (poll, win32).
|
||||
o Fix another pair of fencepost bugs in epoll.c. [Patch from Adam Langley.]
|
||||
o Do not break evdns connections to nameservers when our IP changes.
|
||||
o Set truncated flag correctly in evdns server replies.
|
||||
o Disable strict aliasing with GCC: our code is not compliant with it.
|
||||
|
||||
Changes in 1.4.11-stable:
|
||||
o Fix a bug when removing a timeout from the heap. [Patch from Marko Kreen]
|
||||
o Remove the limit on size of HTTP headers by removing static buffers.
|
||||
o Fix a nasty dangling pointer bug in epoll.c that could occur after epoll_recalc(). [Patch from Kevin Springborn]
|
||||
o Distribute Win32-Code/event-config.h, not ./event-config.h
|
||||
|
||||
Changes in 1.4.10-stable:
|
||||
o clean up buffered http connection data on reset; reported by Brian O'Kelley
|
||||
o bug fix and potential race condition in signal handling; from Alexander Drozdov
|
||||
o rename the Solaris event ports backend to evport
|
||||
o support compilation on Haiku
|
||||
o fix signal processing when a signal callback delivers a signal; from Alexander Drozdov
|
||||
o const-ify some arguments to evdns functions.
|
||||
o off-by-one error in epoll_recalc; reported by Victor Goya
|
||||
o include Doxyfile in tar ball; from Jeff Garzik
|
||||
o correctly parse queries with encoded \r, \n or + characters
|
||||
|
||||
Changes in 1.4.9-stable:
|
||||
o event_add would not return error for some backends; from Dean McNamee
|
||||
o Clear the timer cache on entering the event loop; reported by Victor Chang
|
||||
o Only bind the socket on connect when a local address has been provided; reported by Alejo Sanchez
|
||||
o Allow setting of local port for evhttp connections to support millions of connections from a single system; from Richard Jones.
|
||||
o Clear the timer cache when leaving the event loop; reported by Robin Haberkorn
|
||||
o Fix a typo in setting the global event base; reported by lance.
|
||||
o Fix a memory leak when reading multi-line headers
|
||||
o Fix a memory leak by not running explicit close detection for server connections
|
||||
|
||||
Changes in 1.4.8-stable:
|
||||
o Match the query in DNS replies to the query in the request; from Vsevolod Stakhov.
|
||||
o Fix a merge problem in which name_from_addr returned pointers to the stack; found by Jiang Hong.
|
||||
o Do not remove Accept-Encoding header
|
||||
|
||||
Changes in 1.4.7-stable:
|
||||
o Fix a bug where headers arriving in multiple packets were not parsed; fix from Jiang Hong; test by me.
|
||||
|
||||
Changes in 1.4.6-stable:
|
||||
o evutil.h now includes <stdarg.h> directly
|
||||
o switch all uses of [v]snprintf over to evutil
|
||||
o Correct handling of trailing headers in chunked replies; from Scott Lamb.
|
||||
o Support multi-line HTTP headers; based on a patch from Moshe Litvin
|
||||
o Reject negative Content-Length headers; anonymous bug report
|
||||
o Detect CLOCK_MONOTONIC at runtime for evdns; anonymous bug report
|
||||
o Fix a bug where deleting signals with the kqueue backend would cause subsequent adds to fail
|
||||
o Support multiple events listening on the same signal; make signals regular events that go on the same event queue; problem report by Alexander Drozdov.
|
||||
o Deal with evbuffer_read() returning -1 on EINTR|EAGAIN; from Adam Langley.
|
||||
o Fix a bug in which the DNS server would incorrectly set the type of a cname reply to a.
|
||||
o Fix a bug where setting the timeout on a bufferevent would take not effect if the event was already pending.
|
||||
o Fix a memory leak when using signals for some event bases; reported by Alexander Drozdov.
|
||||
o Add libevent.vcproj file to distribution to help with Windows build.
|
||||
o Fix a problem with epoll() and reinit; problem report by Alexander Drozdov.
|
||||
o Fix off-by-one errors in devpoll; from Ian Bell
|
||||
o Make event_add not change any state if it fails; reported by Ian Bell.
|
||||
o Do not warn on accept when errno is either EAGAIN or EINTR
|
||||
|
||||
Changes in 1.4.5-stable:
|
||||
o Fix connection keep-alive behavior for HTTP/1.0
|
||||
o Fix use of freed memory in event_reinit; pointed out by Peter Postma
|
||||
o Constify struct timeval * where possible; pointed out by Forest Wilkinson
|
||||
o allow min_heap_erase to be called on removed members; from liusifan.
|
||||
o Rename INPUT and OUTPUT to EVRPC_INPUT and EVRPC_OUTPUT. Retain INPUT/OUTPUT aliases on on-win32 platforms for backwards compatibility.
|
||||
o Do not use SO_REUSEADDR when connecting
|
||||
o Fix Windows build
|
||||
o Fix a bug in event_rpcgen when generated fixed-sized entries
|
||||
|
||||
Changes in 1.4.4-stable:
|
||||
o Correct the documentation on buffer printf functions.
|
||||
o Don't warn on unimplemented epoll_create(): this isn't a problem, just a reason to fall back to poll or select.
|
||||
o Correctly handle timeouts larger than 35 minutes on Linux with epoll.c. This is probably a kernel defect, but we'll have to support old kernels anyway even if it gets fixed.
|
||||
o Fix a potential stack corruption bug in tagging on 64-bit CPUs.
|
||||
o expose bufferevent_setwatermark via header files and fix high watermark on read
|
||||
o fix a bug in bufferevent read water marks and add a test for them
|
||||
o introduce bufferevent_setcb and bufferevent_setfd to allow better manipulation of bufferevents
|
||||
o use libevent's internal timercmp on all platforms, to avoid bugs on old platforms where timercmp(a,b,<=) is buggy.
|
||||
o reduce system calls for getting current time by caching it.
|
||||
o fix evhttp_bind_socket() so that multiple sockets can be bound by the same http server.
|
||||
o Build test directory correctly with CPPFLAGS set.
|
||||
o Fix build under Visual C++ 2005.
|
||||
o Expose evhttp_accept_socket() API.
|
||||
o Merge windows gettimeofday() replacement into a new evutil_gettimeofday() function.
|
||||
o Fix autoconf script behavior on IRIX.
|
||||
o Make sure winsock2.h include always comes before windows.h include.
|
||||
|
||||
Changes in 1.4.3-stable:
|
||||
o include Content-Length in reply for HTTP/1.0 requests with keep-alive
|
||||
o Patch from Tani Hosokawa: make some functions in http.c threadsafe.
|
||||
o Do not free the kqop file descriptor in other processes, also allow it to be 0; from Andrei Nigmatulin
|
||||
o make event_rpcgen.py generate code include event-config.h; reported by Sam Banks.
|
||||
o make event methods static so that they are not exported; from Andrei Nigmatulin
|
||||
o make RPC replies use application/octet-stream as mime type
|
||||
o do not delete uninitialized timeout event in evdns
|
||||
|
||||
Changes in 1.4.2-rc:
|
||||
o remove pending timeouts on event_base_free()
|
||||
o also check EAGAIN for Solaris' event ports; from W.C.A. Wijngaards
|
||||
o devpoll and evport need reinit; tested by W.C.A Wijngaards
|
||||
o event_base_get_method; from Springande Ulv
|
||||
o Send CRLF after each chunk in HTTP output, for compliance with RFC2626. Patch from "propanbutan". Fixes bug 1894184.
|
||||
o Add a int64_t parsing function, with unit tests, so we can apply Scott Lamb's fix to allow large HTTP values.
|
||||
o Use a 64-bit field to hold HTTP content-lengths. Patch from Scott Lamb.
|
||||
o Allow regression code to build even without Python installed
|
||||
o remove NDEBUG ifdefs from evdns.c
|
||||
o update documentation of event_loop and event_base_loop; from Tani Hosokawa.
|
||||
o detect integer types properly on platforms without stdint.h
|
||||
o Remove "AM_MAINTAINER_MODE" declaration in configure.in: now makefiles and configure should get re-generated automatically when Makefile.am or configure.in chanes.
|
||||
o do not insert event into list when evsel->add fails
|
||||
|
||||
Changes in 1.4.1-beta:
|
||||
o free minheap on event_base_free(); from Christopher Layne
|
||||
o debug cleanups in signal.c; from Christopher Layne
|
||||
o provide event_base_new() that does not set the current_base global
|
||||
o bufferevent_write now uses a const source argument; report from Charles Kerr
|
||||
o better documentation for event_base_loopexit; from Scott Lamb.
|
||||
o Make kqueue have the same behavior as other backends when a signal is caught between event_add() and event_loop(). Previously, it would catch and ignore such signals.
|
||||
o Make kqueue restore signal handlers correctly when event_del() is called.
|
||||
o provide event_reinit() to reintialize an event_base after fork
|
||||
o small improvements to evhttp documentation
|
||||
o always generate Date and Content-Length headers for HTTP/1.1 replies
|
||||
o set the correct event base for HTTP close events
|
||||
o New function, event_{base_}loopbreak. Like event_loopexit, it makes an event loop stop executing and return. Unlike event_loopexit, it keeps subsequent pending events from getting executed. Patch from Scott Lamb
|
||||
o Removed obsoleted recalc code
|
||||
o pull setters/getters out of RPC structures into a base class to which we just need to store a pointer; this reduces the memory footprint of these structures.
|
||||
o fix a bug with event_rpcgen for integers
|
||||
o move EV_PERSIST handling out of the event backends
|
||||
o support for 32-bit tag numbers in rpc structures; this is wire compatible, but changes the API slightly.
|
||||
o prefix {encode,decode}_tag functions with evtag to avoid collisions
|
||||
o Correctly handle DNS replies with no answers set (Fixes bug 1846282)
|
||||
o The configure script now takes an --enable-gcc-warnigns option that turns on many optional gcc warnings. (Nick has been building with these for a while, but they might be useful to other developers.)
|
||||
o When building with GCC, use the "format" attribute to verify type correctness of calls to printf-like functions.
|
||||
o removed linger from http server socket; reported by Ilya Martynov
|
||||
o allow \r or \n individually to separate HTTP headers instead of the standard "\r\n"; from Charles Kerr.
|
||||
o demote most http warnings to debug messages
|
||||
o Fix Solaris compilation; from Magne Mahre
|
||||
o Add a "Date" header to HTTP responses, as required by HTTP 1.1.
|
||||
o Support specifying the local address of an evhttp_connection using set_local_address
|
||||
o Fix a memory leak in which failed HTTP connections would not free the request object
|
||||
o Make adding of array members in event_rpcgen more efficient, but doubling memory allocation
|
||||
o Fix a memory leak in the DNS server
|
||||
o Fix compilation when DNS_USE_OPENSSL_FOR_ID is enabled
|
||||
o Fix buffer size and string generation in evdns_resolve_reverse_ipv6().
|
||||
o Respond to nonstandard DNS queries with "NOTIMPL" rather than by ignoring them.
|
||||
o In DNS responses, the CD flag should be preserved, not the TC flag.
|
||||
o Fix http.c to compile properly with USE_DEBUG; from Christopher Layne
|
||||
o Handle NULL timeouts correctly on Solaris; from Trond Norbye
|
||||
o Recalculate pending events properly when reallocating event array on Solaris; from Trond Norbye
|
||||
o Add Doxygen documentation to header files; from Mark Heily
|
||||
o Add a evdns_set_transaction_id_fn() function to override the default
|
||||
transaction ID generation code.
|
||||
o Add an evutil module (with header evutil.h) to implement our standard cross-platform hacks, on the theory that somebody else would like to use them too.
|
||||
o Fix signals implementation on windows.
|
||||
o Fix http module on windows to close sockets properly.
|
||||
o Make autogen.sh script run correctly on systems where /bin/sh isn't bash. (Patch from Trond Norbye, rewritten by Hagne Mahre and then Hannah Schroeter.)
|
||||
o Skip calling gettime() in timeout_process if we are not in fact waiting for any events. (Patch from Trond Norbye)
|
||||
o Make test subdirectory compile under mingw.
|
||||
o Fix win32 buffer.c behavior so that it is correct for sockets (which do not like ReadFile and WriteFile).
|
||||
o Make the test.sh script run unit tests for the evpoll method.
|
||||
o Make the entire evdns.h header enclosed in "extern C" as appropriate.
|
||||
o Fix implementation of strsep on platforms that lack it
|
||||
o Fix implementation of getaddrinfo on platforms that lack it; mainly, this will make Windows http.c work better. Original patch by Lubomir Marinov.
|
||||
o Fix evport implementation: port_disassociate called on unassociated events resulting in bogus errors; more efficient memory management; from Trond Norbye and Prakash Sangappa
|
||||
o support for hooks on rpc input and output; can be used to implement rpc independent processing such as compression or authentication.
|
||||
o use a min heap instead of a red-black tree for timeouts; as a result finding the min is a O(1) operation now; from Maxim Yegorushkin
|
||||
o associate an event base with an rpc pool
|
||||
o added two additional libraries: libevent_core and libevent_extra in addition to the regular libevent. libevent_core contains only the event core whereas libevent_extra contains dns, http and rpc support
|
||||
o Begin using libtool's library versioning support correctly. If we don't mess up, this will more or less guarantee binaries linked against old versions of libevent continue working when we make changes to libevent that do not break backward compatibility.
|
||||
o Fix evhttp.h compilation when TAILQ_ENTRY is not defined.
|
||||
o Small code cleanups in epoll_dispatch().
|
||||
o Increase the maximum number of addresses read from a packet in evdns to 32.
|
||||
o Remove support for the rtsig method: it hasn't compiled for a while, and nobody seems to miss it very much. Let us know if there's a good reason to put it back in.
|
||||
o Rename the "class" field in evdns_server_request to dns_question_class, so that it won't break compilation under C++. Use a macro so that old code won't break. Mark the macro as deprecated.
|
||||
o Fix DNS unit tests so that having a DNS server with broken IPv6 support is no longer cause for aborting the unit tests.
|
||||
o Make event_base_free() succeed even if there are pending non-internal events on a base. This may still leak memory and fds, but at least it no longer crashes.
|
||||
o Post-process the config.h file into a new, installed event-config.h file that we can install, and whose macros will be safe to include in header files.
|
||||
o Remove the long-deprecated acconfig.h file.
|
||||
o Do not require #include <sys/types.h> before #include <event.h>.
|
||||
o Add new evutil_timer* functions to wrap (or replace) the regular timeval manipulation functions.
|
||||
o Fix many build issues when using the Microsoft C compiler.
|
||||
o Remove a bash-ism in autogen.sh
|
||||
o When calling event_del on a signal, restore the signal handler's previous value rather than setting it to SIG_DFL. Patch from Christopher Layne.
|
||||
o Make the logic for active events work better with internal events; patch from Christopher Layne.
|
||||
o We do not need to specially remove a timeout before calling event_del; patch from Christopher Layne.
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -239,7 +239,7 @@ INCLUDE_FILE_PATTERNS =
|
|||
# undefined via #undef or recursively expanded use the := operator
|
||||
# instead of the = operator.
|
||||
|
||||
PREDEFINED = TAILQ_ENTRY RB_ENTRY _EVENT_DEFINED_TQENTRY _EVENT_IN_DOXYGEN
|
||||
PREDEFINED = TAILQ_ENTRY RB_ENTRY EVENT_DEFINED_TQENTRY_ EVENT_IN_DOXYGEN_
|
||||
|
||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
|
||||
# this tag can be used to specify a list of macro names that should be expanded.
|
||||
|
|
|
@ -72,3 +72,28 @@ The arc4module is available under the following, sometimes called the
|
|||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
==============================
|
||||
|
||||
The Windows timer code is based on code from libutp, which is
|
||||
distributed under this license, sometimes called the "MIT" license.
|
||||
|
||||
|
||||
Copyright (c) 2010 BitTorrent, 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.
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
# See LICENSE for copying information.
|
||||
|
||||
# 'foreign' means that we're not enforcing GNU package rules strictly.
|
||||
# '1.7' means that we need automake 1.7 or later (and we do).
|
||||
AUTOMAKE_OPTIONS = foreign 1.7
|
||||
# '1.9' means that we need automake 1.9 or later (and we do).
|
||||
AUTOMAKE_OPTIONS = foreign 1.9 subdir-objects
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
|
@ -18,7 +18,7 @@ ACLOCAL_AMFLAGS = -I m4
|
|||
# will increment for each series until we revise our interfaces enough
|
||||
# that we can seriously expect ABI compatibility between series.
|
||||
#
|
||||
RELEASE = -release 2.0
|
||||
RELEASE = -release 2.1
|
||||
|
||||
# This is the version info for the libevent binary API. It has three
|
||||
# numbers:
|
||||
|
@ -38,7 +38,7 @@ RELEASE = -release 2.0
|
|||
#
|
||||
# Once an RC is out, DO NOT MAKE ANY ABI-BREAKING CHANGES IN THAT SERIES
|
||||
# UNLESS YOU REALLY REALLY HAVE TO.
|
||||
VERSION_INFO = 6:10:1
|
||||
VERSION_INFO = 6:2:0
|
||||
|
||||
# History: RELEASE VERSION_INFO
|
||||
# 2.0.1-alpha -- 2.0 1:0:0
|
||||
|
@ -62,11 +62,16 @@ VERSION_INFO = 6:10:1
|
|||
# 2.0.19-stable-- 2.0 6:7:1 (No ABI change)
|
||||
# 2.0.20-stable-- 2.0 6:8:1 (No ABI change)
|
||||
# 2.0.21-stable-- 2.0 6:9:1 (No ABI change)
|
||||
# 2.0.22-stable-- 2.0 6:10:1 (No ABI change)
|
||||
#
|
||||
# For Libevent 2.1:
|
||||
# 2.1.1-alpha -- 2.1 1:0:0
|
||||
|
||||
# 2.1.2-alpha -- 2.1 1:0:0 (should have been 2:0:1)
|
||||
# 2.1.3-alpha -- 2.1 3:0:0 (ABI changed slightly)
|
||||
# 2.1.4-alpha -- 2.1 4:0:0 (ABI changed slightly)
|
||||
# 2.1.5-beta -- 2.1 5:0:0 (ABI changed slightly)
|
||||
# 2.1.6-beta -- 2.1 6:0:0 (ABI changed slightly)
|
||||
# 2.1.7-beta -- 2.1 6:1:0 (ABI changed slightly)
|
||||
# 2.1.8-stable-- 2.1 6:2:0 (ABI changed slightly)
|
||||
|
||||
# ABI version history for this package effectively restarts every time
|
||||
# we change RELEASE. Version 1.4.x had RELEASE of 1.4.
|
||||
|
@ -91,23 +96,26 @@ dist_bin_SCRIPTS = event_rpcgen.py
|
|||
endif
|
||||
|
||||
pkgconfigdir=$(libdir)/pkgconfig
|
||||
LIBEVENT_PKGCONFIG=libevent.pc
|
||||
LIBEVENT_PKGCONFIG=libevent.pc libevent_core.pc libevent_extra.pc
|
||||
|
||||
# These sources are conditionally added by configure.in or conditionally
|
||||
# These sources are conditionally added by configure.ac or conditionally
|
||||
# included from other files.
|
||||
PLATFORM_DEPENDENT_SRC = \
|
||||
epoll_sub.c \
|
||||
arc4random.c
|
||||
arc4random.c \
|
||||
epoll_sub.c
|
||||
|
||||
EXTRA_DIST = \
|
||||
ChangeLog-1.4 \
|
||||
ChangeLog-2.0 \
|
||||
Doxyfile \
|
||||
LICENSE \
|
||||
Makefile.nmake test/Makefile.nmake \
|
||||
autogen.sh \
|
||||
event_rpcgen.py \
|
||||
libevent.pc.in \
|
||||
make-event-config.sed \
|
||||
Doxyfile \
|
||||
whatsnew-2.0.txt \
|
||||
Makefile.nmake test/Makefile.nmake \
|
||||
whatsnew-2.1.txt \
|
||||
$(PLATFORM_DEPENDENT_SRC)
|
||||
|
||||
LIBEVENT_LIBS_LA = libevent.la libevent_core.la libevent_extra.la
|
||||
|
@ -127,14 +135,27 @@ else
|
|||
noinst_LTLIBRARIES = $(LIBEVENT_LIBS_LA)
|
||||
endif
|
||||
|
||||
SUBDIRS = . include sample test
|
||||
EXTRA_SOURCE=
|
||||
noinst_HEADERS=
|
||||
noinst_PROGRAMS=
|
||||
EXTRA_PROGRAMS=
|
||||
CLEANFILES=
|
||||
DISTCLEANFILES=
|
||||
BUILT_SOURCES =
|
||||
include include/include.am
|
||||
include sample/include.am
|
||||
include test/include.am
|
||||
|
||||
if BUILD_WIN32
|
||||
|
||||
SYS_LIBS = -lws2_32 -lshell32 -ladvapi32
|
||||
SYS_SRC = win32select.c evthread_win32.c buffer_iocp.c event_iocp.c \
|
||||
SYS_SRC = win32select.c buffer_iocp.c event_iocp.c \
|
||||
bufferevent_async.c
|
||||
SYS_INCLUDES = -IWIN32-Code
|
||||
SYS_INCLUDES = -IWIN32-Code -IWIN32-Code/nmake
|
||||
|
||||
if THREADS
|
||||
SYS_SRC += evthread_win32.c
|
||||
endif
|
||||
|
||||
else
|
||||
|
||||
|
@ -144,6 +165,9 @@ SYS_INCLUDES =
|
|||
|
||||
endif
|
||||
|
||||
if STRLCPY_IMPL
|
||||
SYS_SRC += strlcpy.c
|
||||
endif
|
||||
if SELECT_BACKEND
|
||||
SYS_SRC += select.c
|
||||
endif
|
||||
|
@ -166,18 +190,35 @@ if SIGNAL_SUPPORT
|
|||
SYS_SRC += signal.c
|
||||
endif
|
||||
|
||||
BUILT_SOURCES = include/event2/event-config.h
|
||||
BUILT_SOURCES += include/event2/event-config.h
|
||||
|
||||
include/event2/event-config.h: config.h make-event-config.sed
|
||||
test -d include/event2 || $(MKDIR_P) include/event2
|
||||
$(SED) -f $(srcdir)/make-event-config.sed < config.h > $@T
|
||||
mv -f $@T $@
|
||||
$(AM_V_GEN)test -d include/event2 || $(MKDIR_P) include/event2
|
||||
$(AM_V_at)$(SED) -f $(srcdir)/make-event-config.sed < config.h > $@T
|
||||
$(AM_V_at)mv -f $@T $@
|
||||
|
||||
CORE_SRC = event.c evthread.c buffer.c \
|
||||
bufferevent.c bufferevent_sock.c bufferevent_filter.c \
|
||||
bufferevent_pair.c listener.c bufferevent_ratelim.c \
|
||||
evmap.c log.c evutil.c evutil_rand.c strlcpy.c $(SYS_SRC)
|
||||
EXTRA_SRC = event_tagging.c http.c evdns.c evrpc.c
|
||||
CORE_SRC = \
|
||||
buffer.c \
|
||||
bufferevent.c \
|
||||
bufferevent_filter.c \
|
||||
bufferevent_pair.c \
|
||||
bufferevent_ratelim.c \
|
||||
bufferevent_sock.c \
|
||||
event.c \
|
||||
evmap.c \
|
||||
evthread.c \
|
||||
evutil.c \
|
||||
evutil_rand.c \
|
||||
evutil_time.c \
|
||||
listener.c \
|
||||
log.c \
|
||||
$(SYS_SRC)
|
||||
|
||||
EXTRAS_SRC = \
|
||||
evdns.c \
|
||||
event_tagging.c \
|
||||
evrpc.c \
|
||||
http.c
|
||||
|
||||
if BUILD_WITH_NO_UNDEFINED
|
||||
NO_UNDEFINED = -no-undefined
|
||||
|
@ -189,7 +230,7 @@ endif
|
|||
|
||||
GENERIC_LDFLAGS = -version-info $(VERSION_INFO) $(RELEASE) $(NO_UNDEFINED)
|
||||
|
||||
libevent_la_SOURCES = $(CORE_SRC) $(EXTRA_SRC)
|
||||
libevent_la_SOURCES = $(CORE_SRC) $(EXTRAS_SRC)
|
||||
libevent_la_LIBADD = @LTLIBOBJS@ $(SYS_LIBS)
|
||||
libevent_la_LDFLAGS = $(GENERIC_LDFLAGS)
|
||||
|
||||
|
@ -203,7 +244,7 @@ libevent_pthreads_la_LIBADD = $(MAYBE_CORE)
|
|||
libevent_pthreads_la_LDFLAGS = $(GENERIC_LDFLAGS)
|
||||
endif
|
||||
|
||||
libevent_extra_la_SOURCES = $(EXTRA_SRC)
|
||||
libevent_extra_la_SOURCES = $(EXTRAS_SRC)
|
||||
libevent_extra_la_LIBADD = $(MAYBE_CORE) $(SYS_LIBS)
|
||||
libevent_extra_la_LDFLAGS = $(GENERIC_LDFLAGS)
|
||||
|
||||
|
@ -211,20 +252,45 @@ if OPENSSL
|
|||
libevent_openssl_la_SOURCES = bufferevent_openssl.c
|
||||
libevent_openssl_la_LIBADD = $(MAYBE_CORE) $(OPENSSL_LIBS)
|
||||
libevent_openssl_la_LDFLAGS = $(GENERIC_LDFLAGS)
|
||||
libevent_openssl_la_CPPFLAGS = $(AM_CPPFLAGS) $(OPENSSL_INCS)
|
||||
endif
|
||||
|
||||
noinst_HEADERS = util-internal.h mm-internal.h ipv6-internal.h \
|
||||
evrpc-internal.h strlcpy-internal.h evbuffer-internal.h \
|
||||
bufferevent-internal.h http-internal.h event-internal.h \
|
||||
evthread-internal.h ht-internal.h defer-internal.h \
|
||||
minheap-internal.h log-internal.h evsignal-internal.h evmap-internal.h \
|
||||
changelist-internal.h iocp-internal.h \
|
||||
ratelim-internal.h \
|
||||
WIN32-Code/event2/event-config.h \
|
||||
WIN32-Code/tree.h \
|
||||
compat/sys/queue.h
|
||||
noinst_HEADERS += \
|
||||
WIN32-Code/nmake/evconfig-private.h \
|
||||
WIN32-Code/nmake/event2/event-config.h \
|
||||
WIN32-Code/tree.h \
|
||||
bufferevent-internal.h \
|
||||
changelist-internal.h \
|
||||
compat/sys/queue.h \
|
||||
defer-internal.h \
|
||||
epolltable-internal.h \
|
||||
evbuffer-internal.h \
|
||||
evconfig-private.h \
|
||||
event-internal.h \
|
||||
evmap-internal.h \
|
||||
evrpc-internal.h \
|
||||
evsignal-internal.h \
|
||||
evthread-internal.h \
|
||||
ht-internal.h \
|
||||
http-internal.h \
|
||||
iocp-internal.h \
|
||||
ipv6-internal.h \
|
||||
kqueue-internal.h \
|
||||
log-internal.h \
|
||||
minheap-internal.h \
|
||||
mm-internal.h \
|
||||
ratelim-internal.h \
|
||||
ratelim-internal.h \
|
||||
strlcpy-internal.h \
|
||||
time-internal.h \
|
||||
util-internal.h
|
||||
|
||||
EVENT1_HDRS = event.h evhttp.h evdns.h evrpc.h evutil.h
|
||||
EVENT1_HDRS = \
|
||||
include/evdns.h \
|
||||
include/event.h \
|
||||
include/evhttp.h \
|
||||
include/evrpc.h \
|
||||
include/evutil.h
|
||||
|
||||
if INSTALL_LIBEVENT
|
||||
include_HEADERS = $(EVENT1_HDRS)
|
||||
|
@ -240,5 +306,5 @@ doxygen: FORCE
|
|||
doxygen $(srcdir)/Doxyfile
|
||||
FORCE:
|
||||
|
||||
DISTCLEANFILES = *~ libevent.pc ./include/event2/event-config.h
|
||||
DISTCLEANFILES += *~ libevent.pc libevent_core.pc libevent_extra.pc ./include/event2/event-config.h
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,8 +1,26 @@
|
|||
# WATCH OUT! This makefile is a work in progress. It is probably missing
|
||||
# tons of important things. DO NOT RELY ON IT TO BUILD A GOOD LIBEVENT.
|
||||
# WATCH OUT! This makefile is a work in progress. -*- makefile -*-
|
||||
#
|
||||
# I'm not very knowledgeable about MSVC and nmake beyond their most basic
|
||||
# aspects. If anything here looks wrong to you, please let me know.
|
||||
|
||||
# If OPENSSL_DIR is not set, builds without OpenSSL support. If you want
|
||||
# OpenSSL support, you can set the OPENSSL_DIR variable to where you
|
||||
# installed OpenSSL. This can be done in the environment:
|
||||
# set OPENSSL_DIR=c:\openssl
|
||||
# Or on the nmake command line:
|
||||
# nmake OPENSSL_DIR=C:\openssl -f Makefile.nmake
|
||||
# Or by uncommenting the following line here in the makefile...
|
||||
|
||||
# OPENSSL_DIR=c:\openssl
|
||||
|
||||
!IFDEF OPENSSL_DIR
|
||||
SSL_CFLAGS=/I$(OPENSSL_DIR)\include /DEVENT__HAVE_OPENSSL
|
||||
!ELSE
|
||||
SSL_CFLAGS=
|
||||
!ENDIF
|
||||
|
||||
# Needed for correctness
|
||||
CFLAGS=/IWIN32-Code /Iinclude /Icompat /DWIN32 /DHAVE_CONFIG_H /I.
|
||||
CFLAGS=/IWIN32-Code /IWIN32-Code/nmake /Iinclude /Icompat /DHAVE_CONFIG_H /I. $(SSL_CFLAGS)
|
||||
|
||||
# For optimization and warnings
|
||||
CFLAGS=$(CFLAGS) /Ox /W3 /wd4996 /nologo
|
||||
|
@ -14,13 +32,21 @@ LIBFLAGS=/nologo
|
|||
CORE_OBJS=event.obj buffer.obj bufferevent.obj bufferevent_sock.obj \
|
||||
bufferevent_pair.obj listener.obj evmap.obj log.obj evutil.obj \
|
||||
strlcpy.obj signal.obj bufferevent_filter.obj evthread.obj \
|
||||
bufferevent_ratelim.obj evutil_rand.obj
|
||||
bufferevent_ratelim.obj evutil_rand.obj evutil_time.obj
|
||||
WIN_OBJS=win32select.obj evthread_win32.obj buffer_iocp.obj \
|
||||
event_iocp.obj bufferevent_async.obj
|
||||
EXTRA_OBJS=event_tagging.obj http.obj evdns.obj evrpc.obj
|
||||
|
||||
ALL_OBJS=$(CORE_OBJS) $(WIN_OBJS) $(EXTRA_OBJS)
|
||||
STATIC_LIBS=libevent_core.lib libevent_extras.lib libevent.lib
|
||||
!IFDEF OPENSSL_DIR
|
||||
SSL_OBJS=bufferevent_openssl.obj
|
||||
SSL_LIBS=libevent_openssl.lib
|
||||
!ELSE
|
||||
SSL_OBJS=
|
||||
SSL_LIBS=
|
||||
!ENDIF
|
||||
|
||||
ALL_OBJS=$(CORE_OBJS) $(WIN_OBJS) $(EXTRA_OBJS) $(SSL_OBJS)
|
||||
STATIC_LIBS=libevent_core.lib libevent_extras.lib libevent.lib $(SSL_LIBS)
|
||||
|
||||
|
||||
all: static_libs tests
|
||||
|
@ -36,12 +62,21 @@ libevent_extras.lib: $(EXTRA_OBJS)
|
|||
libevent.lib: $(CORE_OBJS) $(WIN_OBJS) $(EXTRA_OBJS)
|
||||
lib $(LIBFLAGS) $(CORE_OBJS) $(EXTRA_OBJS) $(WIN_OBJS) /out:libevent.lib
|
||||
|
||||
libevent_openssl.lib: $(SSL_OBJS)
|
||||
lib $(LIBFLAGS) $(SSL_OBJS) /out:libevent_openssl.lib
|
||||
|
||||
clean:
|
||||
del $(ALL_OBJS)
|
||||
del $(STATIC_LIBS)
|
||||
cd test
|
||||
$(MAKE) /F Makefile.nmake clean
|
||||
cd ..
|
||||
|
||||
tests:
|
||||
cd test
|
||||
!IFDEF OPENSSL_DIR
|
||||
$(MAKE) OPENSSL_DIR=$(OPENSSL_DIR) /F Makefile.nmake
|
||||
!ELSE
|
||||
$(MAKE) /F Makefile.nmake
|
||||
!ENDIF
|
||||
cd ..
|
||||
|
|
|
@ -1,198 +0,0 @@
|
|||
0. BUILDING AND INSTALLATION (Briefly)
|
||||
|
||||
$ ./configure
|
||||
$ make
|
||||
$ make verify # (optional)
|
||||
$ sudo make install
|
||||
|
||||
1. BUILDING AND INSTALLATION (In Depth)
|
||||
|
||||
To build libevent, type
|
||||
|
||||
$ ./configure && make
|
||||
|
||||
(If you got libevent from the git repository, you will
|
||||
first need to run the included "autogen.sh" script in order to
|
||||
generate the configure script.)
|
||||
|
||||
You can run the regression tests by running
|
||||
|
||||
$ make verify
|
||||
|
||||
Install as root via
|
||||
|
||||
# make install
|
||||
|
||||
Before, reporting any problems, please run the regression tests.
|
||||
|
||||
To enable the low-level tracing build the library as:
|
||||
|
||||
CFLAGS=-DUSE_DEBUG ./configure [...]
|
||||
|
||||
Standard configure flags should work. In particular, see:
|
||||
|
||||
--disable-shared Only build static libraries
|
||||
--prefix Install all files relative to this directory.
|
||||
|
||||
|
||||
The configure script also supports the following flags:
|
||||
|
||||
--enable-gcc-warnings Enable extra compiler checking with GCC.
|
||||
--disable-malloc-replacement
|
||||
Don't let applications replace our memory
|
||||
management functions
|
||||
--disable-openssl Disable support for OpenSSL encryption.
|
||||
--disable-thread-support Don't support multithreaded environments.
|
||||
|
||||
2. USEFUL LINKS:
|
||||
|
||||
For the latest released version of Libevent, see the official website at
|
||||
http://libevent.org/ .
|
||||
|
||||
There's a pretty good work-in-progress manual up at
|
||||
http://www.wangafu.net/~nickm/libevent-book/ .
|
||||
|
||||
For the latest development versions of Libevent, access our Git repository
|
||||
via
|
||||
"git clone git://levent.git.sourceforge.net/gitroot/levent/libevent"
|
||||
|
||||
You can browse the git repository online at
|
||||
http://levent.git.sourceforge.net/git/gitweb-index.cgi .
|
||||
|
||||
To report bugs, request features, or submit patches to Libevent,
|
||||
use the Sourceforge trackers at
|
||||
https://sourceforge.net/tracker/?group_id=50884 .
|
||||
|
||||
There's also a libevent-users mailing list for talking about Libevent
|
||||
use and development: http://archives.seul.org/libevent/users/
|
||||
|
||||
3. ACKNOWLEDGMENTS
|
||||
|
||||
The following people have helped with suggestions, ideas, code or
|
||||
fixing bugs:
|
||||
|
||||
Arno Bakker
|
||||
Alejo
|
||||
Weston Andros Adamson
|
||||
William Ahern
|
||||
Ivan Andropov
|
||||
Sergey Avseyev
|
||||
Avi Bab
|
||||
Gilad Benjamini
|
||||
Stas Bekman
|
||||
Joachim Bauch
|
||||
Denis Bilenko
|
||||
Julien Blache
|
||||
Kevin Bowling
|
||||
Tomash Brechko
|
||||
Kelly Brock
|
||||
Ralph Castain
|
||||
Adrian Chadd
|
||||
Lawnstein Chan
|
||||
Shuo Chen
|
||||
Ka-Hing Cheung
|
||||
Andrew Cox
|
||||
George Danchev
|
||||
Andrew Danforth
|
||||
Antony Dovgal
|
||||
Ed Day
|
||||
Christopher Davis
|
||||
Mike Davis
|
||||
Mihai Draghicioiu
|
||||
Mark Ellzey
|
||||
Shie Erlich
|
||||
Leonid Evdokimov
|
||||
Juan Pablo Fernandez
|
||||
Christophe Fillot
|
||||
Mike Frysinger
|
||||
Remi Gacogne
|
||||
Alexander von Gernler
|
||||
Artur Grabowski
|
||||
Sebastian Hahn
|
||||
Dave Hart
|
||||
Greg Hazel
|
||||
Michael Herf
|
||||
Savg He
|
||||
Mark Heily
|
||||
Greg Hewgill
|
||||
Andrew Hochhaus
|
||||
Aaron Hopkins
|
||||
Tani Hosokawa
|
||||
Jamie Iles
|
||||
Claudio Jeker
|
||||
Evan Jones
|
||||
George Kadianakis
|
||||
Phua Keat
|
||||
Kevin Ko
|
||||
Brian Koehmstedt
|
||||
Marko Kreen
|
||||
Valery Kyholodov
|
||||
Ross Lagerwall
|
||||
Scott Lamb
|
||||
Christopher Layne
|
||||
Adam Langley
|
||||
Philip Lewis
|
||||
Zhou Li
|
||||
David Libenzi
|
||||
Yan Lin
|
||||
Moshe Litvin
|
||||
Simon Liu
|
||||
Mitchell Livingston
|
||||
Hagne Mahre
|
||||
Lubomir Marinov
|
||||
Abilio Marques
|
||||
Nick Mathewson
|
||||
James Mansion
|
||||
Nicholas Marriott
|
||||
Andrey Matveev
|
||||
Caitlin Mercer
|
||||
Dagobert Michelsen
|
||||
Mansour Moufid
|
||||
Felix Nawothnig
|
||||
Trond Norbye
|
||||
Linus Nordberg
|
||||
Richard Nyberg
|
||||
Jon Oberheide
|
||||
Phil Oleson
|
||||
Dave Pacheco
|
||||
Tassilo von Parseval
|
||||
Catalin Patulea
|
||||
Patrick Pelletier
|
||||
Simon Perreault
|
||||
Pierre Phaneuf
|
||||
Ryan Phillips
|
||||
Dimitre Piskyulev
|
||||
Pavel Plesov
|
||||
Jon Poland
|
||||
Nate R
|
||||
Robert Ransom
|
||||
Bert JW Regeer
|
||||
Peter Rosin
|
||||
Maseeb Abdul Qadir
|
||||
Wang Qin
|
||||
Alex S
|
||||
Hanna Schroeter
|
||||
Ralf Schmitt
|
||||
Mike Smellie
|
||||
Kevin Springborn
|
||||
Harlan Stenn
|
||||
Steve Snyder
|
||||
Dug Song
|
||||
Dongsheng Song
|
||||
Hannes Sowa
|
||||
Ferenc Szalai
|
||||
Brodie Thiesfield
|
||||
Jason Toffaletti
|
||||
Gisle Vanem
|
||||
Bas Verhoeven
|
||||
Constantine Verutin
|
||||
Colin Watt
|
||||
Zack Weinberg
|
||||
Jardel Weyrich
|
||||
Alex
|
||||
Taral
|
||||
propanbutan
|
||||
mmadia
|
||||
|
||||
|
||||
If we have forgotten your name, please contact us.
|
|
@ -0,0 +1,431 @@
|
|||
<p align="center">
|
||||
<img src="https://strcpy.net/libevent3.png" alt="libevent logo"/>
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
[![Appveyor Win32 Build Status](https://ci.appveyor.com/api/projects/status/github/libevent/libevent?branch=master&svg=true)](https://ci.appveyor.com/project/nmathewson/libevent)
|
||||
[![Travis Build Status](https://travis-ci.org/libevent/libevent.svg?branch=master)](https://travis-ci.org/libevent/libevent)
|
||||
[![Coverage Status](https://coveralls.io/repos/github/libevent/libevent/badge.svg)](https://coveralls.io/github/libevent/libevent)
|
||||
|
||||
|
||||
|
||||
# 0. BUILDING AND INSTALLATION (Briefly)
|
||||
|
||||
## Autoconf
|
||||
|
||||
$ ./configure
|
||||
$ make
|
||||
$ make verify # (optional)
|
||||
$ sudo make install
|
||||
|
||||
## Cmake (General)
|
||||
|
||||
|
||||
The following Libevent specific Cmake variables are as follows (the values being
|
||||
the default).
|
||||
|
||||
```
|
||||
# Installation directory for executables
|
||||
EVENT_INSTALL_BIN_DIR:PATH=bin
|
||||
|
||||
# Installation directory for CMake files
|
||||
EVENT_INSTALL_CMAKE_DIR:PATH=lib/cmake/libevent
|
||||
|
||||
## Installation directory for header files
|
||||
EVENT_INSTALL_INCLUDE_DIR:PATH=include
|
||||
|
||||
## Installation directory for libraries
|
||||
EVENT_INSTALL_LIB_DIR:PATH=lib
|
||||
|
||||
## Define if libevent should be built with shared libraries instead of archives
|
||||
EVENT__BUILD_SHARED_LIBRARIES:BOOL=OFF
|
||||
|
||||
# Enable running gcov to get a test coverage report (only works with
|
||||
# GCC/CLang). Make sure to enable -DCMAKE_BUILD_TYPE=Debug as well.
|
||||
EVENT__COVERAGE:BOOL=OFF
|
||||
|
||||
# Defines if libevent should build without the benchmark exectuables
|
||||
EVENT__DISABLE_BENCHMARK:BOOL=OFF
|
||||
|
||||
# Define if libevent should build without support for a debug mode
|
||||
EVENT__DISABLE_DEBUG_MODE:BOOL=OFF
|
||||
|
||||
# Define if libevent should not allow replacing the mm functions
|
||||
EVENT__DISABLE_MM_REPLACEMENT:BOOL=OFF
|
||||
|
||||
# Define if libevent should build without support for OpenSSL encrpytion
|
||||
EVENT__DISABLE_OPENSSL:BOOL=OFF
|
||||
|
||||
# Disable the regress tests
|
||||
EVENT__DISABLE_REGRESS:BOOL=OFF
|
||||
|
||||
# Disable sample files
|
||||
EVENT__DISABLE_SAMPLES:BOOL=OFF
|
||||
|
||||
# If tests should be compiled or not
|
||||
EVENT__DISABLE_TESTS:BOOL=OFF
|
||||
|
||||
# Define if libevent should not be compiled with thread support
|
||||
EVENT__DISABLE_THREAD_SUPPORT:BOOL=OFF
|
||||
|
||||
# Enables verbose debugging
|
||||
EVENT__ENABLE_VERBOSE_DEBUG:BOOL=OFF
|
||||
|
||||
# When crosscompiling forces running a test program that verifies that Kqueue
|
||||
# works with pipes. Note that this requires you to manually run the test program
|
||||
# on the the cross compilation target to verify that it works. See cmake
|
||||
# documentation for try_run for more details
|
||||
EVENT__FORCE_KQUEUE_CHECK:BOOL=OFF
|
||||
|
||||
# set EVENT_STAGE_VERSION
|
||||
EVENT__STAGE_VERSION:STRING=beta
|
||||
```
|
||||
|
||||
__More variables can be found by running `cmake -LAH <sourcedir_path>`__
|
||||
|
||||
|
||||
## CMake (Windows)
|
||||
|
||||
Install CMake: <http://www.cmake.org>
|
||||
|
||||
|
||||
$ md build && cd build
|
||||
$ cmake -G "Visual Studio 10" .. # Or whatever generator you want to use cmake --help for a list.
|
||||
$ start libevent.sln
|
||||
|
||||
## CMake (Unix)
|
||||
|
||||
$ mkdir build && cd build
|
||||
$ cmake .. # Default to Unix Makefiles.
|
||||
$ make
|
||||
$ make verify # (optional)
|
||||
|
||||
|
||||
# 1. BUILDING AND INSTALLATION (In Depth)
|
||||
|
||||
## Autoconf
|
||||
|
||||
To build libevent, type
|
||||
|
||||
$ ./configure && make
|
||||
|
||||
|
||||
(If you got libevent from the git repository, you will
|
||||
first need to run the included "autogen.sh" script in order to
|
||||
generate the configure script.)
|
||||
|
||||
You can run the regression tests by running
|
||||
|
||||
$ make verify
|
||||
|
||||
Install as root via
|
||||
|
||||
$ make install
|
||||
|
||||
Before reporting any problems, please run the regression tests.
|
||||
|
||||
To enable the low-level tracing build the library as:
|
||||
|
||||
$ CFLAGS=-DUSE_DEBUG ./configure [...]
|
||||
|
||||
Standard configure flags should work. In particular, see:
|
||||
|
||||
--disable-shared Only build static libraries
|
||||
--prefix Install all files relative to this directory.
|
||||
|
||||
|
||||
The configure script also supports the following flags:
|
||||
|
||||
--enable-gcc-warnings Enable extra compiler checking with GCC.
|
||||
--disable-malloc-replacement
|
||||
Don't let applications replace our memory
|
||||
management functions
|
||||
--disable-openssl Disable support for OpenSSL encryption.
|
||||
--disable-thread-support Don't support multithreaded environments.
|
||||
|
||||
## CMake (Windows)
|
||||
|
||||
(Note that autoconf is currently the most mature and supported build
|
||||
enviroment for libevent; the cmake instructions here are new and
|
||||
experimental, though they _should_ be solid. We hope that cmake will
|
||||
still be supported in future versions of Libevent, and will try to
|
||||
make sure that happens.)
|
||||
|
||||
First of all install <http://www.cmake.org>.
|
||||
|
||||
To build libevent using Microsoft Visual studio open the "Visual Studio Command prompt" and type:
|
||||
|
||||
```
|
||||
$ cd <libevent source dir>
|
||||
$ mkdir build && cd build
|
||||
$ cmake -G "Visual Studio 10" .. # Or whatever generator you want to use cmake --help for a list.
|
||||
$ start libevent.sln
|
||||
```
|
||||
|
||||
In the above, the ".." refers to the dir containing the Libevent source code.
|
||||
You can build multiple versions (with different compile time settings) from the same source tree
|
||||
by creating other build directories.
|
||||
|
||||
It is highly recommended to build "out of source" when using
|
||||
CMake instead of "in source" like the normal behaviour of autoconf for this reason.
|
||||
|
||||
The "NMake Makefiles" CMake generator can be used to build entirely via the command line.
|
||||
|
||||
To get a list of settings available for the project you can type:
|
||||
|
||||
```
|
||||
$ cmake -LH ..
|
||||
```
|
||||
|
||||
### GUI
|
||||
|
||||
CMake also provides a GUI that lets you specify the source directory and output (binary) directory
|
||||
that the build should be placed in.
|
||||
|
||||
### OpenSSL support
|
||||
|
||||
To build Libevent with OpenSSL support you will need to have OpenSSL binaries available when building,
|
||||
these can be found here: <http://www.openssl.org/related/binaries.html>
|
||||
|
||||
# 2. USEFUL LINKS:
|
||||
|
||||
For the latest released version of Libevent, see the official website at
|
||||
<http://libevent.org/> .
|
||||
|
||||
There's a pretty good work-in-progress manual up at
|
||||
<http://www.wangafu.net/~nickm/libevent-book/> .
|
||||
|
||||
For the latest development versions of Libevent, access our Git repository
|
||||
via
|
||||
|
||||
```
|
||||
$ git clone https://github.com/libevent/libevent.git
|
||||
```
|
||||
|
||||
You can browse the git repository online at:
|
||||
|
||||
<https://github.com/libevent/Libevent>
|
||||
|
||||
To report bugs, issues, or ask for new features:
|
||||
|
||||
__Patches__: https://github.com/libevent/libevent/pulls
|
||||
> OK, those are not really _patches_ You fork, modify, and hit the "Create Pull Request" button.
|
||||
> You can still submit normal git patchs via the mailing list.
|
||||
|
||||
__Bugs, Features [RFC], and Issus__: https://github.com/libevent/libevent/issues
|
||||
> Or you can do it via the mailing list.
|
||||
|
||||
There's also a libevent-users mailing list for talking about Libevent
|
||||
use and development:
|
||||
|
||||
<http://archives.seul.org/libevent/users/>
|
||||
|
||||
# 3. ACKNOWLEDGMENTS
|
||||
|
||||
The following people have helped with suggestions, ideas, code or
|
||||
fixing bugs:
|
||||
|
||||
* Samy Al Bahra
|
||||
* Antony Antony
|
||||
* Jacob Appelbaum
|
||||
* Arno Bakker
|
||||
* Weston Andros Adamson
|
||||
* William Ahern
|
||||
* Ivan Andropov
|
||||
* Sergey Avseyev
|
||||
* Avi Bab
|
||||
* Joachim Bauch
|
||||
* Andrey Belobrov
|
||||
* Gilad Benjamini
|
||||
* Stas Bekman
|
||||
* Denis Bilenko
|
||||
* Julien Blache
|
||||
* Kevin Bowling
|
||||
* Tomash Brechko
|
||||
* Kelly Brock
|
||||
* Ralph Castain
|
||||
* Adrian Chadd
|
||||
* Lawnstein Chan
|
||||
* Shuo Chen
|
||||
* Ka-Hing Cheung
|
||||
* Andrew Cox
|
||||
* Paul Croome
|
||||
* George Danchev
|
||||
* Andrew Danforth
|
||||
* Ed Day
|
||||
* Christopher Davis
|
||||
* Mike Davis
|
||||
* Frank Denis
|
||||
* Antony Dovgal
|
||||
* Mihai Draghicioiu
|
||||
* Alexander Drozdov
|
||||
* Mark Ellzey
|
||||
* Shie Erlich
|
||||
* Leonid Evdokimov
|
||||
* Juan Pablo Fernandez
|
||||
* Christophe Fillot
|
||||
* Mike Frysinger
|
||||
* Remi Gacogne
|
||||
* Artem Germanov
|
||||
* Alexander von Gernler
|
||||
* Diego Giagio
|
||||
* Artur Grabowski
|
||||
* Diwaker Gupta
|
||||
* Kuldeep Gupta
|
||||
* Sebastian Hahn
|
||||
* Dave Hart
|
||||
* Greg Hazel
|
||||
* Nicholas Heath
|
||||
* Michael Herf
|
||||
* Savg He
|
||||
* Mark Heily
|
||||
* Maxime Henrion
|
||||
* Michael Herf
|
||||
* Greg Hewgill
|
||||
* Andrew Hochhaus
|
||||
* Aaron Hopkins
|
||||
* Tani Hosokawa
|
||||
* Jamie Iles
|
||||
* Xiuqiang Jiang
|
||||
* Claudio Jeker
|
||||
* Evan Jones
|
||||
* Marcin Juszkiewicz
|
||||
* George Kadianakis
|
||||
* Makoto Kato
|
||||
* Phua Keat
|
||||
* Azat Khuzhin
|
||||
* Alexander Klauer
|
||||
* Kevin Ko
|
||||
* Brian Koehmstedt
|
||||
* Marko Kreen
|
||||
* Ondřej Kuzník
|
||||
* Valery Kyholodov
|
||||
* Ross Lagerwall
|
||||
* Scott Lamb
|
||||
* Christopher Layne
|
||||
* Adam Langley
|
||||
* Graham Leggett
|
||||
* Volker Lendecke
|
||||
* Philip Lewis
|
||||
* Zhou Li
|
||||
* David Libenzi
|
||||
* Yan Lin
|
||||
* Moshe Litvin
|
||||
* Simon Liu
|
||||
* Mitchell Livingston
|
||||
* Hagne Mahre
|
||||
* Lubomir Marinov
|
||||
* Abilio Marques
|
||||
* Nicolas Martyanoff
|
||||
* Abel Mathew
|
||||
* Nick Mathewson
|
||||
* James Mansion
|
||||
* Nicholas Marriott
|
||||
* Andrey Matveev
|
||||
* Caitlin Mercer
|
||||
* Dagobert Michelsen
|
||||
* Andrea Montefusco
|
||||
* Mansour Moufid
|
||||
* Mina Naguib
|
||||
* Felix Nawothnig
|
||||
* Trond Norbye
|
||||
* Linus Nordberg
|
||||
* Richard Nyberg
|
||||
* Jon Oberheide
|
||||
* John Ohl
|
||||
* Phil Oleson
|
||||
* Alexey Ozeritsky
|
||||
* Dave Pacheco
|
||||
* Derrick Pallas
|
||||
* Tassilo von Parseval
|
||||
* Catalin Patulea
|
||||
* Patrick Pelletier
|
||||
* Simon Perreault
|
||||
* Dan Petro
|
||||
* Pierre Phaneuf
|
||||
* Amarin Phaosawasdi
|
||||
* Ryan Phillips
|
||||
* Dimitre Piskyulev
|
||||
* Pavel Plesov
|
||||
* Jon Poland
|
||||
* Roman Puls
|
||||
* Nate R
|
||||
* Robert Ransom
|
||||
* Balint Reczey
|
||||
* Bert JW Regeer
|
||||
* Nate Rosenblum
|
||||
* Peter Rosin
|
||||
* Maseeb Abdul Qadir
|
||||
* Wang Qin
|
||||
* Alex S
|
||||
* Gyepi Sam
|
||||
* Hanna Schroeter
|
||||
* Ralf Schmitt
|
||||
* Mike Smellie
|
||||
* Steve Snyder
|
||||
* Nir Soffer
|
||||
* Dug Song
|
||||
* Dongsheng Song
|
||||
* Hannes Sowa
|
||||
* Joakim Soderberg
|
||||
* Joseph Spadavecchia
|
||||
* Kevin Springborn
|
||||
* Harlan Stenn
|
||||
* Andrew Sweeney
|
||||
* Ferenc Szalai
|
||||
* Brodie Thiesfield
|
||||
* Jason Toffaletti
|
||||
* Brian Utterback
|
||||
* Gisle Vanem
|
||||
* Bas Verhoeven
|
||||
* Constantine Verutin
|
||||
* Colin Watt
|
||||
* Zack Weinberg
|
||||
* Jardel Weyrich
|
||||
* Jay R. Wren
|
||||
* Zack Weinberg
|
||||
* Mobai Zhang
|
||||
* Alejo
|
||||
* Alex
|
||||
* Taral
|
||||
* propanbutan
|
||||
* masksqwe
|
||||
* mmadia
|
||||
* yangacer
|
||||
* Andrey Skriabin
|
||||
* basavesh.as
|
||||
* billsegall
|
||||
* Bill Vaughan
|
||||
* Christopher Wiley
|
||||
* David Paschich
|
||||
* Ed Schouten
|
||||
* Eduardo Panisset
|
||||
* Jan Heylen
|
||||
* jer-gentoo
|
||||
* Joakim Söderberg
|
||||
* kirillDanshin
|
||||
* lzmths
|
||||
* Marcus Sundberg
|
||||
* Mark Mentovai
|
||||
* Mattes D
|
||||
* Matyas Dolak
|
||||
* Neeraj Badlani
|
||||
* Nick Mathewson
|
||||
* Rainer Keller
|
||||
* Seungmo Koo
|
||||
* Thomas Bernard
|
||||
* Xiao Bao Clark
|
||||
* zeliard
|
||||
* Zonr Chang
|
||||
* Kurt Roeckx
|
||||
* Seven
|
||||
* Simone Basso
|
||||
* Vlad Shcherban
|
||||
* Tim Hentenaar
|
||||
* Breaker
|
||||
* johnsonlee
|
||||
* Philip Prindeville
|
||||
* Vis Virial
|
||||
|
||||
If we have forgotten your name, please contact us.
|
|
@ -1,4 +1,4 @@
|
|||
This is a clean copy of libevent-2.0.22-stable with the following modifications.
|
||||
This is a clean copy of libevent-2.1.8-stable with the following modifications.
|
||||
|
||||
1. Add the following files:
|
||||
|
||||
|
@ -6,13 +6,15 @@ This is a clean copy of libevent-2.0.22-stable with the following modifications.
|
|||
- bsd/event2/event-config.h
|
||||
- linux/event2/event-config.h
|
||||
- mac/event2/event-config.h
|
||||
- evconfig-private.h
|
||||
|
||||
These files are taken from libevent-2.0.22-stable built on the development
|
||||
These files are taken from libevent-2.1.8-stable built on the development
|
||||
environment indicated by the first path component. You have to run
|
||||
"./configure" and "make" to get all of the pre-processing done. The file can
|
||||
then be found in "include/event2/".
|
||||
"./configure" and "make" to get all of the pre-processing done. The
|
||||
event-config.h header can then be found in include/event2/ sub-directory and
|
||||
evconfig-private.h can be found in the root source directory.
|
||||
|
||||
You then need to modify the _EVENT_SIZEOF_* constants in the generated Linux,
|
||||
You then need to modify the EVENT__SIZEOF_* constants in the generated Linux,
|
||||
Android, and BSD headers to be appropriate for both 32-bit and 64-bit platforms.
|
||||
Mac doesn't need this since only 64-bit is supported. Use __LP64__ to
|
||||
distinguish the two cases. If you get something wrong, the CHECK_EVENT_SIZEOF
|
||||
|
@ -22,9 +24,6 @@ added, also add a static assertion for it to message_pump_libevent.cc.
|
|||
2. Apply the following patches from
|
||||
ipc/chromium/src/third_party/libevent/patches/:
|
||||
|
||||
- "avoid-empty-sighandler.patch". Fixes OSX "code -20" crashes.
|
||||
See bug 884471.
|
||||
|
||||
- "openbsd-no-arc4random_addrandom.patch". Fixes the build on OpenBSD
|
||||
and Android (which don't provide arc4random_addrandom anymore).
|
||||
See bug 931354 and bug 1259218.
|
||||
|
@ -37,9 +36,3 @@ ipc/chromium/src/third_party/libevent/patches/:
|
|||
|
||||
- "android-arc4random-buf.patch". Fixes the build for clang/android builds.
|
||||
See bug 1281596 and bug 1282141.
|
||||
|
||||
- "fix-kqueue-workaround.patch". Fixes a broken check for an OSX kqueue bug
|
||||
that caused problems on newer OSX releases. See bug 1304266.
|
||||
|
||||
- "backport-upstream-fixes.patch". Backports a few upstream fixes from 2.1.x
|
||||
to our in-tree copy of 2.0.22.
|
||||
|
|
|
@ -0,0 +1,397 @@
|
|||
# -*- mode: ruby -*-
|
||||
# vi: set ft=ruby :
|
||||
|
||||
# DESCRIPTION:
|
||||
# ============
|
||||
# Vagrant for running libevent tests with:
|
||||
# - timeout 30min, to avoid hungs
|
||||
# - run tests in parallel under ctest (10 concurency)
|
||||
# - if you have uncommited changes, you should commit them first to check
|
||||
# - unix only, because of some tar'ing to avoid one vm affect another
|
||||
#
|
||||
# ENVIRONMENT:
|
||||
# ============
|
||||
# - NO_PKG -- do not install packages
|
||||
# - NO_CMAKE -- do not run with cmake
|
||||
# - NO_AUTOTOOLS -- do not run with autoconf/automake
|
||||
|
||||
Vagrant.configure("2") do |config|
|
||||
# to allow running boxes provisions in parallel, we can't share the same dirs
|
||||
# via virtualbox, however sometimes it is the only way, so instead let's
|
||||
# create an archive of HEAD (this way we will not have any trash there) and
|
||||
# extract it for every box to the separate folder.
|
||||
#
|
||||
# P.S. we will change this --prefix with tar(1) --trasnform
|
||||
system('git archive --prefix=libevent/ --output=.vagrant/libevent.tar HEAD')
|
||||
|
||||
config.vm.provider "virtualbox" do |vb|
|
||||
vb.memory = "512"
|
||||
|
||||
# otherwise osx fails, anyway we do not need this
|
||||
vb.customize ["modifyvm", :id, "--usb", "off"]
|
||||
vb.customize ["modifyvm", :id, "--usbehci", "off"]
|
||||
end
|
||||
|
||||
# disable /vagrant share, in case we will not use default mount
|
||||
config.vm.synced_folder ".", "/vagrant", disabled: true
|
||||
|
||||
config.vm.define "ubuntu" do |ubuntu|
|
||||
system('tar --overwrite --transform=s/libevent/libevent-linux/ -xf .vagrant/libevent.tar -C .vagrant/')
|
||||
|
||||
ubuntu.vm.box = "ubuntu/xenial64"
|
||||
ubuntu.vm.synced_folder ".vagrant/libevent-linux", "/vagrant",
|
||||
type: "rsync"
|
||||
|
||||
if ENV['NO_PKG'] != "true"
|
||||
ubuntu.vm.provision "shell", inline: <<-SHELL
|
||||
apt-get update
|
||||
apt-get install -y zlib1g-dev libssl-dev python2.7
|
||||
apt-get install -y build-essential cmake ninja-build
|
||||
apt-get install -y autoconf automake libtool
|
||||
SHELL
|
||||
end
|
||||
|
||||
if ENV['NO_CMAKE'] != "true"
|
||||
ubuntu.vm.provision "shell", privileged: false, inline: <<-SHELL
|
||||
cd /vagrant
|
||||
rm -fr .cmake-vagrant
|
||||
mkdir -p .cmake-vagrant
|
||||
cd .cmake-vagrant
|
||||
cmake -G Ninja ..
|
||||
|
||||
export CTEST_TEST_TIMEOUT=1800
|
||||
export CTEST_OUTPUT_ON_FAILURE=1
|
||||
export CTEST_PARALLEL_LEVEL=20
|
||||
cmake --build . --target verify
|
||||
SHELL
|
||||
end
|
||||
|
||||
if ENV['NO_AUTOTOOLS'] != "true"
|
||||
ubuntu.vm.provision "shell", privileged: false, inline: <<-SHELL
|
||||
cd /vagrant
|
||||
./autogen.sh
|
||||
./configure
|
||||
make -j20 verify
|
||||
SHELL
|
||||
end
|
||||
end
|
||||
|
||||
config.vm.define "freebsd" do |freebsd|
|
||||
system('tar --overwrite --transform=s/libevent/libevent-freebsd/ -xf .vagrant/libevent.tar -C .vagrant/')
|
||||
|
||||
freebsd.vm.box = "freebsd/FreeBSD-11.0-STABLE"
|
||||
freebsd.vm.synced_folder ".vagrant/libevent-freebsd", "/vagrant",
|
||||
type: "rsync", group: "wheel"
|
||||
|
||||
# otherwise reports error
|
||||
freebsd.ssh.shell = "sh"
|
||||
|
||||
if ENV['NO_PKG'] != "true"
|
||||
freebsd.vm.provision "shell", inline: <<-SHELL
|
||||
pkg install --yes openssl cmake ninja automake autotools
|
||||
SHELL
|
||||
end
|
||||
|
||||
if ENV['NO_CMAKE'] != "true"
|
||||
freebsd.vm.provision "shell", privileged: false, inline: <<-SHELL
|
||||
cd /vagrant
|
||||
rm -fr .cmake-vagrant
|
||||
mkdir -p .cmake-vagrant
|
||||
cd .cmake-vagrant
|
||||
cmake -G Ninja ..
|
||||
|
||||
export CTEST_TEST_TIMEOUT=1800
|
||||
export CTEST_OUTPUT_ON_FAILURE=1
|
||||
export CTEST_PARALLEL_LEVEL=20
|
||||
cmake --build . --target verify
|
||||
SHELL
|
||||
end
|
||||
|
||||
if ENV['NO_AUTOTOOLS'] != "true"
|
||||
freebsd.vm.provision "shell", privileged: false, inline: <<-SHELL
|
||||
cd /vagrant
|
||||
./autogen.sh
|
||||
./configure
|
||||
make -j20 verify
|
||||
SHELL
|
||||
end
|
||||
end
|
||||
|
||||
config.vm.define "netbsd" do |netbsd|
|
||||
system('tar --overwrite --transform=s/libevent/libevent-netbsd/ -xf .vagrant/libevent.tar -C .vagrant/')
|
||||
|
||||
netbsd.vm.box = "kja/netbsd-7-amd64"
|
||||
netbsd.vm.synced_folder ".vagrant/libevent-netbsd", "/vagrant",
|
||||
type: "rsync", group: "wheel"
|
||||
|
||||
if ENV['NO_PKG'] != "true"
|
||||
netbsd.vm.provision "shell", inline: <<-SHELL
|
||||
export PKG_PATH="ftp://ftp.netbsd.org/pub/pkgsrc/packages/NetBSD/x86_64/7.0_2016Q2/All/"
|
||||
pkg_add ncurses ninja-build automake cmake libtool
|
||||
SHELL
|
||||
end
|
||||
|
||||
if ENV['NO_CMAKE'] != "true"
|
||||
netbsd.vm.provision "shell", privileged: false, inline: <<-SHELL
|
||||
cd /vagrant
|
||||
rm -fr .cmake-vagrant
|
||||
mkdir -p .cmake-vagrant
|
||||
cd .cmake-vagrant
|
||||
cmake -G Ninja ..
|
||||
|
||||
export CTEST_TEST_TIMEOUT=1800
|
||||
export CTEST_OUTPUT_ON_FAILURE=1
|
||||
export CTEST_PARALLEL_LEVEL=20
|
||||
cmake --build . --target verify
|
||||
SHELL
|
||||
end
|
||||
|
||||
if ENV['NO_AUTOTOOLS'] != "true"
|
||||
netbsd.vm.provision "shell", privileged: false, inline: <<-SHELL
|
||||
cd /vagrant
|
||||
./autogen.sh
|
||||
./configure
|
||||
make -j20 verify
|
||||
SHELL
|
||||
end
|
||||
end
|
||||
|
||||
config.vm.define "solaris" do |solaris|
|
||||
system('tar --overwrite --transform=s/libevent/libevent-solaris/ -xf .vagrant/libevent.tar -C .vagrant/')
|
||||
|
||||
# XXX:
|
||||
# - solaris do not have '-or' it only has '-o' for find(1), so we can't use
|
||||
# rsync
|
||||
# - and autoconf(1) doesn't work on virtualbox share, ugh
|
||||
solaris.vm.synced_folder ".vagrant/libevent-solaris", "/vagrant-vbox",
|
||||
type: "virtualbox"
|
||||
|
||||
solaris.vm.box = "tnarik/solaris10-minimal"
|
||||
if ENV['NO_PKG'] != "true"
|
||||
# TODO: opencsw does not include ninja(1)
|
||||
solaris.vm.provision "shell", inline: <<-SHELL
|
||||
pkgadd -d http://get.opencsw.org/now
|
||||
pkgutil -U
|
||||
pkgutil -y -i libssl_dev cmake rsync python gmake gcc5core automake autoconf libtool
|
||||
SHELL
|
||||
end
|
||||
|
||||
# copy from virtualbox mount to newly created folder
|
||||
solaris.vm.provision "shell", privileged: false, inline: <<-SHELL
|
||||
rm -fr ~/vagrant
|
||||
cp -r /vagrant-vbox ~/vagrant
|
||||
SHELL
|
||||
|
||||
if ENV['NO_CMAKE'] != "true"
|
||||
# builtin compiler cc(1) is a wrapper, so we should use gcc5 manually,
|
||||
# otherwise it will not work.
|
||||
# Plus we should set some paths so that cmake/compiler can find tham.
|
||||
solaris.vm.provision "shell", privileged: false, inline: <<-SHELL
|
||||
export CMAKE_INCLUDE_PATH=/opt/csw/include
|
||||
export CMAKE_LIBRARY_PATH=/opt/csw/lib
|
||||
export CFLAGS=-I$CMAKE_INCLUDE_PATH
|
||||
export LDFLAGS=-L$CMAKE_LIBRARY_PATH
|
||||
|
||||
cd ~/vagrant
|
||||
rm -rf .cmake-vagrant
|
||||
mkdir -p .cmake-vagrant
|
||||
cd .cmake-vagrant
|
||||
cmake -DCMAKE_C_COMPILER=gcc ..
|
||||
|
||||
export CTEST_TEST_TIMEOUT=1800
|
||||
export CTEST_OUTPUT_ON_FAILURE=1
|
||||
export CTEST_PARALLEL_LEVEL=20
|
||||
cmake --build . --target verify
|
||||
SHELL
|
||||
end
|
||||
|
||||
if ENV['NO_AUTOTOOLS'] != "true"
|
||||
# and we should set MAKE for `configure` otherwise it will try to use
|
||||
# `make`
|
||||
solaris.vm.provision "shell", privileged: false, inline: <<-SHELL
|
||||
cd ~/vagrant
|
||||
./autogen.sh
|
||||
MAKE=gmake ./configure
|
||||
gmake -j20 verify
|
||||
SHELL
|
||||
end
|
||||
end
|
||||
|
||||
# known failures:
|
||||
# - sometimes vm hangs
|
||||
config.vm.define "osx" do |osx|
|
||||
system('tar --overwrite --transform=s/libevent/libevent-osx/ -xf .vagrant/libevent.tar -C .vagrant/')
|
||||
|
||||
osx.vm.synced_folder ".vagrant/libevent-osx", "/vagrant",
|
||||
type: "rsync", group: "wheel"
|
||||
|
||||
osx.vm.box = "jhcook/osx-elcapitan-10.11"
|
||||
if ENV['NO_PKG'] != "true"
|
||||
osx.vm.provision "shell", privileged: false, inline: <<-SHELL
|
||||
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
|
||||
|
||||
brew uninstall libtool
|
||||
brew install libtool openssl ninja cmake autoconf automake
|
||||
SHELL
|
||||
end
|
||||
|
||||
if ENV['NO_CMAKE'] != "true"
|
||||
# we should set some paths so that cmake/compiler can find tham
|
||||
osx.vm.provision "shell", privileged: false, inline: <<-SHELL
|
||||
export OPENSSL_ROOT=$(echo /usr/local/Cellar/openssl/*)
|
||||
export CMAKE_INCLUDE_PATH=$OPENSSL_ROOT/include
|
||||
export CMAKE_LIBRARY_PATH=$OPENSSL_ROOT/lib
|
||||
|
||||
cd /vagrant
|
||||
mkdir -p .cmake-vagrant
|
||||
cd .cmake-vagrant
|
||||
cmake -G Ninja ..
|
||||
|
||||
export CTEST_TEST_TIMEOUT=1800
|
||||
export CTEST_OUTPUT_ON_FAILURE=1
|
||||
export CTEST_PARALLEL_LEVEL=20
|
||||
cmake --build . --target verify
|
||||
SHELL
|
||||
end
|
||||
|
||||
if ENV['NO_AUTOTOOLS'] != "true"
|
||||
osx.vm.provision "shell", privileged: false, inline: <<-SHELL
|
||||
export OPENSSL_ROOT=$(echo /usr/local/Cellar/openssl/*)
|
||||
export CFLAGS=-I$OPENSSL_ROOT/include
|
||||
export LDFLAGS=-L$OPENSSL_ROOT/lib
|
||||
|
||||
cd /vagrant
|
||||
./autogen.sh
|
||||
./configure
|
||||
make -j20 verify
|
||||
SHELL
|
||||
end
|
||||
end
|
||||
|
||||
config.vm.define "centos" do |centos|
|
||||
system('tar --overwrite --transform=s/libevent/libevent-centos/ -xf .vagrant/libevent.tar -C .vagrant/')
|
||||
|
||||
centos.vm.synced_folder ".vagrant/libevent-centos", "/vagrant",
|
||||
type: "rsync", group: "wheel"
|
||||
|
||||
centos.vm.box = "centos/7"
|
||||
if ENV['NO_PKG'] != "true"
|
||||
centos.vm.provision "shell", inline: <<-SHELL
|
||||
echo "[russianfedora]" > /etc/yum.repos.d/russianfedora.repo
|
||||
echo name=russianfedora >> /etc/yum.repos.d/russianfedora.repo
|
||||
echo baseurl=http://mirror.yandex.ru/fedora/russianfedora/russianfedora/free/el/releases/7/Everything/x86_64/os/ >> /etc/yum.repos.d/russianfedora.repo
|
||||
echo enabled=1 >> /etc/yum.repos.d/russianfedora.repo
|
||||
echo gpgcheck=0 >> /etc/yum.repos.d/russianfedora.repo
|
||||
SHELL
|
||||
centos.vm.provision "shell", inline: <<-SHELL
|
||||
yum -y install zlib-devel openssl-devel python
|
||||
yum -y install gcc cmake ninja-build
|
||||
yum -y install autoconf automake libtool
|
||||
SHELL
|
||||
end
|
||||
|
||||
if ENV['NO_CMAKE'] != "true"
|
||||
centos.vm.provision "shell", privileged: false, inline: <<-SHELL
|
||||
cd /vagrant
|
||||
rm -fr .cmake-vagrant
|
||||
mkdir -p .cmake-vagrant
|
||||
cd .cmake-vagrant
|
||||
cmake -G Ninja ..
|
||||
|
||||
export CTEST_TEST_TIMEOUT=1800
|
||||
export CTEST_OUTPUT_ON_FAILURE=1
|
||||
export CTEST_PARALLEL_LEVEL=20
|
||||
cmake --build . --target verify
|
||||
SHELL
|
||||
end
|
||||
|
||||
if ENV['NO_AUTOTOOLS'] != "true"
|
||||
centos.vm.provision "shell", privileged: false, inline: <<-SHELL
|
||||
cd /vagrant
|
||||
./autogen.sh
|
||||
./configure
|
||||
make -j20 verify
|
||||
SHELL
|
||||
end
|
||||
end
|
||||
|
||||
# known failures:
|
||||
# - issues with timers (not enough allowed error)
|
||||
config.vm.define "win" do |win|
|
||||
system('tar --overwrite --transform=s/libevent/libevent-win/ -xf .vagrant/libevent.tar -C .vagrant/')
|
||||
|
||||
# 512MB not enough after libtool install, huh
|
||||
win.vm.provider "virtualbox" do |vb|
|
||||
vb.memory = "1024"
|
||||
end
|
||||
|
||||
# windows does not have rsync builtin, let's use virtualbox for now
|
||||
win.vm.synced_folder ".vagrant/libevent-win", "/vagrant",
|
||||
type: "virtualbox"
|
||||
|
||||
win.vm.box = "senglin/win-10-enterprise-vs2015community"
|
||||
if ENV['NO_PKG'] != "true"
|
||||
# box with vs2015 does not have C++ support, so let's install it manually
|
||||
# plus chocolatey that includes in this box, can't handle sha1 checksum for
|
||||
# cmake.install, so let's update it<
|
||||
win.vm.provision "shell", inline: <<-SHELL
|
||||
choco upgrade -y chocolatey -pre -f
|
||||
choco install -y VisualStudioCommunity2013
|
||||
choco install -y openssl.light
|
||||
choco install -y cygwin cyg-get
|
||||
choco install -y cmake
|
||||
choco install -y cmake.install
|
||||
choco install -y python2
|
||||
SHELL
|
||||
|
||||
# chocolatey openssl.light package does not contains headers
|
||||
win.vm.provision "shell", inline: <<-SHELL
|
||||
(new-object System.Net.WebClient).DownloadFile('http://strcpy.net/packages/Win32OpenSSL-1_0_2a.exe', '/openssl.exe')
|
||||
/openssl.exe /silent /verysilent /sp- /suppressmsgboxes
|
||||
SHELL
|
||||
|
||||
# XXX:
|
||||
# - cyg-get depends from cygwinsetup.exe
|
||||
# https://github.com/chocolatey/chocolatey-coreteampackages/issues/200
|
||||
# - cyg-get only downloads, do not installs them, ugh. so let's do not use
|
||||
# it
|
||||
win.vm.provision "shell", privileged: false, inline: <<-SHELL
|
||||
(new-object System.Net.WebClient).DownloadFile('https://cygwin.com/setup-x86_64.exe', '/tools/cygwin/cygwinsetup.exe')
|
||||
|
||||
$env:PATH="/tools/cygwin/bin;$($env:PATH);/tools/cygwin"
|
||||
|
||||
cygwinsetup --root c:/tools/cygwin/ --local-package-dir c:/tools/cygwin/packages/ --no-desktop --no-startmenu --verbose --quiet-mode --download --packages automake,autoconf,gcc-core,libtool,make,python,openssl-devel
|
||||
cygwinsetup --root c:/tools/cygwin/ --local-package-dir c:/tools/cygwin/packages/ --no-desktop --no-startmenu --verbose --quiet-mode --local-install --packages automake,autoconf,gcc-core,libtool,make,python,openssl-devel
|
||||
SHELL
|
||||
end
|
||||
|
||||
if ENV['NO_CMAKE'] != "true"
|
||||
win.vm.provision "shell", privileged: false, inline: <<-SHELL
|
||||
$env:PATH="/Program Files/CMake/bin;/tools/python2;$($env:PATH)"
|
||||
|
||||
cd /vagrant
|
||||
Remove-Item -Recurse -Force .cmake-vagrant
|
||||
mkdir -p .cmake-vagrant
|
||||
cd .cmake-vagrant
|
||||
cmake -G "Visual Studio 12" ..
|
||||
|
||||
$env:CTEST_TEST_TIMEOUT = "1800"
|
||||
$env:CTEST_OUTPUT_ON_FAILURE = "1"
|
||||
$env:CTEST_PARALLEL_LEVEL = "10"
|
||||
cmake --build . --target verify
|
||||
SHELL
|
||||
end
|
||||
|
||||
if ENV['NO_AUTOTOOLS'] != "true"
|
||||
win.vm.provision "shell", privileged: false, inline: <<-SHELL
|
||||
$env:PATH="/tools/cygwin/bin;$($env:PATH)"
|
||||
|
||||
bash -lc "echo 'C:/tools/mingw64 /mingw ntfs binary 0 0' > /etc/fstab"
|
||||
bash -lc "echo 'C:/OpenSSL-Win32 /ssl ntfs binary 0 0' >> /etc/fstab"
|
||||
bash -lc "echo 'C:/vagrant /vagrant ntfs binary 0 0' >> /etc/fstab"
|
||||
|
||||
bash -lc "exec 0</dev/null; exec 2>&1; cd /vagrant; bash -x ./autogen.sh && ./configure LDFLAGS='-L/ssl -L/ssl/lib -L/ssl/lib/MinGW' CFLAGS=-I/ssl/include && make -j20 verify"
|
||||
SHELL
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,149 @@
|
|||
/* $NetBSD: getopt.c,v 1.16 1999/12/02 13:15:56 kleink Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1987, 1993, 1994, 1995
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the names of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
|
||||
* IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95";
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define __P(x) x
|
||||
#define _DIAGASSERT(x) assert(x)
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(getopt,_getopt);
|
||||
#endif
|
||||
|
||||
|
||||
int opterr = 1, /* if error message should be printed */
|
||||
optind = 1, /* index into parent argv vector */
|
||||
optopt, /* character checked for validity */
|
||||
optreset; /* reset getopt */
|
||||
char *optarg; /* argument associated with option */
|
||||
|
||||
static char * _progname __P((char *));
|
||||
int getopt_internal __P((int, char * const *, const char *));
|
||||
|
||||
static char *
|
||||
_progname(nargv0)
|
||||
char * nargv0;
|
||||
{
|
||||
char * tmp;
|
||||
|
||||
_DIAGASSERT(nargv0 != NULL);
|
||||
|
||||
tmp = strrchr(nargv0, '/');
|
||||
if (tmp)
|
||||
tmp++;
|
||||
else
|
||||
tmp = nargv0;
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
#define BADCH (int)'?'
|
||||
#define BADARG (int)':'
|
||||
#define EMSG ""
|
||||
|
||||
/*
|
||||
* getopt --
|
||||
* Parse argc/argv argument vector.
|
||||
*/
|
||||
int
|
||||
getopt(nargc, nargv, ostr)
|
||||
int nargc;
|
||||
char * const nargv[];
|
||||
const char *ostr;
|
||||
{
|
||||
static char *__progname = 0;
|
||||
static char *place = EMSG; /* option letter processing */
|
||||
char *oli; /* option letter list index */
|
||||
__progname = __progname?__progname:_progname(*nargv);
|
||||
|
||||
_DIAGASSERT(nargv != NULL);
|
||||
_DIAGASSERT(ostr != NULL);
|
||||
|
||||
if (optreset || !*place) { /* update scanning pointer */
|
||||
optreset = 0;
|
||||
if (optind >= nargc || *(place = nargv[optind]) != '-') {
|
||||
place = EMSG;
|
||||
return (-1);
|
||||
}
|
||||
if (place[1] && *++place == '-' /* found "--" */
|
||||
&& place[1] == '\0') {
|
||||
++optind;
|
||||
place = EMSG;
|
||||
return (-1);
|
||||
}
|
||||
} /* option letter okay? */
|
||||
if ((optopt = (int)*place++) == (int)':' ||
|
||||
!(oli = strchr(ostr, optopt))) {
|
||||
/*
|
||||
* if the user didn't specify '-' as an option,
|
||||
* assume it means -1.
|
||||
*/
|
||||
if (optopt == (int)'-')
|
||||
return (-1);
|
||||
if (!*place)
|
||||
++optind;
|
||||
if (opterr && *ostr != ':')
|
||||
(void)fprintf(stderr,
|
||||
"%s: illegal option -- %c\n", __progname, optopt);
|
||||
return (BADCH);
|
||||
}
|
||||
if (*++oli != ':') { /* don't need argument */
|
||||
optarg = NULL;
|
||||
if (!*place)
|
||||
++optind;
|
||||
}
|
||||
else { /* need an argument */
|
||||
if (*place) /* no white space */
|
||||
optarg = place;
|
||||
else if (nargc <= ++optind) { /* no arg */
|
||||
place = EMSG;
|
||||
if (*ostr == ':')
|
||||
return (BADARG);
|
||||
if (opterr)
|
||||
(void)fprintf(stderr,
|
||||
"%s: option requires an argument -- %c\n",
|
||||
__progname, optopt);
|
||||
return (BADCH);
|
||||
}
|
||||
else /* white space */
|
||||
optarg = nargv[optind];
|
||||
place = EMSG;
|
||||
++optind;
|
||||
}
|
||||
return (optopt); /* dump back option letter */
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef __GETOPT_H__
|
||||
#define __GETOPT_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int opterr; /* if error message should be printed */
|
||||
extern int optind; /* index into parent argv vector */
|
||||
extern int optopt; /* character checked for validity */
|
||||
extern int optreset; /* reset getopt */
|
||||
extern char *optarg; /* argument associated with option */
|
||||
|
||||
struct option
|
||||
{
|
||||
const char *name;
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
#define no_argument 0
|
||||
#define required_argument 1
|
||||
#define optional_argument 2
|
||||
|
||||
int getopt(int, char**, const char*);
|
||||
int getopt_long(int, char**, const char*, const struct option*, int*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __GETOPT_H__ */
|
|
@ -0,0 +1,233 @@
|
|||
|
||||
/*
|
||||
* Copyright (c) 1987, 1993, 1994, 1996
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the names of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
|
||||
* IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "getopt.h"
|
||||
|
||||
extern int opterr; /* if error message should be printed */
|
||||
extern int optind; /* index into parent argv vector */
|
||||
extern int optopt; /* character checked for validity */
|
||||
extern int optreset; /* reset getopt */
|
||||
extern char *optarg; /* argument associated with option */
|
||||
|
||||
#define __P(x) x
|
||||
#define _DIAGASSERT(x) assert(x)
|
||||
|
||||
static char * __progname __P((char *));
|
||||
int getopt_internal __P((int, char * const *, const char *));
|
||||
|
||||
static char *
|
||||
__progname(nargv0)
|
||||
char * nargv0;
|
||||
{
|
||||
char * tmp;
|
||||
|
||||
_DIAGASSERT(nargv0 != NULL);
|
||||
|
||||
tmp = strrchr(nargv0, '/');
|
||||
if (tmp)
|
||||
tmp++;
|
||||
else
|
||||
tmp = nargv0;
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
#define BADCH (int)'?'
|
||||
#define BADARG (int)':'
|
||||
#define EMSG ""
|
||||
|
||||
/*
|
||||
* getopt --
|
||||
* Parse argc/argv argument vector.
|
||||
*/
|
||||
int
|
||||
getopt_internal(nargc, nargv, ostr)
|
||||
int nargc;
|
||||
char * const *nargv;
|
||||
const char *ostr;
|
||||
{
|
||||
static char *place = EMSG; /* option letter processing */
|
||||
char *oli; /* option letter list index */
|
||||
|
||||
_DIAGASSERT(nargv != NULL);
|
||||
_DIAGASSERT(ostr != NULL);
|
||||
|
||||
if (optreset || !*place) { /* update scanning pointer */
|
||||
optreset = 0;
|
||||
if (optind >= nargc || *(place = nargv[optind]) != '-') {
|
||||
place = EMSG;
|
||||
return (-1);
|
||||
}
|
||||
if (place[1] && *++place == '-') { /* found "--" */
|
||||
/* ++optind; */
|
||||
place = EMSG;
|
||||
return (-2);
|
||||
}
|
||||
} /* option letter okay? */
|
||||
if ((optopt = (int)*place++) == (int)':' ||
|
||||
!(oli = strchr(ostr, optopt))) {
|
||||
/*
|
||||
* if the user didn't specify '-' as an option,
|
||||
* assume it means -1.
|
||||
*/
|
||||
if (optopt == (int)'-')
|
||||
return (-1);
|
||||
if (!*place)
|
||||
++optind;
|
||||
if (opterr && *ostr != ':')
|
||||
(void)fprintf(stderr,
|
||||
"%s: illegal option -- %c\n", __progname(nargv[0]), optopt);
|
||||
return (BADCH);
|
||||
}
|
||||
if (*++oli != ':') { /* don't need argument */
|
||||
optarg = NULL;
|
||||
if (!*place)
|
||||
++optind;
|
||||
} else { /* need an argument */
|
||||
if (*place) /* no white space */
|
||||
optarg = place;
|
||||
else if (nargc <= ++optind) { /* no arg */
|
||||
place = EMSG;
|
||||
if ((opterr) && (*ostr != ':'))
|
||||
(void)fprintf(stderr,
|
||||
"%s: option requires an argument -- %c\n",
|
||||
__progname(nargv[0]), optopt);
|
||||
return (BADARG);
|
||||
} else /* white space */
|
||||
optarg = nargv[optind];
|
||||
place = EMSG;
|
||||
++optind;
|
||||
}
|
||||
return (optopt); /* dump back option letter */
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* getopt --
|
||||
* Parse argc/argv argument vector.
|
||||
*/
|
||||
int
|
||||
getopt2(nargc, nargv, ostr)
|
||||
int nargc;
|
||||
char * const *nargv;
|
||||
const char *ostr;
|
||||
{
|
||||
int retval;
|
||||
|
||||
if ((retval = getopt_internal(nargc, nargv, ostr)) == -2) {
|
||||
retval = -1;
|
||||
++optind;
|
||||
}
|
||||
return(retval);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* getopt_long --
|
||||
* Parse argc/argv argument vector.
|
||||
*/
|
||||
int
|
||||
getopt_long(nargc, nargv, options, long_options, index)
|
||||
int nargc;
|
||||
char ** nargv;
|
||||
const char * options;
|
||||
const struct option * long_options;
|
||||
int * index;
|
||||
{
|
||||
int retval;
|
||||
|
||||
_DIAGASSERT(nargv != NULL);
|
||||
_DIAGASSERT(options != NULL);
|
||||
_DIAGASSERT(long_options != NULL);
|
||||
/* index may be NULL */
|
||||
|
||||
if ((retval = getopt_internal(nargc, nargv, options)) == -2) {
|
||||
char *current_argv = nargv[optind++] + 2, *has_equal;
|
||||
int i, current_argv_len, match = -1;
|
||||
|
||||
if (*current_argv == '\0') {
|
||||
return(-1);
|
||||
}
|
||||
if ((has_equal = strchr(current_argv, '=')) != NULL) {
|
||||
current_argv_len = has_equal - current_argv;
|
||||
has_equal++;
|
||||
} else
|
||||
current_argv_len = strlen(current_argv);
|
||||
|
||||
for (i = 0; long_options[i].name; i++) {
|
||||
if (strncmp(current_argv, long_options[i].name, current_argv_len))
|
||||
continue;
|
||||
|
||||
if (strlen(long_options[i].name) == (unsigned)current_argv_len) {
|
||||
match = i;
|
||||
break;
|
||||
}
|
||||
if (match == -1)
|
||||
match = i;
|
||||
}
|
||||
if (match != -1) {
|
||||
if (long_options[match].has_arg == required_argument ||
|
||||
long_options[match].has_arg == optional_argument) {
|
||||
if (has_equal)
|
||||
optarg = has_equal;
|
||||
else
|
||||
optarg = nargv[optind++];
|
||||
}
|
||||
if ((long_options[match].has_arg == required_argument)
|
||||
&& (optarg == NULL)) {
|
||||
/*
|
||||
* Missing argument, leading :
|
||||
* indicates no error should be generated
|
||||
*/
|
||||
if ((opterr) && (*options != ':'))
|
||||
(void)fprintf(stderr,
|
||||
"%s: option requires an argument -- %s\n",
|
||||
__progname(nargv[0]), current_argv);
|
||||
return (BADARG);
|
||||
}
|
||||
} else { /* No matching argument */
|
||||
if ((opterr) && (*options != ':'))
|
||||
(void)fprintf(stderr,
|
||||
"%s: illegal option -- %s\n", __progname(nargv[0]), current_argv);
|
||||
return (BADCH);
|
||||
}
|
||||
if (long_options[match].flag) {
|
||||
*long_options[match].flag = long_options[match].val;
|
||||
retval = 0;
|
||||
} else
|
||||
retval = long_options[match].val;
|
||||
if (index)
|
||||
*index = match;
|
||||
}
|
||||
return(retval);
|
||||
}
|
6
ipc/chromium/src/third_party/libevent/WIN32-Code/nmake/evconfig-private.h
поставляемый
Normal file
6
ipc/chromium/src/third_party/libevent/WIN32-Code/nmake/evconfig-private.h
поставляемый
Normal file
|
@ -0,0 +1,6 @@
|
|||
#if !defined(EVENT_EVCONFIG__PRIVATE_H_) && !defined(__MINGW32__)
|
||||
#define EVENT_EVCONFIG__PRIVATE_H_
|
||||
|
||||
/* Nothing to see here. Move along. */
|
||||
|
||||
#endif
|
|
@ -7,357 +7,354 @@
|
|||
*
|
||||
* Do not rely on macros in this file existing in later versions.
|
||||
*/
|
||||
#ifndef _EVENT_CONFIG_H_
|
||||
#define _EVENT_CONFIG_H_
|
||||
#ifndef EVENT_CONFIG_H__
|
||||
#define EVENT_CONFIG_H__
|
||||
/* config.h. Generated by configure. */
|
||||
/* config.h.in. Generated from configure.in by autoheader. */
|
||||
|
||||
/* Define if libevent should not allow replacing the mm functions */
|
||||
/* #undef _EVENT_DISABLE_MM_REPLACEMENT */
|
||||
/* #undef EVENT__DISABLE_MM_REPLACEMENT */
|
||||
|
||||
/* Define if libevent should not be compiled with thread support */
|
||||
/* #undef _EVENT_DISABLE_THREAD_SUPPORT */
|
||||
/* #undef EVENT__DISABLE_THREAD_SUPPORT */
|
||||
|
||||
/* Define if clock_gettime is available in libc */
|
||||
/* #undef _EVENT_DNS_USE_CPU_CLOCK_FOR_ID */
|
||||
|
||||
/* Define is no secure id variant is available */
|
||||
/* #define _EVENT_DNS_USE_GETTIMEOFDAY_FOR_ID 1 */
|
||||
#define _EVENT_DNS_USE_FTIME_FOR_ID 1
|
||||
#define EVENT_DNS_USE_FTIME_FOR_ID_ 1
|
||||
|
||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
/* #undef _EVENT_HAVE_ARPA_INET_H */
|
||||
/* #undef EVENT__HAVE_ARPA_INET_H */
|
||||
|
||||
/* Define to 1 if you have the `clock_gettime' function. */
|
||||
/* #undef _EVENT_HAVE_CLOCK_GETTIME */
|
||||
/* #undef EVENT__HAVE_CLOCK_GETTIME */
|
||||
|
||||
/* Define if /dev/poll is available */
|
||||
/* #undef _EVENT_HAVE_DEVPOLL */
|
||||
/* #undef EVENT__HAVE_DEVPOLL */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
/* #undef _EVENT_HAVE_DLFCN_H */
|
||||
/* #undef EVENT__HAVE_DLFCN_H */
|
||||
|
||||
/* Define if your system supports the epoll system calls */
|
||||
/* #undef _EVENT_HAVE_EPOLL */
|
||||
/* #undef EVENT__HAVE_EPOLL */
|
||||
|
||||
/* Define to 1 if you have the `epoll_ctl' function. */
|
||||
/* #undef _EVENT_HAVE_EPOLL_CTL */
|
||||
/* #undef EVENT__HAVE_EPOLL_CTL */
|
||||
|
||||
/* Define to 1 if you have the `eventfd' function. */
|
||||
/* #undef _EVENT_HAVE_EVENTFD */
|
||||
/* #undef EVENT__HAVE_EVENTFD */
|
||||
|
||||
/* Define if your system supports event ports */
|
||||
/* #undef _EVENT_HAVE_EVENT_PORTS */
|
||||
/* #undef EVENT__HAVE_EVENT_PORTS */
|
||||
|
||||
/* Define to 1 if you have the `fcntl' function. */
|
||||
/* #undef _EVENT_HAVE_FCNTL */
|
||||
/* #undef EVENT__HAVE_FCNTL */
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define _EVENT_HAVE_FCNTL_H 1
|
||||
#define EVENT__HAVE_FCNTL_H 1
|
||||
|
||||
/* Define to 1 if you have the `getaddrinfo' function. */
|
||||
#define _EVENT_HAVE_GETADDRINFO 1
|
||||
#define EVENT__HAVE_GETADDRINFO 1
|
||||
|
||||
/* Define to 1 if you have the `getnameinfo' function. */
|
||||
#define _EVENT_HAVE_GETNAMEINFO 1
|
||||
#define EVENT__HAVE_GETNAMEINFO 1
|
||||
|
||||
/* Define to 1 if you have the `getprotobynumber' function. */
|
||||
#define _EVENT_HAVE_GETPROTOBYNUMBER 1
|
||||
#define EVENT__HAVE_GETPROTOBYNUMBER 1
|
||||
|
||||
/* Define to 1 if you have the `getservbyname' function. */
|
||||
#define _EVENT_HAVE_GETSERVBYNAME 1
|
||||
#define EVENT__HAVE_GETSERVBYNAME 1
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
/* #define _EVENT_HAVE_GETTIMEOFDAY 1 */
|
||||
|
||||
/* Define to 1 if you have the `inet_aton' function. */
|
||||
/* #undef _EVENT_HAVE_INET_ATON */
|
||||
/* #define EVENT__HAVE_GETTIMEOFDAY 1 */
|
||||
|
||||
/* Define to 1 if you have the `inet_ntop' function. */
|
||||
/* #undef _EVENT_HAVE_INET_NTOP */
|
||||
/* #undef EVENT__HAVE_INET_NTOP */
|
||||
|
||||
/* Define to 1 if you have the `inet_pton' function. */
|
||||
/* #undef _EVENT_HAVE_INET_PTON */
|
||||
/* #undef EVENT__HAVE_INET_PTON */
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
/* #define _EVENT_HAVE_INTTYPES_H 1 */
|
||||
/* #define EVENT__HAVE_INTTYPES_H 1 */
|
||||
|
||||
/* Define to 1 if you have the `kqueue' function. */
|
||||
/* #undef _EVENT_HAVE_KQUEUE */
|
||||
/* #undef EVENT__HAVE_KQUEUE */
|
||||
|
||||
/* Define if the system has zlib */
|
||||
/* #undef _EVENT_HAVE_LIBZ */
|
||||
/* #undef EVENT__HAVE_LIBZ */
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define _EVENT_HAVE_MEMORY_H 1
|
||||
#define EVENT__HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the `mmap' function. */
|
||||
/* #undef _EVENT_HAVE_MMAP */
|
||||
/* #undef EVENT__HAVE_MMAP */
|
||||
|
||||
/* Define to 1 if you have the <netinet/in6.h> header file. */
|
||||
/* #undef _EVENT_HAVE_NETINET_IN6_H */
|
||||
/* #undef EVENT__HAVE_NETINET_IN6_H */
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
/* #undef _EVENT_HAVE_NETINET_IN_H */
|
||||
/* #undef EVENT__HAVE_NETINET_IN_H */
|
||||
|
||||
/* Define to 1 if you have the `pipe' function. */
|
||||
/* #undef _EVENT_HAVE_PIPE */
|
||||
/* #undef EVENT__HAVE_PIPE */
|
||||
|
||||
/* Define to 1 if you have the `poll' function. */
|
||||
/* #undef _EVENT_HAVE_POLL */
|
||||
/* #undef EVENT__HAVE_POLL */
|
||||
|
||||
/* Define to 1 if you have the <poll.h> header file. */
|
||||
/* #undef _EVENT_HAVE_POLL_H */
|
||||
/* #undef EVENT__HAVE_POLL_H */
|
||||
|
||||
/* Define to 1 if you have the `port_create' function. */
|
||||
/* #undef _EVENT_HAVE_PORT_CREATE */
|
||||
/* #undef EVENT__HAVE_PORT_CREATE */
|
||||
|
||||
/* Define to 1 if you have the <port.h> header file. */
|
||||
/* #undef _EVENT_HAVE_PORT_H */
|
||||
/* #undef EVENT__HAVE_PORT_H */
|
||||
|
||||
/* Define if you have POSIX threads libraries and header files. */
|
||||
/* #undef _EVENT_HAVE_PTHREAD */
|
||||
/* #undef EVENT__HAVE_PTHREAD */
|
||||
|
||||
/* Define if we have pthreads on this system */
|
||||
/* #undef _EVENT_HAVE_PTHREADS */
|
||||
/* #undef EVENT__HAVE_PTHREADS */
|
||||
|
||||
/* Define to 1 if the system has the type `sa_family_t'. */
|
||||
/* #undef _EVENT_HAVE_SA_FAMILY_T */
|
||||
/* #undef EVENT__HAVE_SA_FAMILY_T */
|
||||
|
||||
/* Define to 1 if you have the `select' function. */
|
||||
/* #undef _EVENT_HAVE_SELECT */
|
||||
/* #undef EVENT__HAVE_SELECT */
|
||||
|
||||
/* Define to 1 if you have the `sendfile' function. */
|
||||
/* #undef _EVENT_HAVE_SENDFILE */
|
||||
/* #undef EVENT__HAVE_SENDFILE */
|
||||
|
||||
/* Define if F_SETFD is defined in <fcntl.h> */
|
||||
/* #undef _EVENT_HAVE_SETFD */
|
||||
/* #undef EVENT__HAVE_SETFD */
|
||||
|
||||
/* Define to 1 if you have the `sigaction' function. */
|
||||
/* #undef _EVENT_HAVE_SIGACTION */
|
||||
/* #undef EVENT__HAVE_SIGACTION */
|
||||
|
||||
/* Define to 1 if you have the `signal' function. */
|
||||
#define _EVENT_HAVE_SIGNAL 1
|
||||
#define EVENT__HAVE_SIGNAL 1
|
||||
|
||||
/* Define to 1 if you have the `splice' function. */
|
||||
/* #undef _EVENT_HAVE_SPLICE */
|
||||
/* #undef EVENT__HAVE_SPLICE */
|
||||
|
||||
/* Define to 1 if you have the <stdarg.h> header file. */
|
||||
#define _EVENT_HAVE_STDARG_H 1
|
||||
#define EVENT__HAVE_STDARG_H 1
|
||||
|
||||
/* Define to 1 if you have the <stddef.h> header file. */
|
||||
#define _EVENT_HAVE_STDDEF_H 1
|
||||
#define EVENT__HAVE_STDDEF_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
/* #define _EVENT_HAVE_STDINT_H 1 */
|
||||
/* #define EVENT__HAVE_STDINT_H 1 */
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define _EVENT_HAVE_STDLIB_H 1
|
||||
#define EVENT__HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define _EVENT_HAVE_STRINGS_H 1
|
||||
#define EVENT__HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define _EVENT_HAVE_STRING_H 1
|
||||
#define EVENT__HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strlcpy' function. */
|
||||
/* #undef _EVENT_HAVE_STRLCPY */
|
||||
/* #undef EVENT__HAVE_STRLCPY */
|
||||
|
||||
/* Define to 1 if you have the `strsep' function. */
|
||||
/* #undef _EVENT_HAVE_STRSEP */
|
||||
/* #undef EVENT__HAVE_STRSEP */
|
||||
|
||||
/* Define to 1 if you have the `strtok_r' function. */
|
||||
/* #undef _EVENT_HAVE_STRTOK_R */
|
||||
/* #undef EVENT__HAVE_STRTOK_R */
|
||||
|
||||
/* Define to 1 if you have the `strtoll' function. */
|
||||
/* #define _EVENT_HAVE_STRTOLL 1 */
|
||||
/* #define EVENT__HAVE_STRTOLL 1 */
|
||||
|
||||
#define _EVENT_HAVE_STRUCT_ADDRINFO 1
|
||||
#define EVENT__HAVE_STRUCT_ADDRINFO 1
|
||||
|
||||
/* Define to 1 if the system has the type `struct in6_addr'. */
|
||||
#define _EVENT_HAVE_STRUCT_IN6_ADDR 1
|
||||
#define EVENT__HAVE_STRUCT_IN6_ADDR 1
|
||||
|
||||
/* Define to 1 if `s6_addr16' is member of `struct in6_addr'. */
|
||||
#define _EVENT_HAVE_STRUCT_IN6_ADDR_S6_ADDR16 1
|
||||
#define EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR16 1
|
||||
|
||||
/* Define to 1 if `s6_addr32' is member of `struct in6_addr'. */
|
||||
#define _EVENT_HAVE_STRUCT_IN6_ADDR_S6_ADDR32 1
|
||||
#define EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR32 1
|
||||
|
||||
/* Define to 1 if the system has the type `struct sockaddr_in6'. */
|
||||
#define _EVENT_HAVE_STRUCT_SOCKADDR_IN6 1
|
||||
#define EVENT__HAVE_STRUCT_SOCKADDR_IN6 1
|
||||
|
||||
/* Define to 1 if `sin6_len' is member of `struct sockaddr_in6'. */
|
||||
/* #undef _EVENT_HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN */
|
||||
/* #undef EVENT__HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN */
|
||||
|
||||
/* Define to 1 if `sin_len' is member of `struct sockaddr_in'. */
|
||||
/* #undef _EVENT_HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
|
||||
/* #undef EVENT__HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
|
||||
|
||||
/* Define to 1 if the system has the type `struct sockaddr_storage'. */
|
||||
#define _EVENT_HAVE_STRUCT_SOCKADDR_STORAGE 1
|
||||
#define EVENT__HAVE_STRUCT_SOCKADDR_STORAGE 1
|
||||
|
||||
/* Define to 1 if you have the <sys/devpoll.h> header file. */
|
||||
/* #undef _EVENT_HAVE_SYS_DEVPOLL_H */
|
||||
/* #undef EVENT__HAVE_SYS_DEVPOLL_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/epoll.h> header file. */
|
||||
/* #undef _EVENT_HAVE_SYS_EPOLL_H */
|
||||
/* #undef EVENT__HAVE_SYS_EPOLL_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/eventfd.h> header file. */
|
||||
/* #undef _EVENT_HAVE_SYS_EVENTFD_H */
|
||||
/* #undef EVENT__HAVE_SYS_EVENTFD_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/event.h> header file. */
|
||||
/* #undef _EVENT_HAVE_SYS_EVENT_H */
|
||||
/* #undef EVENT__HAVE_SYS_EVENT_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||
/* #undef _EVENT_HAVE_SYS_IOCTL_H */
|
||||
/* #undef EVENT__HAVE_SYS_IOCTL_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||
/* #undef _EVENT_HAVE_SYS_MMAN_H */
|
||||
/* #undef EVENT__HAVE_SYS_MMAN_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
/* #define _EVENT_HAVE_SYS_PARAM_H 1 */
|
||||
/* #define EVENT__HAVE_SYS_PARAM_H 1 */
|
||||
|
||||
/* Define to 1 if you have the <sys/queue.h> header file. */
|
||||
/* #undef _EVENT_HAVE_SYS_QUEUE_H */
|
||||
/* #undef EVENT__HAVE_SYS_QUEUE_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
/* #undef _EVENT_HAVE_SYS_SELECT_H */
|
||||
/* #undef EVENT__HAVE_SYS_SELECT_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/sendfile.h> header file. */
|
||||
/* #undef _EVENT_HAVE_SYS_SENDFILE_H */
|
||||
/* #undef EVENT__HAVE_SYS_SENDFILE_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
/* #undef _EVENT_HAVE_SYS_SOCKET_H */
|
||||
/* #undef EVENT__HAVE_SYS_SOCKET_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_STAT_H 1
|
||||
#define EVENT__HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
/* #define _EVENT_HAVE_SYS_TIME_H 1 */
|
||||
/* #define EVENT__HAVE_SYS_TIME_H 1 */
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_TYPES_H 1
|
||||
#define EVENT__HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/uio.h> header file. */
|
||||
/* #undef _EVENT_HAVE_SYS_UIO_H */
|
||||
/* #undef EVENT__HAVE_SYS_UIO_H */
|
||||
|
||||
/* Define if TAILQ_FOREACH is defined in <sys/queue.h> */
|
||||
/* #undef _EVENT_HAVE_TAILQFOREACH */
|
||||
/* #undef EVENT__HAVE_TAILQFOREACH */
|
||||
|
||||
/* Define if timeradd is defined in <sys/time.h> */
|
||||
/* #undef _EVENT_HAVE_TIMERADD */
|
||||
/* #undef EVENT__HAVE_TIMERADD */
|
||||
|
||||
/* Define if timerclear is defined in <sys/time.h> */
|
||||
#define _EVENT_HAVE_TIMERCLEAR 1
|
||||
#define EVENT__HAVE_TIMERCLEAR 1
|
||||
|
||||
/* Define if timercmp is defined in <sys/time.h> */
|
||||
#define _EVENT_HAVE_TIMERCMP 1
|
||||
#define EVENT__HAVE_TIMERCMP 1
|
||||
|
||||
/* Define if timerisset is defined in <sys/time.h> */
|
||||
#define _EVENT_HAVE_TIMERISSET 1
|
||||
#define EVENT__HAVE_TIMERISSET 1
|
||||
|
||||
/* Define to 1 if the system has the type `uint16_t'. */
|
||||
/* #define _EVENT_HAVE_UINT16_T 1 */
|
||||
/* #define EVENT__HAVE_UINT16_T 1 */
|
||||
|
||||
/* Define to 1 if the system has the type `uint32_t'. */
|
||||
/* #define _EVENT_HAVE_UINT32_T 1 */
|
||||
/* #define EVENT__HAVE_UINT32_T 1 */
|
||||
|
||||
/* Define to 1 if the system has the type `uint64_t'. */
|
||||
/* #define _EVENT_HAVE_UINT64_T 1 */
|
||||
/* #define EVENT__HAVE_UINT64_T 1 */
|
||||
|
||||
/* Define to 1 if the system has the type `uint8_t'. */
|
||||
/* #define _EVENT_HAVE_UINT8_T 1 */
|
||||
/* #define EVENT__HAVE_UINT8_T 1 */
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
/* #define _EVENT_HAVE_UNISTD_H 1 */
|
||||
/* #define EVENT__HAVE_UNISTD_H 1 */
|
||||
|
||||
/* Define to 1 if you have the `vasprintf' function. */
|
||||
/* #undef _EVENT_HAVE_VASPRINTF */
|
||||
/* #undef EVENT__HAVE_VASPRINTF */
|
||||
|
||||
/* Define if kqueue works correctly with pipes */
|
||||
/* #undef _EVENT_HAVE_WORKING_KQUEUE */
|
||||
/* #undef EVENT__HAVE_WORKING_KQUEUE */
|
||||
|
||||
/* Numeric representation of the version */
|
||||
#define _EVENT_NUMERIC_VERSION 0x02001600
|
||||
#define EVENT__NUMERIC_VERSION 0x02010800
|
||||
|
||||
/* Name of package */
|
||||
#define _EVENT_PACKAGE "libevent"
|
||||
#define EVENT__PACKAGE "libevent"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define _EVENT_PACKAGE_BUGREPORT ""
|
||||
#define EVENT__PACKAGE_BUGREPORT ""
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define _EVENT_PACKAGE_NAME ""
|
||||
#define EVENT__PACKAGE_NAME ""
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define _EVENT_PACKAGE_STRING ""
|
||||
#define EVENT__PACKAGE_STRING ""
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define _EVENT_PACKAGE_TARNAME ""
|
||||
#define EVENT__PACKAGE_TARNAME ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define _EVENT_PACKAGE_VERSION ""
|
||||
#define EVENT__PACKAGE_VERSION ""
|
||||
|
||||
/* Define to necessary symbol if this constant uses a non-standard name on
|
||||
your system. */
|
||||
/* #undef _EVENT_PTHREAD_CREATE_JOINABLE */
|
||||
/* #undef EVENT__PTHREAD_CREATE_JOINABLE */
|
||||
|
||||
/* The size of a `int', as computed by sizeof. */
|
||||
#define _EVENT_SIZEOF_INT 4
|
||||
#define EVENT__SIZEOF_INT 4
|
||||
|
||||
/* The size of a `long', as computed by sizeof. */
|
||||
#define _EVENT_SIZEOF_LONG 4
|
||||
#define EVENT__SIZEOF_LONG 4
|
||||
|
||||
/* The size of a `long long', as computed by sizeof. */
|
||||
#define _EVENT_SIZEOF_LONG_LONG 8
|
||||
#define EVENT__SIZEOF_LONG_LONG 8
|
||||
|
||||
/* The size of a `short', as computed by sizeof. */
|
||||
#define _EVENT_SIZEOF_SHORT 2
|
||||
#define EVENT__SIZEOF_SHORT 2
|
||||
|
||||
/* The size of `size_t', as computed by sizeof. */
|
||||
#ifdef _WIN64
|
||||
#define _EVENT_SIZEOF_SIZE_T 8
|
||||
#define EVENT__SIZEOF_SIZE_T 8
|
||||
#else
|
||||
#define _EVENT_SIZEOF_SIZE_T 4
|
||||
#define EVENT__SIZEOF_SIZE_T 4
|
||||
#endif
|
||||
|
||||
/* The size of `void *', as computed by sizeof. */
|
||||
#ifdef _WIN64
|
||||
#define _EVENT_SIZEOF_VOID_P 8
|
||||
#define EVENT__SIZEOF_VOID_P 8
|
||||
#else
|
||||
#define _EVENT_SIZEOF_VOID_P 4
|
||||
#define EVENT__SIZEOF_VOID_P 4
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define _EVENT_STDC_HEADERS 1
|
||||
#define EVENT__STDC_HEADERS 1
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#define _EVENT_TIME_WITH_SYS_TIME 1
|
||||
#define EVENT__TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Version number of package */
|
||||
#define _EVENT_VERSION "2.0.22-stable"
|
||||
#define EVENT__VERSION "2.1.8-stable"
|
||||
|
||||
/* Define to appropriate substitue if compiler doesnt have __func__ */
|
||||
#define _EVENT___func__ __FUNCTION__
|
||||
#define EVENT____func__ __FUNCTION__
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* #undef _EVENT_const */
|
||||
/* #undef EVENT__const */
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef _EVENT___cplusplus
|
||||
#define _EVENT_inline __inline
|
||||
#define EVENT__inline __inline
|
||||
#endif
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
/* #undef _EVENT_pid_t */
|
||||
/* #undef EVENT__pid_t */
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> does not define. */
|
||||
/* #undef _EVENT_size_t */
|
||||
/* #undef EVENT__size_t */
|
||||
|
||||
/* Define to unsigned int if you dont have it */
|
||||
#define _EVENT_socklen_t unsigned int
|
||||
#define EVENT__socklen_t unsigned int
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#define _EVENT_ssize_t SSIZE_T
|
||||
#define EVENT__ssize_t SSIZE_T
|
||||
|
||||
#endif
|
|
@ -675,680 +675,3 @@ name##_RB_MINMAX(struct name *head, int val) \
|
|||
(x) = name##_RB_NEXT(x))
|
||||
|
||||
#endif /* _SYS_TREE_H_ */
|
||||
/* $OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $ */
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_TREE_H_
|
||||
#define _SYS_TREE_H_
|
||||
|
||||
/*
|
||||
* This file defines data structures for different types of trees:
|
||||
* splay trees and red-black trees.
|
||||
*
|
||||
* A splay tree is a self-organizing data structure. Every operation
|
||||
* on the tree causes a splay to happen. The splay moves the requested
|
||||
* node to the root of the tree and partly rebalances it.
|
||||
*
|
||||
* This has the benefit that request locality causes faster lookups as
|
||||
* the requested nodes move to the top of the tree. On the other hand,
|
||||
* every lookup causes memory writes.
|
||||
*
|
||||
* The Balance Theorem bounds the total access time for m operations
|
||||
* and n inserts on an initially empty tree as O((m + n)lg n). The
|
||||
* amortized cost for a sequence of m accesses to a splay tree is O(lg n);
|
||||
*
|
||||
* A red-black tree is a binary search tree with the node color as an
|
||||
* extra attribute. It fulfills a set of conditions:
|
||||
* - every search path from the root to a leaf consists of the
|
||||
* same number of black nodes,
|
||||
* - each red node (except for the root) has a black parent,
|
||||
* - each leaf node is black.
|
||||
*
|
||||
* Every operation on a red-black tree is bounded as O(lg n).
|
||||
* The maximum height of a red-black tree is 2lg (n+1).
|
||||
*/
|
||||
|
||||
#define SPLAY_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *sph_root; /* root of the tree */ \
|
||||
}
|
||||
|
||||
#define SPLAY_INITIALIZER(root) \
|
||||
{ NULL }
|
||||
|
||||
#define SPLAY_INIT(root) do { \
|
||||
(root)->sph_root = NULL; \
|
||||
} while (0)
|
||||
|
||||
#define SPLAY_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *spe_left; /* left element */ \
|
||||
struct type *spe_right; /* right element */ \
|
||||
}
|
||||
|
||||
#define SPLAY_LEFT(elm, field) (elm)->field.spe_left
|
||||
#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right
|
||||
#define SPLAY_ROOT(head) (head)->sph_root
|
||||
#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL)
|
||||
|
||||
/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
|
||||
#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \
|
||||
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \
|
||||
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
|
||||
(head)->sph_root = tmp; \
|
||||
} while (0)
|
||||
|
||||
#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \
|
||||
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \
|
||||
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
|
||||
(head)->sph_root = tmp; \
|
||||
} while (0)
|
||||
|
||||
#define SPLAY_LINKLEFT(head, tmp, field) do { \
|
||||
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
|
||||
tmp = (head)->sph_root; \
|
||||
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
|
||||
} while (0)
|
||||
|
||||
#define SPLAY_LINKRIGHT(head, tmp, field) do { \
|
||||
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
|
||||
tmp = (head)->sph_root; \
|
||||
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
|
||||
} while (0)
|
||||
|
||||
#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \
|
||||
SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \
|
||||
SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\
|
||||
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \
|
||||
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \
|
||||
} while (0)
|
||||
|
||||
/* Generates prototypes and inline functions */
|
||||
|
||||
#define SPLAY_PROTOTYPE(name, type, field, cmp) \
|
||||
void name##_SPLAY(struct name *, struct type *); \
|
||||
void name##_SPLAY_MINMAX(struct name *, int); \
|
||||
struct type *name##_SPLAY_INSERT(struct name *, struct type *); \
|
||||
struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \
|
||||
\
|
||||
/* Finds the node with the same key as elm */ \
|
||||
static __inline struct type * \
|
||||
name##_SPLAY_FIND(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
if (SPLAY_EMPTY(head)) \
|
||||
return(NULL); \
|
||||
name##_SPLAY(head, elm); \
|
||||
if ((cmp)(elm, (head)->sph_root) == 0) \
|
||||
return (head->sph_root); \
|
||||
return (NULL); \
|
||||
} \
|
||||
\
|
||||
static __inline struct type * \
|
||||
name##_SPLAY_NEXT(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
name##_SPLAY(head, elm); \
|
||||
if (SPLAY_RIGHT(elm, field) != NULL) { \
|
||||
elm = SPLAY_RIGHT(elm, field); \
|
||||
while (SPLAY_LEFT(elm, field) != NULL) { \
|
||||
elm = SPLAY_LEFT(elm, field); \
|
||||
} \
|
||||
} else \
|
||||
elm = NULL; \
|
||||
return (elm); \
|
||||
} \
|
||||
\
|
||||
static __inline struct type * \
|
||||
name##_SPLAY_MIN_MAX(struct name *head, int val) \
|
||||
{ \
|
||||
name##_SPLAY_MINMAX(head, val); \
|
||||
return (SPLAY_ROOT(head)); \
|
||||
}
|
||||
|
||||
/* Main splay operation.
|
||||
* Moves node close to the key of elm to top
|
||||
*/
|
||||
#define SPLAY_GENERATE(name, type, field, cmp) \
|
||||
struct type * \
|
||||
name##_SPLAY_INSERT(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
if (SPLAY_EMPTY(head)) { \
|
||||
SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \
|
||||
} else { \
|
||||
int __comp; \
|
||||
name##_SPLAY(head, elm); \
|
||||
__comp = (cmp)(elm, (head)->sph_root); \
|
||||
if(__comp < 0) { \
|
||||
SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\
|
||||
SPLAY_RIGHT(elm, field) = (head)->sph_root; \
|
||||
SPLAY_LEFT((head)->sph_root, field) = NULL; \
|
||||
} else if (__comp > 0) { \
|
||||
SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\
|
||||
SPLAY_LEFT(elm, field) = (head)->sph_root; \
|
||||
SPLAY_RIGHT((head)->sph_root, field) = NULL; \
|
||||
} else \
|
||||
return ((head)->sph_root); \
|
||||
} \
|
||||
(head)->sph_root = (elm); \
|
||||
return (NULL); \
|
||||
} \
|
||||
\
|
||||
struct type * \
|
||||
name##_SPLAY_REMOVE(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *__tmp; \
|
||||
if (SPLAY_EMPTY(head)) \
|
||||
return (NULL); \
|
||||
name##_SPLAY(head, elm); \
|
||||
if ((cmp)(elm, (head)->sph_root) == 0) { \
|
||||
if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \
|
||||
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\
|
||||
} else { \
|
||||
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
|
||||
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\
|
||||
name##_SPLAY(head, elm); \
|
||||
SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
|
||||
} \
|
||||
return (elm); \
|
||||
} \
|
||||
return (NULL); \
|
||||
} \
|
||||
\
|
||||
void \
|
||||
name##_SPLAY(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type __node, *__left, *__right, *__tmp; \
|
||||
int __comp; \
|
||||
\
|
||||
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
|
||||
__left = __right = &__node; \
|
||||
\
|
||||
while ((__comp = (cmp)(elm, (head)->sph_root))) { \
|
||||
if (__comp < 0) { \
|
||||
__tmp = SPLAY_LEFT((head)->sph_root, field); \
|
||||
if (__tmp == NULL) \
|
||||
break; \
|
||||
if ((cmp)(elm, __tmp) < 0){ \
|
||||
SPLAY_ROTATE_RIGHT(head, __tmp, field); \
|
||||
if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
|
||||
break; \
|
||||
} \
|
||||
SPLAY_LINKLEFT(head, __right, field); \
|
||||
} else if (__comp > 0) { \
|
||||
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
|
||||
if (__tmp == NULL) \
|
||||
break; \
|
||||
if ((cmp)(elm, __tmp) > 0){ \
|
||||
SPLAY_ROTATE_LEFT(head, __tmp, field); \
|
||||
if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
|
||||
break; \
|
||||
} \
|
||||
SPLAY_LINKRIGHT(head, __left, field); \
|
||||
} \
|
||||
} \
|
||||
SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
|
||||
} \
|
||||
\
|
||||
/* Splay with either the minimum or the maximum element \
|
||||
* Used to find minimum or maximum element in tree. \
|
||||
*/ \
|
||||
void name##_SPLAY_MINMAX(struct name *head, int __comp) \
|
||||
{ \
|
||||
struct type __node, *__left, *__right, *__tmp; \
|
||||
\
|
||||
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
|
||||
__left = __right = &__node; \
|
||||
\
|
||||
while (1) { \
|
||||
if (__comp < 0) { \
|
||||
__tmp = SPLAY_LEFT((head)->sph_root, field); \
|
||||
if (__tmp == NULL) \
|
||||
break; \
|
||||
if (__comp < 0){ \
|
||||
SPLAY_ROTATE_RIGHT(head, __tmp, field); \
|
||||
if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
|
||||
break; \
|
||||
} \
|
||||
SPLAY_LINKLEFT(head, __right, field); \
|
||||
} else if (__comp > 0) { \
|
||||
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
|
||||
if (__tmp == NULL) \
|
||||
break; \
|
||||
if (__comp > 0) { \
|
||||
SPLAY_ROTATE_LEFT(head, __tmp, field); \
|
||||
if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
|
||||
break; \
|
||||
} \
|
||||
SPLAY_LINKRIGHT(head, __left, field); \
|
||||
} \
|
||||
} \
|
||||
SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
|
||||
}
|
||||
|
||||
#define SPLAY_NEGINF -1
|
||||
#define SPLAY_INF 1
|
||||
|
||||
#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y)
|
||||
#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y)
|
||||
#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y)
|
||||
#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y)
|
||||
#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \
|
||||
: name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
|
||||
#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \
|
||||
: name##_SPLAY_MIN_MAX(x, SPLAY_INF))
|
||||
|
||||
#define SPLAY_FOREACH(x, name, head) \
|
||||
for ((x) = SPLAY_MIN(name, head); \
|
||||
(x) != NULL; \
|
||||
(x) = SPLAY_NEXT(name, head, x))
|
||||
|
||||
/* Macros that define a red-back tree */
|
||||
#define RB_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *rbh_root; /* root of the tree */ \
|
||||
}
|
||||
|
||||
#define RB_INITIALIZER(root) \
|
||||
{ NULL }
|
||||
|
||||
#define RB_INIT(root) do { \
|
||||
(root)->rbh_root = NULL; \
|
||||
} while (0)
|
||||
|
||||
#define RB_BLACK 0
|
||||
#define RB_RED 1
|
||||
#define RB_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *rbe_left; /* left element */ \
|
||||
struct type *rbe_right; /* right element */ \
|
||||
struct type *rbe_parent; /* parent element */ \
|
||||
int rbe_color; /* node color */ \
|
||||
}
|
||||
|
||||
#define RB_LEFT(elm, field) (elm)->field.rbe_left
|
||||
#define RB_RIGHT(elm, field) (elm)->field.rbe_right
|
||||
#define RB_PARENT(elm, field) (elm)->field.rbe_parent
|
||||
#define RB_COLOR(elm, field) (elm)->field.rbe_color
|
||||
#define RB_ROOT(head) (head)->rbh_root
|
||||
#define RB_EMPTY(head) (RB_ROOT(head) == NULL)
|
||||
|
||||
#define RB_SET(elm, parent, field) do { \
|
||||
RB_PARENT(elm, field) = parent; \
|
||||
RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \
|
||||
RB_COLOR(elm, field) = RB_RED; \
|
||||
} while (0)
|
||||
|
||||
#define RB_SET_BLACKRED(black, red, field) do { \
|
||||
RB_COLOR(black, field) = RB_BLACK; \
|
||||
RB_COLOR(red, field) = RB_RED; \
|
||||
} while (0)
|
||||
|
||||
#ifndef RB_AUGMENT
|
||||
#define RB_AUGMENT(x)
|
||||
#endif
|
||||
|
||||
#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \
|
||||
(tmp) = RB_RIGHT(elm, field); \
|
||||
if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) { \
|
||||
RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \
|
||||
} \
|
||||
RB_AUGMENT(elm); \
|
||||
if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \
|
||||
if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
|
||||
RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
|
||||
else \
|
||||
RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
|
||||
} else \
|
||||
(head)->rbh_root = (tmp); \
|
||||
RB_LEFT(tmp, field) = (elm); \
|
||||
RB_PARENT(elm, field) = (tmp); \
|
||||
RB_AUGMENT(tmp); \
|
||||
if ((RB_PARENT(tmp, field))) \
|
||||
RB_AUGMENT(RB_PARENT(tmp, field)); \
|
||||
} while (0)
|
||||
|
||||
#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \
|
||||
(tmp) = RB_LEFT(elm, field); \
|
||||
if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) { \
|
||||
RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \
|
||||
} \
|
||||
RB_AUGMENT(elm); \
|
||||
if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \
|
||||
if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
|
||||
RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
|
||||
else \
|
||||
RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
|
||||
} else \
|
||||
(head)->rbh_root = (tmp); \
|
||||
RB_RIGHT(tmp, field) = (elm); \
|
||||
RB_PARENT(elm, field) = (tmp); \
|
||||
RB_AUGMENT(tmp); \
|
||||
if ((RB_PARENT(tmp, field))) \
|
||||
RB_AUGMENT(RB_PARENT(tmp, field)); \
|
||||
} while (0)
|
||||
|
||||
/* Generates prototypes and inline functions */
|
||||
#define RB_PROTOTYPE(name, type, field, cmp) \
|
||||
void name##_RB_INSERT_COLOR(struct name *, struct type *); \
|
||||
void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
|
||||
struct type *name##_RB_REMOVE(struct name *, struct type *); \
|
||||
struct type *name##_RB_INSERT(struct name *, struct type *); \
|
||||
struct type *name##_RB_FIND(struct name *, struct type *); \
|
||||
struct type *name##_RB_NEXT(struct type *); \
|
||||
struct type *name##_RB_MINMAX(struct name *, int); \
|
||||
\
|
||||
|
||||
/* Main rb operation.
|
||||
* Moves node close to the key of elm to top
|
||||
*/
|
||||
#define RB_GENERATE(name, type, field, cmp) \
|
||||
void \
|
||||
name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *parent, *gparent, *tmp; \
|
||||
while ((parent = RB_PARENT(elm, field)) && \
|
||||
RB_COLOR(parent, field) == RB_RED) { \
|
||||
gparent = RB_PARENT(parent, field); \
|
||||
if (parent == RB_LEFT(gparent, field)) { \
|
||||
tmp = RB_RIGHT(gparent, field); \
|
||||
if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
|
||||
RB_COLOR(tmp, field) = RB_BLACK; \
|
||||
RB_SET_BLACKRED(parent, gparent, field);\
|
||||
elm = gparent; \
|
||||
continue; \
|
||||
} \
|
||||
if (RB_RIGHT(parent, field) == elm) { \
|
||||
RB_ROTATE_LEFT(head, parent, tmp, field);\
|
||||
tmp = parent; \
|
||||
parent = elm; \
|
||||
elm = tmp; \
|
||||
} \
|
||||
RB_SET_BLACKRED(parent, gparent, field); \
|
||||
RB_ROTATE_RIGHT(head, gparent, tmp, field); \
|
||||
} else { \
|
||||
tmp = RB_LEFT(gparent, field); \
|
||||
if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
|
||||
RB_COLOR(tmp, field) = RB_BLACK; \
|
||||
RB_SET_BLACKRED(parent, gparent, field);\
|
||||
elm = gparent; \
|
||||
continue; \
|
||||
} \
|
||||
if (RB_LEFT(parent, field) == elm) { \
|
||||
RB_ROTATE_RIGHT(head, parent, tmp, field);\
|
||||
tmp = parent; \
|
||||
parent = elm; \
|
||||
elm = tmp; \
|
||||
} \
|
||||
RB_SET_BLACKRED(parent, gparent, field); \
|
||||
RB_ROTATE_LEFT(head, gparent, tmp, field); \
|
||||
} \
|
||||
} \
|
||||
RB_COLOR(head->rbh_root, field) = RB_BLACK; \
|
||||
} \
|
||||
\
|
||||
void \
|
||||
name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
|
||||
{ \
|
||||
struct type *tmp; \
|
||||
while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \
|
||||
elm != RB_ROOT(head)) { \
|
||||
if (RB_LEFT(parent, field) == elm) { \
|
||||
tmp = RB_RIGHT(parent, field); \
|
||||
if (RB_COLOR(tmp, field) == RB_RED) { \
|
||||
RB_SET_BLACKRED(tmp, parent, field); \
|
||||
RB_ROTATE_LEFT(head, parent, tmp, field);\
|
||||
tmp = RB_RIGHT(parent, field); \
|
||||
} \
|
||||
if ((RB_LEFT(tmp, field) == NULL || \
|
||||
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
|
||||
(RB_RIGHT(tmp, field) == NULL || \
|
||||
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
|
||||
RB_COLOR(tmp, field) = RB_RED; \
|
||||
elm = parent; \
|
||||
parent = RB_PARENT(elm, field); \
|
||||
} else { \
|
||||
if (RB_RIGHT(tmp, field) == NULL || \
|
||||
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\
|
||||
struct type *oleft; \
|
||||
if ((oleft = RB_LEFT(tmp, field)))\
|
||||
RB_COLOR(oleft, field) = RB_BLACK;\
|
||||
RB_COLOR(tmp, field) = RB_RED; \
|
||||
RB_ROTATE_RIGHT(head, tmp, oleft, field);\
|
||||
tmp = RB_RIGHT(parent, field); \
|
||||
} \
|
||||
RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
|
||||
RB_COLOR(parent, field) = RB_BLACK; \
|
||||
if (RB_RIGHT(tmp, field)) \
|
||||
RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\
|
||||
RB_ROTATE_LEFT(head, parent, tmp, field);\
|
||||
elm = RB_ROOT(head); \
|
||||
break; \
|
||||
} \
|
||||
} else { \
|
||||
tmp = RB_LEFT(parent, field); \
|
||||
if (RB_COLOR(tmp, field) == RB_RED) { \
|
||||
RB_SET_BLACKRED(tmp, parent, field); \
|
||||
RB_ROTATE_RIGHT(head, parent, tmp, field);\
|
||||
tmp = RB_LEFT(parent, field); \
|
||||
} \
|
||||
if ((RB_LEFT(tmp, field) == NULL || \
|
||||
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
|
||||
(RB_RIGHT(tmp, field) == NULL || \
|
||||
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
|
||||
RB_COLOR(tmp, field) = RB_RED; \
|
||||
elm = parent; \
|
||||
parent = RB_PARENT(elm, field); \
|
||||
} else { \
|
||||
if (RB_LEFT(tmp, field) == NULL || \
|
||||
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\
|
||||
struct type *oright; \
|
||||
if ((oright = RB_RIGHT(tmp, field)))\
|
||||
RB_COLOR(oright, field) = RB_BLACK;\
|
||||
RB_COLOR(tmp, field) = RB_RED; \
|
||||
RB_ROTATE_LEFT(head, tmp, oright, field);\
|
||||
tmp = RB_LEFT(parent, field); \
|
||||
} \
|
||||
RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
|
||||
RB_COLOR(parent, field) = RB_BLACK; \
|
||||
if (RB_LEFT(tmp, field)) \
|
||||
RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\
|
||||
RB_ROTATE_RIGHT(head, parent, tmp, field);\
|
||||
elm = RB_ROOT(head); \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
if (elm) \
|
||||
RB_COLOR(elm, field) = RB_BLACK; \
|
||||
} \
|
||||
\
|
||||
struct type * \
|
||||
name##_RB_REMOVE(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *child, *parent, *old = elm; \
|
||||
int color; \
|
||||
if (RB_LEFT(elm, field) == NULL) \
|
||||
child = RB_RIGHT(elm, field); \
|
||||
else if (RB_RIGHT(elm, field) == NULL) \
|
||||
child = RB_LEFT(elm, field); \
|
||||
else { \
|
||||
struct type *left; \
|
||||
elm = RB_RIGHT(elm, field); \
|
||||
while ((left = RB_LEFT(elm, field))) \
|
||||
elm = left; \
|
||||
child = RB_RIGHT(elm, field); \
|
||||
parent = RB_PARENT(elm, field); \
|
||||
color = RB_COLOR(elm, field); \
|
||||
if (child) \
|
||||
RB_PARENT(child, field) = parent; \
|
||||
if (parent) { \
|
||||
if (RB_LEFT(parent, field) == elm) \
|
||||
RB_LEFT(parent, field) = child; \
|
||||
else \
|
||||
RB_RIGHT(parent, field) = child; \
|
||||
RB_AUGMENT(parent); \
|
||||
} else \
|
||||
RB_ROOT(head) = child; \
|
||||
if (RB_PARENT(elm, field) == old) \
|
||||
parent = elm; \
|
||||
(elm)->field = (old)->field; \
|
||||
if (RB_PARENT(old, field)) { \
|
||||
if (RB_LEFT(RB_PARENT(old, field), field) == old)\
|
||||
RB_LEFT(RB_PARENT(old, field), field) = elm;\
|
||||
else \
|
||||
RB_RIGHT(RB_PARENT(old, field), field) = elm;\
|
||||
RB_AUGMENT(RB_PARENT(old, field)); \
|
||||
} else \
|
||||
RB_ROOT(head) = elm; \
|
||||
RB_PARENT(RB_LEFT(old, field), field) = elm; \
|
||||
if (RB_RIGHT(old, field)) \
|
||||
RB_PARENT(RB_RIGHT(old, field), field) = elm; \
|
||||
if (parent) { \
|
||||
left = parent; \
|
||||
do { \
|
||||
RB_AUGMENT(left); \
|
||||
} while ((left = RB_PARENT(left, field))); \
|
||||
} \
|
||||
goto color; \
|
||||
} \
|
||||
parent = RB_PARENT(elm, field); \
|
||||
color = RB_COLOR(elm, field); \
|
||||
if (child) \
|
||||
RB_PARENT(child, field) = parent; \
|
||||
if (parent) { \
|
||||
if (RB_LEFT(parent, field) == elm) \
|
||||
RB_LEFT(parent, field) = child; \
|
||||
else \
|
||||
RB_RIGHT(parent, field) = child; \
|
||||
RB_AUGMENT(parent); \
|
||||
} else \
|
||||
RB_ROOT(head) = child; \
|
||||
color: \
|
||||
if (color == RB_BLACK) \
|
||||
name##_RB_REMOVE_COLOR(head, parent, child); \
|
||||
return (old); \
|
||||
} \
|
||||
\
|
||||
/* Inserts a node into the RB tree */ \
|
||||
struct type * \
|
||||
name##_RB_INSERT(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *tmp; \
|
||||
struct type *parent = NULL; \
|
||||
int comp = 0; \
|
||||
tmp = RB_ROOT(head); \
|
||||
while (tmp) { \
|
||||
parent = tmp; \
|
||||
comp = (cmp)(elm, parent); \
|
||||
if (comp < 0) \
|
||||
tmp = RB_LEFT(tmp, field); \
|
||||
else if (comp > 0) \
|
||||
tmp = RB_RIGHT(tmp, field); \
|
||||
else \
|
||||
return (tmp); \
|
||||
} \
|
||||
RB_SET(elm, parent, field); \
|
||||
if (parent != NULL) { \
|
||||
if (comp < 0) \
|
||||
RB_LEFT(parent, field) = elm; \
|
||||
else \
|
||||
RB_RIGHT(parent, field) = elm; \
|
||||
RB_AUGMENT(parent); \
|
||||
} else \
|
||||
RB_ROOT(head) = elm; \
|
||||
name##_RB_INSERT_COLOR(head, elm); \
|
||||
return (NULL); \
|
||||
} \
|
||||
\
|
||||
/* Finds the node with the same key as elm */ \
|
||||
struct type * \
|
||||
name##_RB_FIND(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *tmp = RB_ROOT(head); \
|
||||
int comp; \
|
||||
while (tmp) { \
|
||||
comp = cmp(elm, tmp); \
|
||||
if (comp < 0) \
|
||||
tmp = RB_LEFT(tmp, field); \
|
||||
else if (comp > 0) \
|
||||
tmp = RB_RIGHT(tmp, field); \
|
||||
else \
|
||||
return (tmp); \
|
||||
} \
|
||||
return (NULL); \
|
||||
} \
|
||||
\
|
||||
struct type * \
|
||||
name##_RB_NEXT(struct type *elm) \
|
||||
{ \
|
||||
if (RB_RIGHT(elm, field)) { \
|
||||
elm = RB_RIGHT(elm, field); \
|
||||
while (RB_LEFT(elm, field)) \
|
||||
elm = RB_LEFT(elm, field); \
|
||||
} else { \
|
||||
if (RB_PARENT(elm, field) && \
|
||||
(elm == RB_LEFT(RB_PARENT(elm, field), field))) \
|
||||
elm = RB_PARENT(elm, field); \
|
||||
else { \
|
||||
while (RB_PARENT(elm, field) && \
|
||||
(elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
|
||||
elm = RB_PARENT(elm, field); \
|
||||
elm = RB_PARENT(elm, field); \
|
||||
} \
|
||||
} \
|
||||
return (elm); \
|
||||
} \
|
||||
\
|
||||
struct type * \
|
||||
name##_RB_MINMAX(struct name *head, int val) \
|
||||
{ \
|
||||
struct type *tmp = RB_ROOT(head); \
|
||||
struct type *parent = NULL; \
|
||||
while (tmp) { \
|
||||
parent = tmp; \
|
||||
if (val < 0) \
|
||||
tmp = RB_LEFT(tmp, field); \
|
||||
else \
|
||||
tmp = RB_RIGHT(tmp, field); \
|
||||
} \
|
||||
return (parent); \
|
||||
}
|
||||
|
||||
#define RB_NEGINF -1
|
||||
#define RB_INF 1
|
||||
|
||||
#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
|
||||
#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
|
||||
#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
|
||||
#define RB_NEXT(name, x, y) name##_RB_NEXT(y)
|
||||
#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF)
|
||||
#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF)
|
||||
|
||||
#define RB_FOREACH(x, name, head) \
|
||||
for ((x) = RB_MIN(name, head); \
|
||||
(x) != NULL; \
|
||||
(x) = name##_RB_NEXT(x))
|
||||
|
||||
#endif /* _SYS_TREE_H_ */
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -8,395 +8,439 @@
|
|||
* Do not rely on macros in this file existing in later versions.
|
||||
*/
|
||||
|
||||
#ifndef _EVENT2_EVENT_CONFIG_H_
|
||||
#define _EVENT2_EVENT_CONFIG_H_
|
||||
#ifndef EVENT2_EVENT_CONFIG_H_INCLUDED_
|
||||
#define EVENT2_EVENT_CONFIG_H_INCLUDED_
|
||||
|
||||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define if libevent should build without support for a debug mode */
|
||||
/* #undef _EVENT_DISABLE_DEBUG_MODE */
|
||||
/* #undef EVENT__DISABLE_DEBUG_MODE */
|
||||
|
||||
/* Define if libevent should not allow replacing the mm functions */
|
||||
/* #undef _EVENT_DISABLE_MM_REPLACEMENT */
|
||||
/* #undef EVENT__DISABLE_MM_REPLACEMENT */
|
||||
|
||||
/* Define if libevent should not be compiled with thread support */
|
||||
/* #undef _EVENT_DISABLE_THREAD_SUPPORT */
|
||||
/* #undef EVENT__DISABLE_THREAD_SUPPORT */
|
||||
|
||||
/* Define to 1 if you have the `accept4' function. */
|
||||
#define EVENT__HAVE_ACCEPT4 1
|
||||
|
||||
/* Define to 1 if you have the `arc4random' function. */
|
||||
#define _EVENT_HAVE_ARC4RANDOM 1
|
||||
#define EVENT__HAVE_ARC4RANDOM 1
|
||||
|
||||
/* Define to 1 if you have the `arc4random_buf' function. */
|
||||
/* #undef _EVENT_HAVE_ARC4RANDOM_BUF */
|
||||
/* #undef EVENT__HAVE_ARC4RANDOM_BUF */
|
||||
|
||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
#define _EVENT_HAVE_ARPA_INET_H 1
|
||||
#define EVENT__HAVE_ARPA_INET_H 1
|
||||
|
||||
/* Define to 1 if you have the `clock_gettime' function. */
|
||||
#define _EVENT_HAVE_CLOCK_GETTIME 1
|
||||
#define EVENT__HAVE_CLOCK_GETTIME 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `CTL_KERN', and to 0 if you
|
||||
don't. */
|
||||
/* #undef _EVENT_HAVE_DECL_CTL_KERN */
|
||||
/* #undef EVENT__HAVE_DECL_CTL_KERN */
|
||||
|
||||
/* Define to 1 if you have the declaration of `KERN_ARND', and to 0 if you
|
||||
don't. */
|
||||
/* #undef _EVENT_HAVE_DECL_KERN_ARND */
|
||||
/* #undef EVENT__HAVE_DECL_KERN_ARND */
|
||||
|
||||
/* Define to 1 if you have the declaration of `KERN_RANDOM', and to 0 if you
|
||||
don't. */
|
||||
/* #undef _EVENT_HAVE_DECL_KERN_RANDOM */
|
||||
/* #undef EVENT__HAVE_DECL_KERN_RANDOM */
|
||||
|
||||
/* Define to 1 if you have the declaration of `RANDOM_UUID', and to 0 if you
|
||||
don't. */
|
||||
/* #undef _EVENT_HAVE_DECL_RANDOM_UUID */
|
||||
/* #undef EVENT__HAVE_DECL_RANDOM_UUID */
|
||||
|
||||
/* Define if /dev/poll is available */
|
||||
/* #undef _EVENT_HAVE_DEVPOLL */
|
||||
/* #undef EVENT__HAVE_DEVPOLL */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define _EVENT_HAVE_DLFCN_H 1
|
||||
#define EVENT__HAVE_DLFCN_H 1
|
||||
|
||||
/* Define if your system supports the epoll system calls */
|
||||
#define _EVENT_HAVE_EPOLL 1
|
||||
#define EVENT__HAVE_EPOLL 1
|
||||
|
||||
/* Define to 1 if you have the `epoll_create1' function. */
|
||||
/* #undef EVENT__HAVE_EPOLL_CREATE1 */
|
||||
|
||||
/* Define to 1 if you have the `epoll_ctl' function. */
|
||||
#define _EVENT_HAVE_EPOLL_CTL 1
|
||||
#define EVENT__HAVE_EPOLL_CTL 1
|
||||
|
||||
/* Define to 1 if you have the <errno.h> header file. */
|
||||
#define EVENT__HAVE_ERRNO_H 1
|
||||
|
||||
/* Define to 1 if you have ERR_remove_thread_stat(). */
|
||||
/* #undef EVENT__HAVE_ERR_REMOVE_THREAD_STATE */
|
||||
|
||||
/* Define to 1 if you have the `eventfd' function. */
|
||||
#define _EVENT_HAVE_EVENTFD 1
|
||||
#define EVENT__HAVE_EVENTFD 1
|
||||
|
||||
/* Define if your system supports event ports */
|
||||
/* #undef _EVENT_HAVE_EVENT_PORTS */
|
||||
/* #undef EVENT__HAVE_EVENT_PORTS */
|
||||
|
||||
/* Define to 1 if you have the `fcntl' function. */
|
||||
#define _EVENT_HAVE_FCNTL 1
|
||||
#define EVENT__HAVE_FCNTL 1
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define _EVENT_HAVE_FCNTL_H 1
|
||||
#define EVENT__HAVE_FCNTL_H 1
|
||||
|
||||
/* Define to 1 if the system has the type `fd_mask'. */
|
||||
/* #undef _EVENT_HAVE_FD_MASK */
|
||||
/* #undef EVENT__HAVE_FD_MASK */
|
||||
|
||||
/* Do we have getaddrinfo()? */
|
||||
#define _EVENT_HAVE_GETADDRINFO 1
|
||||
#define EVENT__HAVE_GETADDRINFO 1
|
||||
|
||||
/* Define to 1 if you have the `getegid' function. */
|
||||
#define _EVENT_HAVE_GETEGID 1
|
||||
#define EVENT__HAVE_GETEGID 1
|
||||
|
||||
/* Define to 1 if you have the `geteuid' function. */
|
||||
#define _EVENT_HAVE_GETEUID 1
|
||||
#define EVENT__HAVE_GETEUID 1
|
||||
|
||||
/* Define this if you have any gethostbyname_r() */
|
||||
/* #undef _EVENT_HAVE_GETHOSTBYNAME_R */
|
||||
/* #undef EVENT__HAVE_GETHOSTBYNAME_R */
|
||||
|
||||
/* Define this if gethostbyname_r takes 3 arguments */
|
||||
/* #undef _EVENT_HAVE_GETHOSTBYNAME_R_3_ARG */
|
||||
/* #undef EVENT__HAVE_GETHOSTBYNAME_R_3_ARG */
|
||||
|
||||
/* Define this if gethostbyname_r takes 5 arguments */
|
||||
/* #undef _EVENT_HAVE_GETHOSTBYNAME_R_5_ARG */
|
||||
/* #undef EVENT__HAVE_GETHOSTBYNAME_R_5_ARG */
|
||||
|
||||
/* Define this if gethostbyname_r takes 6 arguments */
|
||||
/* #undef _EVENT_HAVE_GETHOSTBYNAME_R_6_ARG */
|
||||
/* #undef EVENT__HAVE_GETHOSTBYNAME_R_6_ARG */
|
||||
|
||||
/* Define to 1 if you have the `getifaddrs' function. */
|
||||
/* #undef EVENT__HAVE_GETIFADDRS */
|
||||
|
||||
/* Define to 1 if you have the `getnameinfo' function. */
|
||||
#define _EVENT_HAVE_GETNAMEINFO 1
|
||||
#define EVENT__HAVE_GETNAMEINFO 1
|
||||
|
||||
/* Define to 1 if you have the `getprotobynumber' function. */
|
||||
#define _EVENT_HAVE_GETPROTOBYNUMBER 1
|
||||
#define EVENT__HAVE_GETPROTOBYNUMBER 1
|
||||
|
||||
/* Define to 1 if you have the `getservbyname' function. */
|
||||
/* #undef _EVENT_HAVE_GETSERVBYNAME */
|
||||
#define EVENT__HAVE_GETSERVBYNAME 1
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
#define _EVENT_HAVE_GETTIMEOFDAY 1
|
||||
#define EVENT__HAVE_GETTIMEOFDAY 1
|
||||
|
||||
/* Define to 1 if you have the `inet_aton' function. */
|
||||
#define _EVENT_HAVE_INET_ATON 1
|
||||
/* Define to 1 if you have the <ifaddrs.h> header file. */
|
||||
/* #undef EVENT__HAVE_IFADDRS_H */
|
||||
|
||||
/* Define to 1 if you have the `inet_ntop' function. */
|
||||
#define _EVENT_HAVE_INET_NTOP 1
|
||||
#define EVENT__HAVE_INET_NTOP 1
|
||||
|
||||
/* Define to 1 if you have the `inet_pton' function. */
|
||||
#define _EVENT_HAVE_INET_PTON 1
|
||||
#define EVENT__HAVE_INET_PTON 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define _EVENT_HAVE_INTTYPES_H 1
|
||||
#define EVENT__HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the `issetugid' function. */
|
||||
/* #undef _EVENT_HAVE_ISSETUGID */
|
||||
/* #undef EVENT__HAVE_ISSETUGID */
|
||||
|
||||
/* Define to 1 if you have the `kqueue' function. */
|
||||
/* #undef _EVENT_HAVE_KQUEUE */
|
||||
/* #undef EVENT__HAVE_KQUEUE */
|
||||
|
||||
/* Define if the system has zlib */
|
||||
#define _EVENT_HAVE_LIBZ 1
|
||||
#define EVENT__HAVE_LIBZ 1
|
||||
|
||||
/* Define to 1 if you have the `mach_absolute_time' function. */
|
||||
/* #undef EVENT__HAVE_MACH_ABSOLUTE_TIME */
|
||||
|
||||
/* Define to 1 if you have the <mach/mach_time.h> header file. */
|
||||
/* #undef EVENT__HAVE_MACH_MACH_TIME_H */
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define _EVENT_HAVE_MEMORY_H 1
|
||||
#define EVENT__HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the `mmap' function. */
|
||||
#define _EVENT_HAVE_MMAP 1
|
||||
#define EVENT__HAVE_MMAP 1
|
||||
|
||||
/* Define to 1 if you have the `nanosleep' function. */
|
||||
#define EVENT__HAVE_NANOSLEEP 1
|
||||
|
||||
/* Define to 1 if you have the <netdb.h> header file. */
|
||||
#define _EVENT_HAVE_NETDB_H 1
|
||||
#define EVENT__HAVE_NETDB_H 1
|
||||
|
||||
/* Define to 1 if you have the <netinet/in6.h> header file. */
|
||||
#define _EVENT_HAVE_NETINET_IN6_H 1
|
||||
#define EVENT__HAVE_NETINET_IN6_H 1
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#define _EVENT_HAVE_NETINET_IN_H 1
|
||||
#define EVENT__HAVE_NETINET_IN_H 1
|
||||
|
||||
/* Define to 1 if you have the <netinet/tcp.h> header file. */
|
||||
#define EVENT__HAVE_NETINET_TCP_H 1
|
||||
|
||||
/* Define if the system has openssl */
|
||||
/* #undef _EVENT_HAVE_OPENSSL */
|
||||
|
||||
/* Define to 1 if you have the <openssl/bio.h> header file. */
|
||||
/* #undef _EVENT_HAVE_OPENSSL_BIO_H */
|
||||
/* #undef EVENT__HAVE_OPENSSL */
|
||||
|
||||
/* Define to 1 if you have the `pipe' function. */
|
||||
#define _EVENT_HAVE_PIPE 1
|
||||
#define EVENT__HAVE_PIPE 1
|
||||
|
||||
/* Define to 1 if you have the `pipe2' function. */
|
||||
#define EVENT__HAVE_PIPE2 1
|
||||
|
||||
/* Define to 1 if you have the `poll' function. */
|
||||
#define _EVENT_HAVE_POLL 1
|
||||
#define EVENT__HAVE_POLL 1
|
||||
|
||||
/* Define to 1 if you have the <poll.h> header file. */
|
||||
#define _EVENT_HAVE_POLL_H 1
|
||||
#define EVENT__HAVE_POLL_H 1
|
||||
|
||||
/* Define to 1 if you have the `port_create' function. */
|
||||
/* #undef _EVENT_HAVE_PORT_CREATE */
|
||||
/* #undef EVENT__HAVE_PORT_CREATE */
|
||||
|
||||
/* Define to 1 if you have the <port.h> header file. */
|
||||
/* #undef _EVENT_HAVE_PORT_H */
|
||||
/* #undef EVENT__HAVE_PORT_H */
|
||||
|
||||
/* Define if you have POSIX threads libraries and header files. */
|
||||
/* #undef _EVENT_HAVE_PTHREAD */
|
||||
/* #undef EVENT__HAVE_PTHREAD */
|
||||
|
||||
/* Define if we have pthreads on this system */
|
||||
#define _EVENT_HAVE_PTHREADS 1
|
||||
#define EVENT__HAVE_PTHREADS 1
|
||||
|
||||
/* Define to 1 if you have the `putenv' function. */
|
||||
#define _EVENT_HAVE_PUTENV 1
|
||||
#define EVENT__HAVE_PUTENV 1
|
||||
|
||||
/* Define to 1 if the system has the type `sa_family_t'. */
|
||||
#define _EVENT_HAVE_SA_FAMILY_T 1
|
||||
#define EVENT__HAVE_SA_FAMILY_T 1
|
||||
|
||||
/* Define to 1 if you have the `select' function. */
|
||||
#define _EVENT_HAVE_SELECT 1
|
||||
#define EVENT__HAVE_SELECT 1
|
||||
|
||||
/* Define to 1 if you have the `sendfile' function. */
|
||||
#define _EVENT_HAVE_SENDFILE 1
|
||||
#define EVENT__HAVE_SENDFILE 1
|
||||
|
||||
/* Define to 1 if you have the `setenv' function. */
|
||||
#define _EVENT_HAVE_SETENV 1
|
||||
#define EVENT__HAVE_SETENV 1
|
||||
|
||||
/* Define if F_SETFD is defined in <fcntl.h> */
|
||||
#define _EVENT_HAVE_SETFD 1
|
||||
#define EVENT__HAVE_SETFD 1
|
||||
|
||||
/* Define to 1 if you have the `setrlimit' function. */
|
||||
#define EVENT__HAVE_SETRLIMIT 1
|
||||
|
||||
/* Define to 1 if you have the `sigaction' function. */
|
||||
#define _EVENT_HAVE_SIGACTION 1
|
||||
#define EVENT__HAVE_SIGACTION 1
|
||||
|
||||
/* Define to 1 if you have the `signal' function. */
|
||||
/* #undef _EVENT_HAVE_SIGNAL */
|
||||
/* #undef EVENT__HAVE_SIGNAL */
|
||||
|
||||
/* Define to 1 if you have the `splice' function. */
|
||||
/* #undef _EVENT_HAVE_SPLICE */
|
||||
/* #undef EVENT__HAVE_SPLICE */
|
||||
|
||||
/* Define to 1 if you have the <stdarg.h> header file. */
|
||||
#define _EVENT_HAVE_STDARG_H 1
|
||||
#define EVENT__HAVE_STDARG_H 1
|
||||
|
||||
/* Define to 1 if you have the <stddef.h> header file. */
|
||||
#define _EVENT_HAVE_STDDEF_H 1
|
||||
#define EVENT__HAVE_STDDEF_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define _EVENT_HAVE_STDINT_H 1
|
||||
#define EVENT__HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define _EVENT_HAVE_STDLIB_H 1
|
||||
#define EVENT__HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define _EVENT_HAVE_STRINGS_H 1
|
||||
#define EVENT__HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define _EVENT_HAVE_STRING_H 1
|
||||
#define EVENT__HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strlcpy' function. */
|
||||
#define _EVENT_HAVE_STRLCPY 1
|
||||
#define EVENT__HAVE_STRLCPY 1
|
||||
|
||||
/* Define to 1 if you have the `strsep' function. */
|
||||
#define _EVENT_HAVE_STRSEP 1
|
||||
#define EVENT__HAVE_STRSEP 1
|
||||
|
||||
/* Define to 1 if you have the `strtok_r' function. */
|
||||
#define _EVENT_HAVE_STRTOK_R 1
|
||||
#define EVENT__HAVE_STRTOK_R 1
|
||||
|
||||
/* Define to 1 if you have the `strtoll' function. */
|
||||
#define _EVENT_HAVE_STRTOLL 1
|
||||
#define EVENT__HAVE_STRTOLL 1
|
||||
|
||||
/* Define to 1 if the system has the type `struct addrinfo'. */
|
||||
#define _EVENT_HAVE_STRUCT_ADDRINFO 1
|
||||
#define EVENT__HAVE_STRUCT_ADDRINFO 1
|
||||
|
||||
/* Define to 1 if the system has the type `struct in6_addr'. */
|
||||
#define _EVENT_HAVE_STRUCT_IN6_ADDR 1
|
||||
#define EVENT__HAVE_STRUCT_IN6_ADDR 1
|
||||
|
||||
/* Define to 1 if `s6_addr16' is a member of `struct in6_addr'. */
|
||||
#define _EVENT_HAVE_STRUCT_IN6_ADDR_S6_ADDR16 1
|
||||
#define EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR16 1
|
||||
|
||||
/* Define to 1 if `s6_addr32' is a member of `struct in6_addr'. */
|
||||
#define _EVENT_HAVE_STRUCT_IN6_ADDR_S6_ADDR32 1
|
||||
#define EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR32 1
|
||||
|
||||
/* Define to 1 if the system has the type `struct sockaddr_in6'. */
|
||||
#define _EVENT_HAVE_STRUCT_SOCKADDR_IN6 1
|
||||
#define EVENT__HAVE_STRUCT_SOCKADDR_IN6 1
|
||||
|
||||
/* Define to 1 if `sin6_len' is a member of `struct sockaddr_in6'. */
|
||||
/* #undef _EVENT_HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN */
|
||||
/* #undef EVENT__HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN */
|
||||
|
||||
/* Define to 1 if `sin_len' is a member of `struct sockaddr_in'. */
|
||||
/* #undef _EVENT_HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
|
||||
/* #undef EVENT__HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
|
||||
|
||||
/* Define to 1 if the system has the type `struct sockaddr_storage'. */
|
||||
#define _EVENT_HAVE_STRUCT_SOCKADDR_STORAGE 1
|
||||
#define EVENT__HAVE_STRUCT_SOCKADDR_STORAGE 1
|
||||
|
||||
/* Define to 1 if `ss_family' is a member of `struct sockaddr_storage'. */
|
||||
#define _EVENT_HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY 1
|
||||
#define EVENT__HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY 1
|
||||
|
||||
/* Define to 1 if `__ss_family' is a member of `struct sockaddr_storage'. */
|
||||
/* #undef _EVENT_HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY */
|
||||
/* #undef EVENT__HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY */
|
||||
|
||||
/* Define to 1 if the system has the type `struct so_linger'. */
|
||||
#define EVENT__HAVE_STRUCT_SO_LINGER 1
|
||||
|
||||
/* Define to 1 if you have the `sysctl' function. */
|
||||
/* #undef _EVENT_HAVE_SYSCTL */
|
||||
/* #undef EVENT__HAVE_SYSCTL */
|
||||
|
||||
/* Define to 1 if you have the <sys/devpoll.h> header file. */
|
||||
/* #undef _EVENT_HAVE_SYS_DEVPOLL_H */
|
||||
/* #undef EVENT__HAVE_SYS_DEVPOLL_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/epoll.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_EPOLL_H 1
|
||||
#define EVENT__HAVE_SYS_EPOLL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/eventfd.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_EVENTFD_H 1
|
||||
#define EVENT__HAVE_SYS_EVENTFD_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/event.h> header file. */
|
||||
/* #undef _EVENT_HAVE_SYS_EVENT_H */
|
||||
/* #undef EVENT__HAVE_SYS_EVENT_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_IOCTL_H 1
|
||||
#define EVENT__HAVE_SYS_IOCTL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_MMAN_H 1
|
||||
#define EVENT__HAVE_SYS_MMAN_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_PARAM_H 1
|
||||
#define EVENT__HAVE_SYS_PARAM_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/queue.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_QUEUE_H 1
|
||||
#define EVENT__HAVE_SYS_QUEUE_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/resource.h> header file. */
|
||||
#define EVENT__HAVE_SYS_RESOURCE_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_SELECT_H 1
|
||||
#define EVENT__HAVE_SYS_SELECT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/sendfile.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_SENDFILE_H 1
|
||||
#define EVENT__HAVE_SYS_SENDFILE_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_SOCKET_H 1
|
||||
#define EVENT__HAVE_SYS_SOCKET_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_STAT_H 1
|
||||
#define EVENT__HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/sysctl.h> header file. */
|
||||
/* #undef _EVENT_HAVE_SYS_SYSCTL_H */
|
||||
/* #undef EVENT__HAVE_SYS_SYSCTL_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/timerfd.h> header file. */
|
||||
/* #undef EVENT__HAVE_SYS_TIMERFD_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_TIME_H 1
|
||||
#define EVENT__HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_TYPES_H 1
|
||||
#define EVENT__HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/uio.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_UIO_H 1
|
||||
#define EVENT__HAVE_SYS_UIO_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/wait.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_WAIT_H 1
|
||||
#define EVENT__HAVE_SYS_WAIT_H 1
|
||||
|
||||
/* Define if TAILQ_FOREACH is defined in <sys/queue.h> */
|
||||
#define _EVENT_HAVE_TAILQFOREACH 1
|
||||
#define EVENT__HAVE_TAILQFOREACH 1
|
||||
|
||||
/* Define if timeradd is defined in <sys/time.h> */
|
||||
#define _EVENT_HAVE_TIMERADD 1
|
||||
#define EVENT__HAVE_TIMERADD 1
|
||||
|
||||
/* Define if timerclear is defined in <sys/time.h> */
|
||||
#define _EVENT_HAVE_TIMERCLEAR 1
|
||||
#define EVENT__HAVE_TIMERCLEAR 1
|
||||
|
||||
/* Define if timercmp is defined in <sys/time.h> */
|
||||
#define _EVENT_HAVE_TIMERCMP 1
|
||||
#define EVENT__HAVE_TIMERCMP 1
|
||||
|
||||
/* Define to 1 if you have the `timerfd_create' function. */
|
||||
#define EVENT__HAVE_TIMERFD_CREATE 1
|
||||
|
||||
/* Define if timerisset is defined in <sys/time.h> */
|
||||
#define _EVENT_HAVE_TIMERISSET 1
|
||||
#define EVENT__HAVE_TIMERISSET 1
|
||||
|
||||
/* Define to 1 if the system has the type `uint16_t'. */
|
||||
#define _EVENT_HAVE_UINT16_T 1
|
||||
#define EVENT__HAVE_UINT16_T 1
|
||||
|
||||
/* Define to 1 if the system has the type `uint32_t'. */
|
||||
#define _EVENT_HAVE_UINT32_T 1
|
||||
#define EVENT__HAVE_UINT32_T 1
|
||||
|
||||
/* Define to 1 if the system has the type `uint64_t'. */
|
||||
#define _EVENT_HAVE_UINT64_T 1
|
||||
#define EVENT__HAVE_UINT64_T 1
|
||||
|
||||
/* Define to 1 if the system has the type `uint8_t'. */
|
||||
#define _EVENT_HAVE_UINT8_T 1
|
||||
#define EVENT__HAVE_UINT8_T 1
|
||||
|
||||
/* Define to 1 if the system has the type `uintptr_t'. */
|
||||
#define _EVENT_HAVE_UINTPTR_T 1
|
||||
#define EVENT__HAVE_UINTPTR_T 1
|
||||
|
||||
/* Define to 1 if you have the `umask' function. */
|
||||
#define _EVENT_HAVE_UMASK 1
|
||||
#define EVENT__HAVE_UMASK 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define _EVENT_HAVE_UNISTD_H 1
|
||||
#define EVENT__HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the `unsetenv' function. */
|
||||
#define _EVENT_HAVE_UNSETENV 1
|
||||
#define EVENT__HAVE_UNSETENV 1
|
||||
|
||||
/* Define to 1 if you have the `usleep' function. */
|
||||
#define EVENT__HAVE_USLEEP 1
|
||||
|
||||
/* Define to 1 if you have the `vasprintf' function. */
|
||||
#define _EVENT_HAVE_VASPRINTF 1
|
||||
#define EVENT__HAVE_VASPRINTF 1
|
||||
|
||||
/* Define if waitpid() supports WNOWAIT */
|
||||
#define EVENT__HAVE_WAITPID_WITH_WNOWAIT 1
|
||||
|
||||
/* Define if kqueue works correctly with pipes */
|
||||
/* #undef _EVENT_HAVE_WORKING_KQUEUE */
|
||||
/* #undef EVENT__HAVE_WORKING_KQUEUE */
|
||||
|
||||
/* Define to 1 if you have the <zlib.h> header file. */
|
||||
#define _EVENT_HAVE_ZLIB_H 1
|
||||
#define EVENT__HAVE_ZLIB_H 1
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#define _EVENT_LT_OBJDIR ".libs/"
|
||||
|
||||
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
|
||||
/* #undef _EVENT_NO_MINUS_C_MINUS_O */
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
#define EVENT__LT_OBJDIR ".libs/"
|
||||
|
||||
/* Numeric representation of the version */
|
||||
#define _EVENT_NUMERIC_VERSION 0x02001600
|
||||
#define EVENT__NUMERIC_VERSION 0x02010800
|
||||
|
||||
/* Name of package */
|
||||
#define _EVENT_PACKAGE "libevent"
|
||||
#define EVENT__PACKAGE "libevent"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define _EVENT_PACKAGE_BUGREPORT ""
|
||||
#define EVENT__PACKAGE_BUGREPORT ""
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define _EVENT_PACKAGE_NAME ""
|
||||
#define EVENT__PACKAGE_NAME "libevent"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define _EVENT_PACKAGE_STRING ""
|
||||
#define EVENT__PACKAGE_STRING "libevent 2.1.8-stable"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define _EVENT_PACKAGE_TARNAME ""
|
||||
#define EVENT__PACKAGE_TARNAME "libevent"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define _EVENT_PACKAGE_URL ""
|
||||
#define EVENT__PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define _EVENT_PACKAGE_VERSION ""
|
||||
#define EVENT__PACKAGE_VERSION "2.1.8-stable"
|
||||
|
||||
/* Define to necessary symbol if this constant uses a non-standard name on
|
||||
your system. */
|
||||
/* #undef _EVENT_PTHREAD_CREATE_JOINABLE */
|
||||
/* #undef EVENT__PTHREAD_CREATE_JOINABLE */
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* MOZILLA NOTE: the following constants are hand-modified to be suitable */
|
||||
|
@ -404,80 +448,123 @@
|
|||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
/* The size of `int', as computed by sizeof. */
|
||||
#define _EVENT_SIZEOF_INT 4
|
||||
#define EVENT__SIZEOF_INT 4
|
||||
|
||||
/* The size of `long', as computed by sizeof. */
|
||||
#ifdef __LP64__
|
||||
#define _EVENT_SIZEOF_LONG 8
|
||||
#define EVENT__SIZEOF_LONG 8
|
||||
#else
|
||||
#define _EVENT_SIZEOF_LONG 4
|
||||
#define EVENT__SIZEOF_LONG 4
|
||||
#endif
|
||||
|
||||
/* The size of `long long', as computed by sizeof. */
|
||||
#define _EVENT_SIZEOF_LONG_LONG 8
|
||||
#define EVENT__SIZEOF_LONG_LONG 8
|
||||
|
||||
/* The size of `off_t', as computed by sizeof. */
|
||||
#ifdef __LP64__
|
||||
#define _EVENT_SIZEOF_OFF_T 8
|
||||
#define EVENT__SIZEOF_OFF_T 8
|
||||
#else
|
||||
#define _EVENT_SIZEOF_OFF_T 4
|
||||
#define EVENT__SIZEOF_OFF_T 4
|
||||
#endif
|
||||
|
||||
/* The size of `pthread_t', as computed by sizeof. */
|
||||
#ifdef __LP64__
|
||||
#define _EVENT_SIZEOF_PTHREAD_T 8
|
||||
#define EVENT__SIZEOF_PTHREAD_T 8
|
||||
#else
|
||||
#define _EVENT_SIZEOF_PTHREAD_T 4
|
||||
#define EVENT__SIZEOF_PTHREAD_T 4
|
||||
#endif
|
||||
|
||||
/* The size of `short', as computed by sizeof. */
|
||||
#define _EVENT_SIZEOF_SHORT 2
|
||||
#define EVENT__SIZEOF_SHORT 2
|
||||
|
||||
/* The size of `size_t', as computed by sizeof. */
|
||||
#ifdef __LP64__
|
||||
#define _EVENT_SIZEOF_SIZE_T 8
|
||||
#define EVENT__SIZEOF_SIZE_T 8
|
||||
#else
|
||||
#define _EVENT_SIZEOF_SIZE_T 4
|
||||
#define EVENT__SIZEOF_SIZE_T 4
|
||||
#endif
|
||||
|
||||
/* The size of `void *', as computed by sizeof. */
|
||||
#ifdef __LP64__
|
||||
#define _EVENT_SIZEOF_VOID_P 8
|
||||
#define EVENT__SIZEOF_VOID_P 8
|
||||
#else
|
||||
#define _EVENT_SIZEOF_VOID_P 4
|
||||
#define EVENT__SIZEOF_VOID_P 4
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define _EVENT_STDC_HEADERS 1
|
||||
#define EVENT__STDC_HEADERS 1
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#define _EVENT_TIME_WITH_SYS_TIME 1
|
||||
#define EVENT__TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
#ifndef EVENT___ALL_SOURCE
|
||||
# define EVENT___ALL_SOURCE 1
|
||||
#endif
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef EVENT___GNU_SOURCE
|
||||
# define EVENT___GNU_SOURCE 1
|
||||
#endif
|
||||
/* Enable threading extensions on Solaris. */
|
||||
#ifndef EVENT___POSIX_PTHREAD_SEMANTICS
|
||||
# define EVENT___POSIX_PTHREAD_SEMANTICS 1
|
||||
#endif
|
||||
/* Enable extensions on HP NonStop. */
|
||||
#ifndef EVENT___TANDEM_SOURCE
|
||||
# define EVENT___TANDEM_SOURCE 1
|
||||
#endif
|
||||
/* Enable general extensions on Solaris. */
|
||||
#ifndef EVENT____EXTENSIONS__
|
||||
# define EVENT____EXTENSIONS__ 1
|
||||
#endif
|
||||
|
||||
|
||||
/* Version number of package */
|
||||
#define _EVENT_VERSION "2.0.22-stable"
|
||||
#define EVENT__VERSION "2.1.8-stable"
|
||||
|
||||
/* Enable large inode numbers on Mac OS X 10.5. */
|
||||
#ifndef EVENT___DARWIN_USE_64_BIT_INODE
|
||||
# define EVENT___DARWIN_USE_64_BIT_INODE 1
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
/* #undef EVENT___FILE_OFFSET_BITS */
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
/* #undef EVENT___LARGE_FILES */
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
/* #undef EVENT___MINIX */
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
/* #undef EVENT___POSIX_1_SOURCE */
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
/* #undef EVENT___POSIX_SOURCE */
|
||||
|
||||
/* Define to appropriate substitue if compiler doesnt have __func__ */
|
||||
/* #undef _EVENT___func__ */
|
||||
/* #undef EVENT____func__ */
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* #undef _EVENT_const */
|
||||
/* #undef EVENT__const */
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef _EVENT___cplusplus
|
||||
/* #undef _EVENT_inline */
|
||||
#ifndef EVENT____cplusplus
|
||||
/* #undef EVENT__inline */
|
||||
#endif
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
/* #undef _EVENT_pid_t */
|
||||
/* #undef EVENT__pid_t */
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
/* #undef _EVENT_size_t */
|
||||
/* #undef EVENT__size_t */
|
||||
|
||||
/* Define to unsigned int if you dont have it */
|
||||
/* #undef _EVENT_socklen_t */
|
||||
/* #undef EVENT__socklen_t */
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
/* #undef _EVENT_ssize_t */
|
||||
/* #undef EVENT__ssize_t */
|
||||
|
||||
#endif /* event2/event-config.h */
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
version: 2.1.8.{build}
|
||||
|
||||
os: Visual Studio 2015
|
||||
|
||||
build:
|
||||
verbosity: detailed
|
||||
|
||||
environment:
|
||||
global:
|
||||
CYG_ROOT: C:/MinGW/msys/1.0
|
||||
matrix:
|
||||
- EVENT_BUILD_METHOD: "autotools"
|
||||
EVENT_CONFIGURE_OPTIONS: ""
|
||||
- EVENT_BUILD_METHOD: "autotools"
|
||||
EVENT_CONFIGURE_OPTIONS: "--disable-openssl"
|
||||
- EVENT_BUILD_METHOD: "autotools"
|
||||
EVENT_CONFIGURE_OPTIONS: "--disable-thread-support"
|
||||
- EVENT_BUILD_METHOD: "autotools"
|
||||
EVENT_CONFIGURE_OPTIONS: "--disable-debug-mode"
|
||||
- EVENT_BUILD_METHOD: "autotools"
|
||||
EVENT_CONFIGURE_OPTIONS: "--disable-malloc-replacement"
|
||||
- EVENT_BUILD_METHOD: "cmake"
|
||||
EVENT_CMAKE_OPTIONS: ""
|
||||
- EVENT_BUILD_METHOD: "cmake"
|
||||
EVENT_CMAKE_OPTIONS: "-DEVENT__DISABLE_OPENSSL=ON"
|
||||
- EVENT_BUILD_METHOD: "cmake"
|
||||
EVENT_CMAKE_OPTIONS: "-DEVENT__DISABLE_THREAD_SUPPORT=ON"
|
||||
- EVENT_BUILD_METHOD: "cmake"
|
||||
EVENT_CMAKE_OPTIONS: "-DEVENT__DISABLE_DEBUG_MODE=ON"
|
||||
- EVENT_BUILD_METHOD: "cmake"
|
||||
EVENT_CMAKE_OPTIONS: "-DEVENT__DISABLE_MM_REPLACEMENT=ON"
|
||||
- EVENT_BUILD_METHOD: "cmake"
|
||||
EVENT_CMAKE_OPTIONS: "-DEVENT__ENABLE_VERBOSE_DEBUG=ON"
|
||||
- EVENT_BUILD_METHOD: "cmake"
|
||||
EVENT_CMAKE_OPTIONS: "-DCMAKE_C_FLAGS='-DUNICODE -D_UNICODE'"
|
||||
init:
|
||||
- 'echo Building libevent %version% for Windows'
|
||||
- 'echo System architecture: %PLATFORM%'
|
||||
- 'echo Repo build branch is: %APPVEYOR_REPO_BRANCH%'
|
||||
- 'echo Build folder is: %APPVEYOR_BUILD_FOLDER%'
|
||||
- 'echo Repo build commit is: %APPVEYOR_REPO_COMMIT%'
|
||||
- 'echo Cygwin root is: %CYG_ROOT%'
|
||||
install:
|
||||
- C:\MinGW\bin\mingw-get install autotools autoconf automake
|
||||
build_script:
|
||||
- ps: |
|
||||
if ($env:EVENT_BUILD_METHOD -eq 'autotools') {
|
||||
$env:PATH="$env:CYG_ROOT\bin;C:\MinGW\bin;$($env:PATH)"
|
||||
bash -lc "echo 'C:\MinGW /mingw' > /etc/fstab"
|
||||
bash -lc "echo 'C:\OpenSSL-Win32 /ssl' >> /etc/fstab"
|
||||
$env:APPVEYOR_BUILD_FOLDER = $env:APPVEYOR_BUILD_FOLDER -replace "\\", "/"
|
||||
bash -lc "exec 0</dev/null; exec 2>&1; cd $env:APPVEYOR_BUILD_FOLDER; bash -x ./autogen.sh && ./configure LDFLAGS='-L/ssl -L/ssl/lib -L/ssl/lib/MinGW' CFLAGS=-I/ssl/include $env:EVENT_CONFIGURE_OPTIONS && make && make verify -j20"
|
||||
} else {
|
||||
md build
|
||||
cd build
|
||||
cmake .. $env:EVENT_CMAKE_OPTIONS
|
||||
cmake --build .
|
||||
$env:CTEST_PARALLEL_LEVEL="20"
|
||||
ctest --output-on-failure
|
||||
}
|
|
@ -50,7 +50,8 @@
|
|||
#endif
|
||||
|
||||
#ifndef ARC4RANDOM_NO_INCLUDES
|
||||
#ifdef WIN32
|
||||
#include "evconfig-private.h"
|
||||
#ifdef _WIN32
|
||||
#include <wincrypt.h>
|
||||
#include <process.h>
|
||||
#else
|
||||
|
@ -58,7 +59,7 @@
|
|||
#include <unistd.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#ifdef _EVENT_HAVE_SYS_SYSCTL_H
|
||||
#ifdef EVENT__HAVE_SYS_SYSCTL_H
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
#endif
|
||||
|
@ -79,7 +80,7 @@ struct arc4_stream {
|
|||
unsigned char s[256];
|
||||
};
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#define getpid _getpid
|
||||
#define pid_t int
|
||||
#endif
|
||||
|
@ -120,7 +121,7 @@ arc4_addrandom(const unsigned char *dat, int datlen)
|
|||
rs.j = rs.i;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
static ssize_t
|
||||
read_all(int fd, unsigned char *buf, size_t count)
|
||||
{
|
||||
|
@ -140,7 +141,7 @@ read_all(int fd, unsigned char *buf, size_t count)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#define TRY_SEED_WIN32
|
||||
static int
|
||||
arc4_seed_win32(void)
|
||||
|
@ -167,8 +168,8 @@ arc4_seed_win32(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(_EVENT_HAVE_SYS_SYSCTL_H) && defined(_EVENT_HAVE_SYSCTL)
|
||||
#if _EVENT_HAVE_DECL_CTL_KERN && _EVENT_HAVE_DECL_KERN_RANDOM && _EVENT_HAVE_DECL_RANDOM_UUID
|
||||
#if defined(EVENT__HAVE_SYS_SYSCTL_H) && defined(EVENT__HAVE_SYSCTL)
|
||||
#if EVENT__HAVE_DECL_CTL_KERN && EVENT__HAVE_DECL_KERN_RANDOM && EVENT__HAVE_DECL_RANDOM_UUID
|
||||
#define TRY_SEED_SYSCTL_LINUX
|
||||
static int
|
||||
arc4_seed_sysctl_linux(void)
|
||||
|
@ -205,7 +206,7 @@ arc4_seed_sysctl_linux(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if _EVENT_HAVE_DECL_CTL_KERN && _EVENT_HAVE_DECL_KERN_ARND
|
||||
#if EVENT__HAVE_DECL_CTL_KERN && EVENT__HAVE_DECL_KERN_ARND
|
||||
#define TRY_SEED_SYSCTL_BSD
|
||||
static int
|
||||
arc4_seed_sysctl_bsd(void)
|
||||
|
@ -244,7 +245,7 @@ arc4_seed_sysctl_bsd(void)
|
|||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif /* defined(_EVENT_HAVE_SYS_SYSCTL_H) */
|
||||
#endif /* defined(EVENT__HAVE_SYS_SYSCTL_H) */
|
||||
|
||||
#ifdef __linux__
|
||||
#define TRY_SEED_PROC_SYS_KERNEL_RANDOM_UUID
|
||||
|
@ -260,7 +261,7 @@ arc4_seed_proc_sys_kernel_random_uuid(void)
|
|||
unsigned char entropy[64];
|
||||
int bytes, n, i, nybbles;
|
||||
for (bytes = 0; bytes<ADD_ENTROPY; ) {
|
||||
fd = evutil_open_closeonexec("/proc/sys/kernel/random/uuid", O_RDONLY, 0);
|
||||
fd = evutil_open_closeonexec_("/proc/sys/kernel/random/uuid", O_RDONLY, 0);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
n = read(fd, buf, sizeof(buf));
|
||||
|
@ -269,8 +270,8 @@ arc4_seed_proc_sys_kernel_random_uuid(void)
|
|||
return -1;
|
||||
memset(entropy, 0, sizeof(entropy));
|
||||
for (i=nybbles=0; i<n; ++i) {
|
||||
if (EVUTIL_ISXDIGIT(buf[i])) {
|
||||
int nyb = evutil_hex_char_to_int(buf[i]);
|
||||
if (EVUTIL_ISXDIGIT_(buf[i])) {
|
||||
int nyb = evutil_hex_char_to_int_(buf[i]);
|
||||
if (nybbles & 1) {
|
||||
entropy[nybbles/2] |= nyb;
|
||||
} else {
|
||||
|
@ -291,7 +292,7 @@ arc4_seed_proc_sys_kernel_random_uuid(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
#define TRY_SEED_URANDOM
|
||||
static char *arc4random_urandom_filename = NULL;
|
||||
|
||||
|
@ -301,7 +302,7 @@ static int arc4_seed_urandom_helper_(const char *fname)
|
|||
int fd;
|
||||
size_t n;
|
||||
|
||||
fd = evutil_open_closeonexec(fname, O_RDONLY, 0);
|
||||
fd = evutil_open_closeonexec_(fname, O_RDONLY, 0);
|
||||
if (fd<0)
|
||||
return -1;
|
||||
n = read_all(fd, buf, sizeof(buf));
|
||||
|
@ -453,9 +454,9 @@ ARC4RANDOM_EXPORT int
|
|||
arc4random_stir(void)
|
||||
{
|
||||
int val;
|
||||
_ARC4_LOCK();
|
||||
ARC4_LOCK_();
|
||||
val = arc4_stir();
|
||||
_ARC4_UNLOCK();
|
||||
ARC4_UNLOCK_();
|
||||
return val;
|
||||
}
|
||||
#endif
|
||||
|
@ -465,7 +466,7 @@ ARC4RANDOM_EXPORT void
|
|||
arc4random_addrandom(const unsigned char *dat, int datlen)
|
||||
{
|
||||
int j;
|
||||
_ARC4_LOCK();
|
||||
ARC4_LOCK_();
|
||||
if (!rs_initialized)
|
||||
arc4_stir();
|
||||
for (j = 0; j < datlen; j += 256) {
|
||||
|
@ -475,7 +476,7 @@ arc4random_addrandom(const unsigned char *dat, int datlen)
|
|||
* crazy like passing us all the files in /var/log. */
|
||||
arc4_addrandom(dat + j, datlen - j);
|
||||
}
|
||||
_ARC4_UNLOCK();
|
||||
ARC4_UNLOCK_();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -484,27 +485,27 @@ ARC4RANDOM_EXPORT ARC4RANDOM_UINT32
|
|||
arc4random(void)
|
||||
{
|
||||
ARC4RANDOM_UINT32 val;
|
||||
_ARC4_LOCK();
|
||||
ARC4_LOCK_();
|
||||
arc4_count -= 4;
|
||||
arc4_stir_if_needed();
|
||||
val = arc4_getword();
|
||||
_ARC4_UNLOCK();
|
||||
ARC4_UNLOCK_();
|
||||
return val;
|
||||
}
|
||||
#endif
|
||||
|
||||
ARC4RANDOM_EXPORT void
|
||||
arc4random_buf(void *_buf, size_t n)
|
||||
arc4random_buf(void *buf_, size_t n)
|
||||
{
|
||||
unsigned char *buf = _buf;
|
||||
_ARC4_LOCK();
|
||||
unsigned char *buf = buf_;
|
||||
ARC4_LOCK_();
|
||||
arc4_stir_if_needed();
|
||||
while (n--) {
|
||||
if (--arc4_count <= 0)
|
||||
arc4_stir();
|
||||
buf[n] = arc4_getbyte();
|
||||
}
|
||||
_ARC4_UNLOCK();
|
||||
ARC4_UNLOCK_();
|
||||
}
|
||||
|
||||
#ifndef ARC4RANDOM_NOUNIFORM
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
#!/bin/sh
|
||||
|
||||
MAKE=make
|
||||
if command -v gmake >/dev/null 2>/dev/null; then
|
||||
MAKE=gmake
|
||||
fi
|
||||
$MAKE maintainer-clean >/dev/null 2>/dev/null
|
||||
|
||||
if [ -x "`which autoreconf 2>/dev/null`" ] ; then
|
||||
exec autoreconf -ivf
|
||||
fi
|
||||
|
|
|
@ -8,395 +8,443 @@
|
|||
* Do not rely on macros in this file existing in later versions.
|
||||
*/
|
||||
|
||||
#ifndef _EVENT2_EVENT_CONFIG_H_
|
||||
#define _EVENT2_EVENT_CONFIG_H_
|
||||
#ifndef EVENT2_EVENT_CONFIG_H_INCLUDED_
|
||||
#define EVENT2_EVENT_CONFIG_H_INCLUDED_
|
||||
|
||||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define if libevent should build without support for a debug mode */
|
||||
/* #undef _EVENT_DISABLE_DEBUG_MODE */
|
||||
/* #undef EVENT__DISABLE_DEBUG_MODE */
|
||||
|
||||
/* Define if libevent should not allow replacing the mm functions */
|
||||
/* #undef _EVENT_DISABLE_MM_REPLACEMENT */
|
||||
/* #undef EVENT__DISABLE_MM_REPLACEMENT */
|
||||
|
||||
/* Define if libevent should not be compiled with thread support */
|
||||
/* #undef _EVENT_DISABLE_THREAD_SUPPORT */
|
||||
/* #undef EVENT__DISABLE_THREAD_SUPPORT */
|
||||
|
||||
/* Define to 1 if you have the `accept4' function. */
|
||||
#if !defined(__NetBSD__)
|
||||
#define EVENT__HAVE_ACCEPT4 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the `arc4random' function. */
|
||||
#define _EVENT_HAVE_ARC4RANDOM 1
|
||||
#define EVENT__HAVE_ARC4RANDOM 1
|
||||
|
||||
/* Define to 1 if you have the `arc4random_buf' function. */
|
||||
#define _EVENT_HAVE_ARC4RANDOM_BUF 1
|
||||
#define EVENT__HAVE_ARC4RANDOM_BUF 1
|
||||
|
||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
#define _EVENT_HAVE_ARPA_INET_H 1
|
||||
#define EVENT__HAVE_ARPA_INET_H 1
|
||||
|
||||
/* Define to 1 if you have the `clock_gettime' function. */
|
||||
#define _EVENT_HAVE_CLOCK_GETTIME 1
|
||||
#define EVENT__HAVE_CLOCK_GETTIME 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `CTL_KERN', and to 0 if you
|
||||
don't. */
|
||||
#define _EVENT_HAVE_DECL_CTL_KERN 1
|
||||
#define EVENT__HAVE_DECL_CTL_KERN 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `KERN_ARND', and to 0 if you
|
||||
don't. */
|
||||
#define _EVENT_HAVE_DECL_KERN_ARND 1
|
||||
#define EVENT__HAVE_DECL_KERN_ARND 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `KERN_RANDOM', and to 0 if you
|
||||
don't. */
|
||||
#define _EVENT_HAVE_DECL_KERN_RANDOM 0
|
||||
#define EVENT__HAVE_DECL_KERN_RANDOM 0
|
||||
|
||||
/* Define to 1 if you have the declaration of `RANDOM_UUID', and to 0 if you
|
||||
don't. */
|
||||
#define _EVENT_HAVE_DECL_RANDOM_UUID 0
|
||||
#define EVENT__HAVE_DECL_RANDOM_UUID 0
|
||||
|
||||
/* Define if /dev/poll is available */
|
||||
/* #undef _EVENT_HAVE_DEVPOLL */
|
||||
/* #undef EVENT__HAVE_DEVPOLL */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define _EVENT_HAVE_DLFCN_H 1
|
||||
#define EVENT__HAVE_DLFCN_H 1
|
||||
|
||||
/* Define if your system supports the epoll system calls */
|
||||
/* #undef _EVENT_HAVE_EPOLL */
|
||||
/* #undef EVENT__HAVE_EPOLL */
|
||||
|
||||
/* Define to 1 if you have the `epoll_create1' function. */
|
||||
/* #undef EVENT__HAVE_EPOLL_CREATE1 */
|
||||
|
||||
/* Define to 1 if you have the `epoll_ctl' function. */
|
||||
/* #undef _EVENT_HAVE_EPOLL_CTL */
|
||||
/* #undef EVENT__HAVE_EPOLL_CTL */
|
||||
|
||||
/* Define to 1 if you have the <errno.h> header file. */
|
||||
#define EVENT__HAVE_ERRNO_H 1
|
||||
|
||||
/* Define to 1 if you have ERR_remove_thread_stat(). */
|
||||
/* #undef EVENT__HAVE_ERR_REMOVE_THREAD_STATE */
|
||||
|
||||
/* Define to 1 if you have the `eventfd' function. */
|
||||
/* #undef _EVENT_HAVE_EVENTFD */
|
||||
/* #undef EVENT__HAVE_EVENTFD */
|
||||
|
||||
/* Define if your system supports event ports */
|
||||
/* #undef _EVENT_HAVE_EVENT_PORTS */
|
||||
/* #undef EVENT__HAVE_EVENT_PORTS */
|
||||
|
||||
/* Define to 1 if you have the `fcntl' function. */
|
||||
#define _EVENT_HAVE_FCNTL 1
|
||||
#define EVENT__HAVE_FCNTL 1
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define _EVENT_HAVE_FCNTL_H 1
|
||||
#define EVENT__HAVE_FCNTL_H 1
|
||||
|
||||
/* Define to 1 if the system has the type `fd_mask'. */
|
||||
#define _EVENT_HAVE_FD_MASK 1
|
||||
#define EVENT__HAVE_FD_MASK 1
|
||||
|
||||
/* Do we have getaddrinfo()? */
|
||||
#define _EVENT_HAVE_GETADDRINFO 1
|
||||
#define EVENT__HAVE_GETADDRINFO 1
|
||||
|
||||
/* Define to 1 if you have the `getegid' function. */
|
||||
#define _EVENT_HAVE_GETEGID 1
|
||||
#define EVENT__HAVE_GETEGID 1
|
||||
|
||||
/* Define to 1 if you have the `geteuid' function. */
|
||||
#define _EVENT_HAVE_GETEUID 1
|
||||
#define EVENT__HAVE_GETEUID 1
|
||||
|
||||
/* Define this if you have any gethostbyname_r() */
|
||||
/* #undef _EVENT_HAVE_GETHOSTBYNAME_R */
|
||||
/* #undef EVENT__HAVE_GETHOSTBYNAME_R */
|
||||
|
||||
/* Define this if gethostbyname_r takes 3 arguments */
|
||||
/* #undef _EVENT_HAVE_GETHOSTBYNAME_R_3_ARG */
|
||||
/* #undef EVENT__HAVE_GETHOSTBYNAME_R_3_ARG */
|
||||
|
||||
/* Define this if gethostbyname_r takes 5 arguments */
|
||||
/* #undef _EVENT_HAVE_GETHOSTBYNAME_R_5_ARG */
|
||||
/* #undef EVENT__HAVE_GETHOSTBYNAME_R_5_ARG */
|
||||
|
||||
/* Define this if gethostbyname_r takes 6 arguments */
|
||||
/* #undef _EVENT_HAVE_GETHOSTBYNAME_R_6_ARG */
|
||||
/* #undef EVENT__HAVE_GETHOSTBYNAME_R_6_ARG */
|
||||
|
||||
/* Define to 1 if you have the `getifaddrs' function. */
|
||||
#define EVENT__HAVE_GETIFADDRS 1
|
||||
|
||||
/* Define to 1 if you have the `getnameinfo' function. */
|
||||
#define _EVENT_HAVE_GETNAMEINFO 1
|
||||
#define EVENT__HAVE_GETNAMEINFO 1
|
||||
|
||||
/* Define to 1 if you have the `getprotobynumber' function. */
|
||||
#define _EVENT_HAVE_GETPROTOBYNUMBER 1
|
||||
#define EVENT__HAVE_GETPROTOBYNUMBER 1
|
||||
|
||||
/* Define to 1 if you have the `getservbyname' function. */
|
||||
/* #undef _EVENT_HAVE_GETSERVBYNAME */
|
||||
#define EVENT__HAVE_GETSERVBYNAME 1
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
#define _EVENT_HAVE_GETTIMEOFDAY 1
|
||||
#define EVENT__HAVE_GETTIMEOFDAY 1
|
||||
|
||||
/* Define to 1 if you have the `inet_aton' function. */
|
||||
#define _EVENT_HAVE_INET_ATON 1
|
||||
/* Define to 1 if you have the <ifaddrs.h> header file. */
|
||||
#define EVENT__HAVE_IFADDRS_H 1
|
||||
|
||||
/* Define to 1 if you have the `inet_ntop' function. */
|
||||
#define _EVENT_HAVE_INET_NTOP 1
|
||||
#define EVENT__HAVE_INET_NTOP 1
|
||||
|
||||
/* Define to 1 if you have the `inet_pton' function. */
|
||||
#define _EVENT_HAVE_INET_PTON 1
|
||||
#define EVENT__HAVE_INET_PTON 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define _EVENT_HAVE_INTTYPES_H 1
|
||||
#define EVENT__HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the `issetugid' function. */
|
||||
#define _EVENT_HAVE_ISSETUGID 1
|
||||
#define EVENT__HAVE_ISSETUGID 1
|
||||
|
||||
/* Define to 1 if you have the `kqueue' function. */
|
||||
#define _EVENT_HAVE_KQUEUE 1
|
||||
#define EVENT__HAVE_KQUEUE 1
|
||||
|
||||
/* Define if the system has zlib */
|
||||
#define _EVENT_HAVE_LIBZ 1
|
||||
#define EVENT__HAVE_LIBZ 1
|
||||
|
||||
/* Define to 1 if you have the `mach_absolute_time' function. */
|
||||
/* #undef EVENT__HAVE_MACH_ABSOLUTE_TIME */
|
||||
|
||||
/* Define to 1 if you have the <mach/mach_time.h> header file. */
|
||||
/* #undef EVENT__HAVE_MACH_MACH_TIME_H */
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define _EVENT_HAVE_MEMORY_H 1
|
||||
#define EVENT__HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the `mmap' function. */
|
||||
#define _EVENT_HAVE_MMAP 1
|
||||
#define EVENT__HAVE_MMAP 1
|
||||
|
||||
/* Define to 1 if you have the `nanosleep' function. */
|
||||
#define EVENT__HAVE_NANOSLEEP 1
|
||||
|
||||
/* Define to 1 if you have the <netdb.h> header file. */
|
||||
#define _EVENT_HAVE_NETDB_H 1
|
||||
#define EVENT__HAVE_NETDB_H 1
|
||||
|
||||
/* Define to 1 if you have the <netinet/in6.h> header file. */
|
||||
/* #undef _EVENT_HAVE_NETINET_IN6_H */
|
||||
/* #undef EVENT__HAVE_NETINET_IN6_H */
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#define _EVENT_HAVE_NETINET_IN_H 1
|
||||
#define EVENT__HAVE_NETINET_IN_H 1
|
||||
|
||||
/* Define to 1 if you have the <netinet/tcp.h> header file. */
|
||||
#define EVENT__HAVE_NETINET_TCP_H 1
|
||||
|
||||
/* Define if the system has openssl */
|
||||
#define _EVENT_HAVE_OPENSSL 1
|
||||
|
||||
/* Define to 1 if you have the <openssl/bio.h> header file. */
|
||||
#define _EVENT_HAVE_OPENSSL_BIO_H 1
|
||||
/* #undef EVENT__HAVE_OPENSSL */
|
||||
|
||||
/* Define to 1 if you have the `pipe' function. */
|
||||
#define _EVENT_HAVE_PIPE 1
|
||||
#define EVENT__HAVE_PIPE 1
|
||||
|
||||
/* Define to 1 if you have the `pipe2' function. */
|
||||
#define EVENT__HAVE_PIPE2 1
|
||||
|
||||
/* Define to 1 if you have the `poll' function. */
|
||||
#define _EVENT_HAVE_POLL 1
|
||||
#define EVENT__HAVE_POLL 1
|
||||
|
||||
/* Define to 1 if you have the <poll.h> header file. */
|
||||
#define _EVENT_HAVE_POLL_H 1
|
||||
#define EVENT__HAVE_POLL_H 1
|
||||
|
||||
/* Define to 1 if you have the `port_create' function. */
|
||||
/* #undef _EVENT_HAVE_PORT_CREATE */
|
||||
/* #undef EVENT__HAVE_PORT_CREATE */
|
||||
|
||||
/* Define to 1 if you have the <port.h> header file. */
|
||||
/* #undef _EVENT_HAVE_PORT_H */
|
||||
/* #undef EVENT__HAVE_PORT_H */
|
||||
|
||||
/* Define if you have POSIX threads libraries and header files. */
|
||||
/* #undef _EVENT_HAVE_PTHREAD */
|
||||
/* #undef EVENT__HAVE_PTHREAD */
|
||||
|
||||
/* Define if we have pthreads on this system */
|
||||
#define _EVENT_HAVE_PTHREADS 1
|
||||
#define EVENT__HAVE_PTHREADS 1
|
||||
|
||||
/* Define to 1 if you have the `putenv' function. */
|
||||
#define _EVENT_HAVE_PUTENV 1
|
||||
#define EVENT__HAVE_PUTENV 1
|
||||
|
||||
/* Define to 1 if the system has the type `sa_family_t'. */
|
||||
#define _EVENT_HAVE_SA_FAMILY_T 1
|
||||
#define EVENT__HAVE_SA_FAMILY_T 1
|
||||
|
||||
/* Define to 1 if you have the `select' function. */
|
||||
#define _EVENT_HAVE_SELECT 1
|
||||
#define EVENT__HAVE_SELECT 1
|
||||
|
||||
/* Define to 1 if you have the `sendfile' function. */
|
||||
#define _EVENT_HAVE_SENDFILE 1
|
||||
#define EVENT__HAVE_SENDFILE 1
|
||||
|
||||
/* Define to 1 if you have the `setenv' function. */
|
||||
#define _EVENT_HAVE_SETENV 1
|
||||
#define EVENT__HAVE_SETENV 1
|
||||
|
||||
/* Define if F_SETFD is defined in <fcntl.h> */
|
||||
#define _EVENT_HAVE_SETFD 1
|
||||
#define EVENT__HAVE_SETFD 1
|
||||
|
||||
/* Define to 1 if you have the `setrlimit' function. */
|
||||
#define EVENT__HAVE_SETRLIMIT 1
|
||||
|
||||
/* Define to 1 if you have the `sigaction' function. */
|
||||
#define _EVENT_HAVE_SIGACTION 1
|
||||
#define EVENT__HAVE_SIGACTION 1
|
||||
|
||||
/* Define to 1 if you have the `signal' function. */
|
||||
#define _EVENT_HAVE_SIGNAL 1
|
||||
#define EVENT__HAVE_SIGNAL 1
|
||||
|
||||
/* Define to 1 if you have the `splice' function. */
|
||||
/* #undef _EVENT_HAVE_SPLICE */
|
||||
/* #undef EVENT__HAVE_SPLICE */
|
||||
|
||||
/* Define to 1 if you have the <stdarg.h> header file. */
|
||||
#define _EVENT_HAVE_STDARG_H 1
|
||||
#define EVENT__HAVE_STDARG_H 1
|
||||
|
||||
/* Define to 1 if you have the <stddef.h> header file. */
|
||||
#define _EVENT_HAVE_STDDEF_H 1
|
||||
#define EVENT__HAVE_STDDEF_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define _EVENT_HAVE_STDINT_H 1
|
||||
#define EVENT__HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define _EVENT_HAVE_STDLIB_H 1
|
||||
#define EVENT__HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define _EVENT_HAVE_STRINGS_H 1
|
||||
#define EVENT__HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define _EVENT_HAVE_STRING_H 1
|
||||
#define EVENT__HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strlcpy' function. */
|
||||
#define _EVENT_HAVE_STRLCPY 1
|
||||
#define EVENT__HAVE_STRLCPY 1
|
||||
|
||||
/* Define to 1 if you have the `strsep' function. */
|
||||
#define _EVENT_HAVE_STRSEP 1
|
||||
#define EVENT__HAVE_STRSEP 1
|
||||
|
||||
/* Define to 1 if you have the `strtok_r' function. */
|
||||
#define _EVENT_HAVE_STRTOK_R 1
|
||||
#define EVENT__HAVE_STRTOK_R 1
|
||||
|
||||
/* Define to 1 if you have the `strtoll' function. */
|
||||
#define _EVENT_HAVE_STRTOLL 1
|
||||
#define EVENT__HAVE_STRTOLL 1
|
||||
|
||||
/* Define to 1 if the system has the type `struct addrinfo'. */
|
||||
#define _EVENT_HAVE_STRUCT_ADDRINFO 1
|
||||
#define EVENT__HAVE_STRUCT_ADDRINFO 1
|
||||
|
||||
/* Define to 1 if the system has the type `struct in6_addr'. */
|
||||
#define _EVENT_HAVE_STRUCT_IN6_ADDR 1
|
||||
#define EVENT__HAVE_STRUCT_IN6_ADDR 1
|
||||
|
||||
/* Define to 1 if `s6_addr16' is a member of `struct in6_addr'. */
|
||||
/* #undef _EVENT_HAVE_STRUCT_IN6_ADDR_S6_ADDR16 */
|
||||
/* #undef EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR16 */
|
||||
|
||||
/* Define to 1 if `s6_addr32' is a member of `struct in6_addr'. */
|
||||
/* #undef _EVENT_HAVE_STRUCT_IN6_ADDR_S6_ADDR32 */
|
||||
/* #undef EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR32 */
|
||||
|
||||
/* Define to 1 if the system has the type `struct sockaddr_in6'. */
|
||||
#define _EVENT_HAVE_STRUCT_SOCKADDR_IN6 1
|
||||
#define EVENT__HAVE_STRUCT_SOCKADDR_IN6 1
|
||||
|
||||
/* Define to 1 if `sin6_len' is a member of `struct sockaddr_in6'. */
|
||||
#define _EVENT_HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN 1
|
||||
#define EVENT__HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN 1
|
||||
|
||||
/* Define to 1 if `sin_len' is a member of `struct sockaddr_in'. */
|
||||
#define _EVENT_HAVE_STRUCT_SOCKADDR_IN_SIN_LEN 1
|
||||
#define EVENT__HAVE_STRUCT_SOCKADDR_IN_SIN_LEN 1
|
||||
|
||||
/* Define to 1 if the system has the type `struct sockaddr_storage'. */
|
||||
#define _EVENT_HAVE_STRUCT_SOCKADDR_STORAGE 1
|
||||
#define EVENT__HAVE_STRUCT_SOCKADDR_STORAGE 1
|
||||
|
||||
/* Define to 1 if `ss_family' is a member of `struct sockaddr_storage'. */
|
||||
#define _EVENT_HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY 1
|
||||
#define EVENT__HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY 1
|
||||
|
||||
/* Define to 1 if `__ss_family' is a member of `struct sockaddr_storage'. */
|
||||
/* #undef _EVENT_HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY */
|
||||
/* #undef EVENT__HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY */
|
||||
|
||||
/* Define to 1 if the system has the type `struct so_linger'. */
|
||||
#define EVENT__HAVE_STRUCT_SO_LINGER 1
|
||||
|
||||
/* Define to 1 if you have the `sysctl' function. */
|
||||
#define _EVENT_HAVE_SYSCTL 1
|
||||
#define EVENT__HAVE_SYSCTL 1
|
||||
|
||||
/* Define to 1 if you have the <sys/devpoll.h> header file. */
|
||||
/* #undef _EVENT_HAVE_SYS_DEVPOLL_H */
|
||||
/* #undef EVENT__HAVE_SYS_DEVPOLL_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/epoll.h> header file. */
|
||||
/* #undef _EVENT_HAVE_SYS_EPOLL_H */
|
||||
/* #undef EVENT__HAVE_SYS_EPOLL_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/eventfd.h> header file. */
|
||||
/* #undef _EVENT_HAVE_SYS_EVENTFD_H */
|
||||
/* #undef EVENT__HAVE_SYS_EVENTFD_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/event.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_EVENT_H 1
|
||||
#define EVENT__HAVE_SYS_EVENT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_IOCTL_H 1
|
||||
#define EVENT__HAVE_SYS_IOCTL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_MMAN_H 1
|
||||
#define EVENT__HAVE_SYS_MMAN_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_PARAM_H 1
|
||||
#define EVENT__HAVE_SYS_PARAM_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/queue.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_QUEUE_H 1
|
||||
#define EVENT__HAVE_SYS_QUEUE_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/resource.h> header file. */
|
||||
#define EVENT__HAVE_SYS_RESOURCE_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_SELECT_H 1
|
||||
#define EVENT__HAVE_SYS_SELECT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/sendfile.h> header file. */
|
||||
/* #undef _EVENT_HAVE_SYS_SENDFILE_H */
|
||||
/* #undef EVENT__HAVE_SYS_SENDFILE_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_SOCKET_H 1
|
||||
#define EVENT__HAVE_SYS_SOCKET_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_STAT_H 1
|
||||
#define EVENT__HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/sysctl.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_SYSCTL_H 1
|
||||
#define EVENT__HAVE_SYS_SYSCTL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/timerfd.h> header file. */
|
||||
/* #undef EVENT__HAVE_SYS_TIMERFD_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_TIME_H 1
|
||||
#define EVENT__HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_TYPES_H 1
|
||||
#define EVENT__HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/uio.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_UIO_H 1
|
||||
#define EVENT__HAVE_SYS_UIO_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/wait.h> header file. */
|
||||
#define _EVENT_HAVE_SYS_WAIT_H 1
|
||||
#define EVENT__HAVE_SYS_WAIT_H 1
|
||||
|
||||
/* Define if TAILQ_FOREACH is defined in <sys/queue.h> */
|
||||
#define _EVENT_HAVE_TAILQFOREACH 1
|
||||
#define EVENT__HAVE_TAILQFOREACH 1
|
||||
|
||||
/* Define if timeradd is defined in <sys/time.h> */
|
||||
#define _EVENT_HAVE_TIMERADD 1
|
||||
#define EVENT__HAVE_TIMERADD 1
|
||||
|
||||
/* Define if timerclear is defined in <sys/time.h> */
|
||||
#define _EVENT_HAVE_TIMERCLEAR 1
|
||||
#define EVENT__HAVE_TIMERCLEAR 1
|
||||
|
||||
/* Define if timercmp is defined in <sys/time.h> */
|
||||
#define _EVENT_HAVE_TIMERCMP 1
|
||||
#define EVENT__HAVE_TIMERCMP 1
|
||||
|
||||
/* Define to 1 if you have the `timerfd_create' function. */
|
||||
/* #undef EVENT__HAVE_TIMERFD_CREATE */
|
||||
|
||||
/* Define if timerisset is defined in <sys/time.h> */
|
||||
#define _EVENT_HAVE_TIMERISSET 1
|
||||
#define EVENT__HAVE_TIMERISSET 1
|
||||
|
||||
/* Define to 1 if the system has the type `uint16_t'. */
|
||||
#define _EVENT_HAVE_UINT16_T 1
|
||||
#define EVENT__HAVE_UINT16_T 1
|
||||
|
||||
/* Define to 1 if the system has the type `uint32_t'. */
|
||||
#define _EVENT_HAVE_UINT32_T 1
|
||||
#define EVENT__HAVE_UINT32_T 1
|
||||
|
||||
/* Define to 1 if the system has the type `uint64_t'. */
|
||||
#define _EVENT_HAVE_UINT64_T 1
|
||||
#define EVENT__HAVE_UINT64_T 1
|
||||
|
||||
/* Define to 1 if the system has the type `uint8_t'. */
|
||||
#define _EVENT_HAVE_UINT8_T 1
|
||||
#define EVENT__HAVE_UINT8_T 1
|
||||
|
||||
/* Define to 1 if the system has the type `uintptr_t'. */
|
||||
#define _EVENT_HAVE_UINTPTR_T 1
|
||||
#define EVENT__HAVE_UINTPTR_T 1
|
||||
|
||||
/* Define to 1 if you have the `umask' function. */
|
||||
#define _EVENT_HAVE_UMASK 1
|
||||
#define EVENT__HAVE_UMASK 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define _EVENT_HAVE_UNISTD_H 1
|
||||
#define EVENT__HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the `unsetenv' function. */
|
||||
#define _EVENT_HAVE_UNSETENV 1
|
||||
#define EVENT__HAVE_UNSETENV 1
|
||||
|
||||
/* Define to 1 if you have the `usleep' function. */
|
||||
#define EVENT__HAVE_USLEEP 1
|
||||
|
||||
/* Define to 1 if you have the `vasprintf' function. */
|
||||
#define _EVENT_HAVE_VASPRINTF 1
|
||||
#define EVENT__HAVE_VASPRINTF 1
|
||||
|
||||
/* Define if waitpid() supports WNOWAIT */
|
||||
#if !defined(__DragonFly__) && !defined(__OpenBSD__)
|
||||
#define EVENT__HAVE_WAITPID_WITH_WNOWAIT 1
|
||||
#endif
|
||||
|
||||
/* Define if kqueue works correctly with pipes */
|
||||
#define _EVENT_HAVE_WORKING_KQUEUE 1
|
||||
#define EVENT__HAVE_WORKING_KQUEUE 1
|
||||
|
||||
/* Define to 1 if you have the <zlib.h> header file. */
|
||||
#define _EVENT_HAVE_ZLIB_H 1
|
||||
#define EVENT__HAVE_ZLIB_H 1
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#define _EVENT_LT_OBJDIR ".libs/"
|
||||
|
||||
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
|
||||
/* #undef _EVENT_NO_MINUS_C_MINUS_O */
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
#define EVENT__LT_OBJDIR ".libs/"
|
||||
|
||||
/* Numeric representation of the version */
|
||||
#define _EVENT_NUMERIC_VERSION 0x02001600
|
||||
#define EVENT__NUMERIC_VERSION 0x02010800
|
||||
|
||||
/* Name of package */
|
||||
#define _EVENT_PACKAGE "libevent"
|
||||
#define EVENT__PACKAGE "libevent"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define _EVENT_PACKAGE_BUGREPORT ""
|
||||
#define EVENT__PACKAGE_BUGREPORT ""
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define _EVENT_PACKAGE_NAME ""
|
||||
#define EVENT__PACKAGE_NAME "libevent"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define _EVENT_PACKAGE_STRING ""
|
||||
#define EVENT__PACKAGE_STRING "libevent 2.1.8-stable"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define _EVENT_PACKAGE_TARNAME ""
|
||||
#define EVENT__PACKAGE_TARNAME "libevent"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define _EVENT_PACKAGE_URL ""
|
||||
#define EVENT__PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define _EVENT_PACKAGE_VERSION ""
|
||||
#define EVENT__PACKAGE_VERSION "2.1.8-stable"
|
||||
|
||||
/* Define to necessary symbol if this constant uses a non-standard name on
|
||||
your system. */
|
||||
/* #undef _EVENT_PTHREAD_CREATE_JOINABLE */
|
||||
/* #undef EVENT__PTHREAD_CREATE_JOINABLE */
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* MOZILLA NOTE: the following constants are hand-modified to be suitable */
|
||||
|
@ -404,43 +452,43 @@
|
|||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
/* The size of `int', as computed by sizeof. */
|
||||
#define _EVENT_SIZEOF_INT 4
|
||||
#define EVENT__SIZEOF_INT 4
|
||||
|
||||
/* The size of `long', as computed by sizeof. */
|
||||
#ifdef __LP64__
|
||||
#define _EVENT_SIZEOF_LONG 8
|
||||
#define EVENT__SIZEOF_LONG 8
|
||||
#else
|
||||
#define _EVENT_SIZEOF_LONG 4
|
||||
#define EVENT__SIZEOF_LONG 4
|
||||
#endif
|
||||
|
||||
/* The size of `long long', as computed by sizeof. */
|
||||
#define _EVENT_SIZEOF_LONG_LONG 8
|
||||
#define EVENT__SIZEOF_LONG_LONG 8
|
||||
|
||||
/* The size of `off_t', as computed by sizeof. */
|
||||
#define _EVENT_SIZEOF_OFF_T 8
|
||||
#define EVENT__SIZEOF_OFF_T 8
|
||||
|
||||
/* The size of `pthread_t', as computed by sizeof. */
|
||||
#ifdef __LP64__
|
||||
#define _EVENT_SIZEOF_PTHREAD_T 8
|
||||
#define EVENT__SIZEOF_PTHREAD_T 8
|
||||
#else
|
||||
#define _EVENT_SIZEOF_PTHREAD_T 4
|
||||
#define EVENT__SIZEOF_PTHREAD_T 4
|
||||
#endif
|
||||
|
||||
/* The size of `short', as computed by sizeof. */
|
||||
#define _EVENT_SIZEOF_SHORT 2
|
||||
#define EVENT__SIZEOF_SHORT 2
|
||||
|
||||
/* The size of `size_t', as computed by sizeof. */
|
||||
#ifdef __LP64__
|
||||
#define _EVENT_SIZEOF_SIZE_T 8
|
||||
#define EVENT__SIZEOF_SIZE_T 8
|
||||
#else
|
||||
#define _EVENT_SIZEOF_SIZE_T 4
|
||||
#define EVENT__SIZEOF_SIZE_T 4
|
||||
#endif
|
||||
|
||||
/* The size of `void *', as computed by sizeof. */
|
||||
#ifdef __LP64__
|
||||
#define _EVENT_SIZEOF_VOID_P 8
|
||||
#define EVENT__SIZEOF_VOID_P 8
|
||||
#else
|
||||
#define _EVENT_SIZEOF_VOID_P 4
|
||||
#define EVENT__SIZEOF_VOID_P 4
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
@ -448,36 +496,79 @@
|
|||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define _EVENT_STDC_HEADERS 1
|
||||
#define EVENT__STDC_HEADERS 1
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#define _EVENT_TIME_WITH_SYS_TIME 1
|
||||
#define EVENT__TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
#ifndef EVENT___ALL_SOURCE
|
||||
# define EVENT___ALL_SOURCE 1
|
||||
#endif
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef EVENT___GNU_SOURCE
|
||||
# define EVENT___GNU_SOURCE 1
|
||||
#endif
|
||||
/* Enable threading extensions on Solaris. */
|
||||
#ifndef EVENT___POSIX_PTHREAD_SEMANTICS
|
||||
# define EVENT___POSIX_PTHREAD_SEMANTICS 1
|
||||
#endif
|
||||
/* Enable extensions on HP NonStop. */
|
||||
#ifndef EVENT___TANDEM_SOURCE
|
||||
# define EVENT___TANDEM_SOURCE 1
|
||||
#endif
|
||||
/* Enable general extensions on Solaris. */
|
||||
#ifndef EVENT____EXTENSIONS__
|
||||
# define EVENT____EXTENSIONS__ 1
|
||||
#endif
|
||||
|
||||
|
||||
/* Version number of package */
|
||||
#define _EVENT_VERSION "2.0.22-stable"
|
||||
#define EVENT__VERSION "2.1.8-stable"
|
||||
|
||||
/* Enable large inode numbers on Mac OS X 10.5. */
|
||||
#ifndef EVENT___DARWIN_USE_64_BIT_INODE
|
||||
# define EVENT___DARWIN_USE_64_BIT_INODE 1
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
/* #undef EVENT___FILE_OFFSET_BITS */
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
/* #undef EVENT___LARGE_FILES */
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
/* #undef EVENT___MINIX */
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
/* #undef EVENT___POSIX_1_SOURCE */
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
/* #undef EVENT___POSIX_SOURCE */
|
||||
|
||||
/* Define to appropriate substitue if compiler doesnt have __func__ */
|
||||
/* #undef _EVENT___func__ */
|
||||
/* #undef EVENT____func__ */
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* #undef _EVENT_const */
|
||||
/* #undef EVENT__const */
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef _EVENT___cplusplus
|
||||
/* #undef _EVENT_inline */
|
||||
#ifndef EVENT____cplusplus
|
||||
/* #undef EVENT__inline */
|
||||
#endif
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
/* #undef _EVENT_pid_t */
|
||||
/* #undef EVENT__pid_t */
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
/* #undef _EVENT_size_t */
|
||||
/* #undef EVENT__size_t */
|
||||
|
||||
/* Define to unsigned int if you dont have it */
|
||||
/* #undef _EVENT_socklen_t */
|
||||
/* #undef EVENT__socklen_t */
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
/* #undef _EVENT_ssize_t */
|
||||
/* #undef EVENT__ssize_t */
|
||||
|
||||
#endif /* event2/event-config.h */
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -30,12 +30,13 @@
|
|||
This module implements overlapped read and write functions for evbuffer
|
||||
objects on Windows.
|
||||
*/
|
||||
#include "event2/event-config.h"
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#include "event2/buffer.h"
|
||||
#include "event2/buffer_compat.h"
|
||||
#include "event2/util.h"
|
||||
#include "event2/thread.h"
|
||||
#include "event2/event-config.h"
|
||||
#include "util-internal.h"
|
||||
#include "evthread-internal.h"
|
||||
#include "evbuffer-internal.h"
|
||||
|
@ -87,13 +88,13 @@ pin_release(struct evbuffer_overlapped *eo, unsigned flag)
|
|||
for (i = 0; i < eo->n_buffers; ++i) {
|
||||
EVUTIL_ASSERT(chain);
|
||||
next = chain->next;
|
||||
_evbuffer_chain_unpin(chain, flag);
|
||||
evbuffer_chain_unpin_(chain, flag);
|
||||
chain = next;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
evbuffer_commit_read(struct evbuffer *evbuf, ev_ssize_t nBytes)
|
||||
evbuffer_commit_read_(struct evbuffer *evbuf, ev_ssize_t nBytes)
|
||||
{
|
||||
struct evbuffer_overlapped *buf = upcast_evbuffer(evbuf);
|
||||
struct evbuffer_chain **chainp;
|
||||
|
@ -128,13 +129,13 @@ evbuffer_commit_read(struct evbuffer *evbuf, ev_ssize_t nBytes)
|
|||
evbuf->total_len += nBytes;
|
||||
evbuf->n_add_for_cb += nBytes;
|
||||
|
||||
evbuffer_invoke_callbacks(evbuf);
|
||||
evbuffer_invoke_callbacks_(evbuf);
|
||||
|
||||
_evbuffer_decref_and_unlock(evbuf);
|
||||
evbuffer_decref_and_unlock_(evbuf);
|
||||
}
|
||||
|
||||
void
|
||||
evbuffer_commit_write(struct evbuffer *evbuf, ev_ssize_t nBytes)
|
||||
evbuffer_commit_write_(struct evbuffer *evbuf, ev_ssize_t nBytes)
|
||||
{
|
||||
struct evbuffer_overlapped *buf = upcast_evbuffer(evbuf);
|
||||
|
||||
|
@ -144,11 +145,11 @@ evbuffer_commit_write(struct evbuffer *evbuf, ev_ssize_t nBytes)
|
|||
evbuffer_drain(evbuf, nBytes);
|
||||
pin_release(buf,EVBUFFER_MEM_PINNED_W);
|
||||
buf->write_in_progress = 0;
|
||||
_evbuffer_decref_and_unlock(evbuf);
|
||||
evbuffer_decref_and_unlock_(evbuf);
|
||||
}
|
||||
|
||||
struct evbuffer *
|
||||
evbuffer_overlapped_new(evutil_socket_t fd)
|
||||
evbuffer_overlapped_new_(evutil_socket_t fd)
|
||||
{
|
||||
struct evbuffer_overlapped *evo;
|
||||
|
||||
|
@ -156,7 +157,7 @@ evbuffer_overlapped_new(evutil_socket_t fd)
|
|||
if (!evo)
|
||||
return NULL;
|
||||
|
||||
TAILQ_INIT(&evo->buffer.callbacks);
|
||||
LIST_INIT(&evo->buffer.callbacks);
|
||||
evo->buffer.refcnt = 1;
|
||||
evo->buffer.last_with_datap = &evo->buffer.first;
|
||||
|
||||
|
@ -167,7 +168,7 @@ evbuffer_overlapped_new(evutil_socket_t fd)
|
|||
}
|
||||
|
||||
int
|
||||
evbuffer_launch_write(struct evbuffer *buf, ev_ssize_t at_most,
|
||||
evbuffer_launch_write_(struct evbuffer *buf, ev_ssize_t at_most,
|
||||
struct event_overlapped *ol)
|
||||
{
|
||||
struct evbuffer_overlapped *buf_o = upcast_evbuffer(buf);
|
||||
|
@ -203,7 +204,7 @@ evbuffer_launch_write(struct evbuffer *buf, ev_ssize_t at_most,
|
|||
for (i=0; i < MAX_WSABUFS && chain; ++i, chain=chain->next) {
|
||||
WSABUF *b = &buf_o->buffers[i];
|
||||
b->buf = (char*)( chain->buffer + chain->misalign );
|
||||
_evbuffer_chain_pin(chain, EVBUFFER_MEM_PINNED_W);
|
||||
evbuffer_chain_pin_(chain, EVBUFFER_MEM_PINNED_W);
|
||||
|
||||
if ((size_t)at_most > chain->off) {
|
||||
/* XXXX Cast is safe for now, since win32 has no
|
||||
|
@ -220,7 +221,7 @@ evbuffer_launch_write(struct evbuffer *buf, ev_ssize_t at_most,
|
|||
}
|
||||
|
||||
buf_o->n_buffers = i;
|
||||
_evbuffer_incref(buf);
|
||||
evbuffer_incref_(buf);
|
||||
if (WSASend(buf_o->fd, buf_o->buffers, i, &bytesSent, 0,
|
||||
&ol->overlapped, NULL)) {
|
||||
int error = WSAGetLastError();
|
||||
|
@ -241,7 +242,7 @@ done:
|
|||
}
|
||||
|
||||
int
|
||||
evbuffer_launch_read(struct evbuffer *buf, size_t at_most,
|
||||
evbuffer_launch_read_(struct evbuffer *buf, size_t at_most,
|
||||
struct event_overlapped *ol)
|
||||
{
|
||||
struct evbuffer_overlapped *buf_o = upcast_evbuffer(buf);
|
||||
|
@ -264,11 +265,11 @@ evbuffer_launch_read(struct evbuffer *buf, size_t at_most,
|
|||
buf_o->n_buffers = 0;
|
||||
memset(buf_o->buffers, 0, sizeof(buf_o->buffers));
|
||||
|
||||
if (_evbuffer_expand_fast(buf, at_most, MAX_WSABUFS) == -1)
|
||||
if (evbuffer_expand_fast_(buf, at_most, MAX_WSABUFS) == -1)
|
||||
goto done;
|
||||
evbuffer_freeze(buf, 0);
|
||||
|
||||
nvecs = _evbuffer_read_setup_vecs(buf, at_most,
|
||||
nvecs = evbuffer_read_setup_vecs_(buf, at_most,
|
||||
vecs, MAX_WSABUFS, &chainp, 1);
|
||||
for (i=0;i<nvecs;++i) {
|
||||
WSABUF_FROM_EVBUFFER_IOV(
|
||||
|
@ -281,12 +282,12 @@ evbuffer_launch_read(struct evbuffer *buf, size_t at_most,
|
|||
|
||||
npin=0;
|
||||
for ( ; chain; chain = chain->next) {
|
||||
_evbuffer_chain_pin(chain, EVBUFFER_MEM_PINNED_R);
|
||||
evbuffer_chain_pin_(chain, EVBUFFER_MEM_PINNED_R);
|
||||
++npin;
|
||||
}
|
||||
EVUTIL_ASSERT(npin == nvecs);
|
||||
|
||||
_evbuffer_incref(buf);
|
||||
evbuffer_incref_(buf);
|
||||
if (WSARecv(buf_o->fd, buf_o->buffers, nvecs, &bytesRead, &flags,
|
||||
&ol->overlapped, NULL)) {
|
||||
int error = WSAGetLastError();
|
||||
|
@ -307,14 +308,14 @@ done:
|
|||
}
|
||||
|
||||
evutil_socket_t
|
||||
_evbuffer_overlapped_get_fd(struct evbuffer *buf)
|
||||
evbuffer_overlapped_get_fd_(struct evbuffer *buf)
|
||||
{
|
||||
struct evbuffer_overlapped *buf_o = upcast_evbuffer(buf);
|
||||
return buf_o ? buf_o->fd : -1;
|
||||
}
|
||||
|
||||
void
|
||||
_evbuffer_overlapped_set_fd(struct evbuffer *buf, evutil_socket_t fd)
|
||||
evbuffer_overlapped_set_fd_(struct evbuffer *buf, evutil_socket_t fd)
|
||||
{
|
||||
struct evbuffer_overlapped *buf_o = upcast_evbuffer(buf);
|
||||
EVBUFFER_LOCK(buf);
|
||||
|
|
|
@ -23,14 +23,16 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _BUFFEREVENT_INTERNAL_H_
|
||||
#define _BUFFEREVENT_INTERNAL_H_
|
||||
#ifndef BUFFEREVENT_INTERNAL_H_INCLUDED_
|
||||
#define BUFFEREVENT_INTERNAL_H_INCLUDED_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "event2/event-config.h"
|
||||
#include "event2/event_struct.h"
|
||||
#include "evconfig-private.h"
|
||||
#include "event2/util.h"
|
||||
#include "defer-internal.h"
|
||||
#include "evthread-internal.h"
|
||||
|
@ -38,6 +40,17 @@ extern "C" {
|
|||
#include "ratelim-internal.h"
|
||||
#include "event2/bufferevent_struct.h"
|
||||
|
||||
#include "ipv6-internal.h"
|
||||
#ifdef _WIN32
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
#ifdef EVENT__HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef EVENT__HAVE_NETINET_IN6_H
|
||||
#include <netinet/in6.h>
|
||||
#endif
|
||||
|
||||
/* These flags are reasons that we might be declining to actually enable
|
||||
reading or writing on a bufferevent.
|
||||
*/
|
||||
|
@ -65,7 +78,7 @@ typedef ev_uint16_t bufferevent_suspend_flags;
|
|||
|
||||
struct bufferevent_rate_limit_group {
|
||||
/** List of all members in the group */
|
||||
TAILQ_HEAD(rlim_group_member_list, bufferevent_private) members;
|
||||
LIST_HEAD(rlim_group_member_list, bufferevent_private) members;
|
||||
/** Current limits for the group. */
|
||||
struct ev_token_bucket rate_limit;
|
||||
struct ev_token_bucket_cfg rate_limit_cfg;
|
||||
|
@ -103,6 +116,10 @@ struct bufferevent_rate_limit_group {
|
|||
/** Timeout event that goes off once a tick, when the bucket is ready
|
||||
* to refill. */
|
||||
struct event master_refill_event;
|
||||
|
||||
/** Seed for weak random number generator. Protected by 'lock' */
|
||||
struct evutil_weakrand_state weakrand_seed;
|
||||
|
||||
/** Lock to protect the members of this group. This lock should nest
|
||||
* within every bufferevent lock: if you are holding this lock, do
|
||||
* not assume you can lock another bufferevent. */
|
||||
|
@ -116,7 +133,7 @@ struct bufferevent_rate_limit {
|
|||
*
|
||||
* Note that this field is supposed to be protected by the group
|
||||
* lock */
|
||||
TAILQ_ENTRY(bufferevent_private) next_in_group;
|
||||
LIST_ENTRY(bufferevent_private) next_in_group;
|
||||
/** The rate-limiting group for this bufferevent, or NULL if it is
|
||||
* only rate-limited on its own. */
|
||||
struct bufferevent_rate_limit_group *group;
|
||||
|
@ -177,7 +194,7 @@ struct bufferevent_private {
|
|||
int dns_error;
|
||||
|
||||
/** Used to implement deferred callbacks */
|
||||
struct deferred_cb deferred;
|
||||
struct event_callback deferred;
|
||||
|
||||
/** The options this bufferevent was constructed with */
|
||||
enum bufferevent_options options;
|
||||
|
@ -189,8 +206,30 @@ struct bufferevent_private {
|
|||
* If NULL, locking is disabled. */
|
||||
void *lock;
|
||||
|
||||
/** No matter how big our bucket gets, don't try to read more than this
|
||||
* much in a single read operation. */
|
||||
ev_ssize_t max_single_read;
|
||||
|
||||
/** No matter how big our bucket gets, don't try to write more than this
|
||||
* much in a single write operation. */
|
||||
ev_ssize_t max_single_write;
|
||||
|
||||
/** Rate-limiting information for this bufferevent */
|
||||
struct bufferevent_rate_limit *rate_limiting;
|
||||
|
||||
/* Saved conn_addr, to extract IP address from it.
|
||||
*
|
||||
* Because some servers may reset/close connection without waiting clients,
|
||||
* in that case we can't extract IP address even in close_cb.
|
||||
* So we need to save it, just after we connected to remote server, or
|
||||
* after resolving (to avoid extra dns requests during retrying, since UDP
|
||||
* is slow) */
|
||||
union {
|
||||
struct sockaddr_in6 in6;
|
||||
struct sockaddr_in in;
|
||||
} conn_address;
|
||||
|
||||
struct evdns_getaddrinfo_request *dns_request;
|
||||
};
|
||||
|
||||
/** Possible operations for a control callback. */
|
||||
|
@ -238,8 +277,13 @@ struct bufferevent_ops {
|
|||
*/
|
||||
int (*disable)(struct bufferevent *, short);
|
||||
|
||||
/** Detatches the bufferevent from related data structures. Called as
|
||||
* soon as its reference count reaches 0. */
|
||||
void (*unlink)(struct bufferevent *);
|
||||
|
||||
/** Free any storage and deallocate any extra data or structures used
|
||||
in this implementation.
|
||||
in this implementation. Called when the bufferevent is
|
||||
finalized.
|
||||
*/
|
||||
void (*destruct)(struct bufferevent *);
|
||||
|
||||
|
@ -262,7 +306,7 @@ extern const struct bufferevent_ops bufferevent_ops_pair;
|
|||
#define BEV_IS_FILTER(bevp) ((bevp)->be_ops == &bufferevent_ops_filter)
|
||||
#define BEV_IS_PAIR(bevp) ((bevp)->be_ops == &bufferevent_ops_pair)
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
extern const struct bufferevent_ops bufferevent_ops_async;
|
||||
#define BEV_IS_ASYNC(bevp) ((bevp)->be_ops == &bufferevent_ops_async)
|
||||
#else
|
||||
|
@ -270,69 +314,92 @@ extern const struct bufferevent_ops bufferevent_ops_async;
|
|||
#endif
|
||||
|
||||
/** Initialize the shared parts of a bufferevent. */
|
||||
int bufferevent_init_common(struct bufferevent_private *, struct event_base *, const struct bufferevent_ops *, enum bufferevent_options options);
|
||||
int bufferevent_init_common_(struct bufferevent_private *, struct event_base *, const struct bufferevent_ops *, enum bufferevent_options options);
|
||||
|
||||
/** For internal use: temporarily stop all reads on bufev, until the conditions
|
||||
* in 'what' are over. */
|
||||
void bufferevent_suspend_read(struct bufferevent *bufev, bufferevent_suspend_flags what);
|
||||
void bufferevent_suspend_read_(struct bufferevent *bufev, bufferevent_suspend_flags what);
|
||||
/** For internal use: clear the conditions 'what' on bufev, and re-enable
|
||||
* reading if there are no conditions left. */
|
||||
void bufferevent_unsuspend_read(struct bufferevent *bufev, bufferevent_suspend_flags what);
|
||||
void bufferevent_unsuspend_read_(struct bufferevent *bufev, bufferevent_suspend_flags what);
|
||||
|
||||
/** For internal use: temporarily stop all writes on bufev, until the conditions
|
||||
* in 'what' are over. */
|
||||
void bufferevent_suspend_write(struct bufferevent *bufev, bufferevent_suspend_flags what);
|
||||
void bufferevent_suspend_write_(struct bufferevent *bufev, bufferevent_suspend_flags what);
|
||||
/** For internal use: clear the conditions 'what' on bufev, and re-enable
|
||||
* writing if there are no conditions left. */
|
||||
void bufferevent_unsuspend_write(struct bufferevent *bufev, bufferevent_suspend_flags what);
|
||||
void bufferevent_unsuspend_write_(struct bufferevent *bufev, bufferevent_suspend_flags what);
|
||||
|
||||
#define bufferevent_wm_suspend_read(b) \
|
||||
bufferevent_suspend_read((b), BEV_SUSPEND_WM)
|
||||
bufferevent_suspend_read_((b), BEV_SUSPEND_WM)
|
||||
#define bufferevent_wm_unsuspend_read(b) \
|
||||
bufferevent_unsuspend_read((b), BEV_SUSPEND_WM)
|
||||
bufferevent_unsuspend_read_((b), BEV_SUSPEND_WM)
|
||||
|
||||
/*
|
||||
Disable a bufferevent. Equivalent to bufferevent_disable(), but
|
||||
first resets 'connecting' flag to force EV_WRITE down for sure.
|
||||
|
||||
XXXX this method will go away in the future; try not to add new users.
|
||||
See comment in evhttp_connection_reset() for discussion.
|
||||
See comment in evhttp_connection_reset_() for discussion.
|
||||
|
||||
@param bufev the bufferevent to be disabled
|
||||
@param event any combination of EV_READ | EV_WRITE.
|
||||
@return 0 if successful, or -1 if an error occurred
|
||||
@see bufferevent_disable()
|
||||
*/
|
||||
int bufferevent_disable_hard(struct bufferevent *bufev, short event);
|
||||
int bufferevent_disable_hard_(struct bufferevent *bufev, short event);
|
||||
|
||||
/** Internal: Set up locking on a bufferevent. If lock is set, use it.
|
||||
* Otherwise, use a new lock. */
|
||||
int bufferevent_enable_locking(struct bufferevent *bufev, void *lock);
|
||||
/** Internal: Increment the reference count on bufev. */
|
||||
void bufferevent_incref(struct bufferevent *bufev);
|
||||
int bufferevent_enable_locking_(struct bufferevent *bufev, void *lock);
|
||||
/** Internal: backwards compat macro for the now public function
|
||||
* Increment the reference count on bufev. */
|
||||
#define bufferevent_incref_(bufev) bufferevent_incref(bufev)
|
||||
/** Internal: Lock bufev and increase its reference count.
|
||||
* unlocking it otherwise. */
|
||||
void _bufferevent_incref_and_lock(struct bufferevent *bufev);
|
||||
/** Internal: Decrement the reference count on bufev. Returns 1 if it freed
|
||||
void bufferevent_incref_and_lock_(struct bufferevent *bufev);
|
||||
/** Internal: backwards compat macro for the now public function
|
||||
* Decrement the reference count on bufev. Returns 1 if it freed
|
||||
* the bufferevent.*/
|
||||
int bufferevent_decref(struct bufferevent *bufev);
|
||||
#define bufferevent_decref_(bufev) bufferevent_decref(bufev)
|
||||
|
||||
/** Internal: Drop the reference count on bufev, freeing as necessary, and
|
||||
* unlocking it otherwise. Returns 1 if it freed the bufferevent. */
|
||||
int _bufferevent_decref_and_unlock(struct bufferevent *bufev);
|
||||
int bufferevent_decref_and_unlock_(struct bufferevent *bufev);
|
||||
|
||||
/** Internal: If callbacks are deferred and we have a read callback, schedule
|
||||
* a readcb. Otherwise just run the readcb. */
|
||||
void _bufferevent_run_readcb(struct bufferevent *bufev);
|
||||
* a readcb. Otherwise just run the readcb. Ignores watermarks. */
|
||||
void bufferevent_run_readcb_(struct bufferevent *bufev, int options);
|
||||
/** Internal: If callbacks are deferred and we have a write callback, schedule
|
||||
* a writecb. Otherwise just run the writecb. */
|
||||
void _bufferevent_run_writecb(struct bufferevent *bufev);
|
||||
* a writecb. Otherwise just run the writecb. Ignores watermarks. */
|
||||
void bufferevent_run_writecb_(struct bufferevent *bufev, int options);
|
||||
/** Internal: If callbacks are deferred and we have an eventcb, schedule
|
||||
* it to run with events "what". Otherwise just run the eventcb. */
|
||||
void _bufferevent_run_eventcb(struct bufferevent *bufev, short what);
|
||||
* it to run with events "what". Otherwise just run the eventcb.
|
||||
* See bufferevent_trigger_event for meaning of "options". */
|
||||
void bufferevent_run_eventcb_(struct bufferevent *bufev, short what, int options);
|
||||
|
||||
/** Internal: Run or schedule (if deferred or options contain
|
||||
* BEV_TRIG_DEFER_CALLBACKS) I/O callbacks specified in iotype.
|
||||
* Must already hold the bufev lock. Honors watermarks unless
|
||||
* BEV_TRIG_IGNORE_WATERMARKS is in options. */
|
||||
static inline void bufferevent_trigger_nolock_(struct bufferevent *bufev, short iotype, int options);
|
||||
|
||||
/* Making this inline since all of the common-case calls to this function in
|
||||
* libevent use constant arguments. */
|
||||
static inline void
|
||||
bufferevent_trigger_nolock_(struct bufferevent *bufev, short iotype, int options)
|
||||
{
|
||||
if ((iotype & EV_READ) && ((options & BEV_TRIG_IGNORE_WATERMARKS) ||
|
||||
evbuffer_get_length(bufev->input) >= bufev->wm_read.low))
|
||||
bufferevent_run_readcb_(bufev, options);
|
||||
if ((iotype & EV_WRITE) && ((options & BEV_TRIG_IGNORE_WATERMARKS) ||
|
||||
evbuffer_get_length(bufev->output) <= bufev->wm_write.low))
|
||||
bufferevent_run_writecb_(bufev, options);
|
||||
}
|
||||
|
||||
/** Internal: Add the event 'ev' with timeout tv, unless tv is set to 0, in
|
||||
* which case add ev with no timeout. */
|
||||
int _bufferevent_add_event(struct event *ev, const struct timeval *tv);
|
||||
int bufferevent_add_event_(struct event *ev, const struct timeval *tv);
|
||||
|
||||
/* =========
|
||||
* These next functions implement timeouts for bufferevents that aren't doing
|
||||
|
@ -341,15 +408,18 @@ int _bufferevent_add_event(struct event *ev, const struct timeval *tv);
|
|||
/** Internal use: Set up the ev_read and ev_write callbacks so that
|
||||
* the other "generic_timeout" functions will work on it. Call this from
|
||||
* the constructor function. */
|
||||
void _bufferevent_init_generic_timeout_cbs(struct bufferevent *bev);
|
||||
/** Internal use: Delete the ev_read and ev_write callbacks if they're pending.
|
||||
* Call this from the destructor function. */
|
||||
int _bufferevent_del_generic_timeout_cbs(struct bufferevent *bev);
|
||||
void bufferevent_init_generic_timeout_cbs_(struct bufferevent *bev);
|
||||
/** Internal use: Add or delete the generic timeout events as appropriate.
|
||||
* (If an event is enabled and a timeout is set, we add the event. Otherwise
|
||||
* we delete it.) Call this from anything that changes the timeout values,
|
||||
* that enabled EV_READ or EV_WRITE, or that disables EV_READ or EV_WRITE. */
|
||||
int _bufferevent_generic_adj_timeouts(struct bufferevent *bev);
|
||||
int bufferevent_generic_adj_timeouts_(struct bufferevent *bev);
|
||||
int bufferevent_generic_adj_existing_timeouts_(struct bufferevent *bev);
|
||||
|
||||
enum bufferevent_options bufferevent_get_options_(struct bufferevent *bev);
|
||||
|
||||
const struct sockaddr*
|
||||
bufferevent_socket_get_conn_address_(struct bufferevent *bev);
|
||||
|
||||
/** Internal use: We have just successfully read data into an inbuf, so
|
||||
* reset the read timeout (if any). */
|
||||
|
@ -375,9 +445,9 @@ int _bufferevent_generic_adj_timeouts(struct bufferevent *bev);
|
|||
* bufferevent_private. */
|
||||
#define BEV_UPCAST(b) EVUTIL_UPCAST((b), struct bufferevent_private, bev)
|
||||
|
||||
#ifdef _EVENT_DISABLE_THREAD_SUPPORT
|
||||
#define BEV_LOCK(b) _EVUTIL_NIL_STMT
|
||||
#define BEV_UNLOCK(b) _EVUTIL_NIL_STMT
|
||||
#ifdef EVENT__DISABLE_THREAD_SUPPORT
|
||||
#define BEV_LOCK(b) EVUTIL_NIL_STMT_
|
||||
#define BEV_UNLOCK(b) EVUTIL_NIL_STMT_
|
||||
#else
|
||||
/** Internal: Grab the lock (if any) on a bufferevent */
|
||||
#define BEV_LOCK(b) do { \
|
||||
|
@ -395,16 +465,18 @@ int _bufferevent_generic_adj_timeouts(struct bufferevent *bev);
|
|||
|
||||
/* ==== For rate-limiting. */
|
||||
|
||||
int _bufferevent_decrement_write_buckets(struct bufferevent_private *bev,
|
||||
int bufferevent_decrement_write_buckets_(struct bufferevent_private *bev,
|
||||
ev_ssize_t bytes);
|
||||
int _bufferevent_decrement_read_buckets(struct bufferevent_private *bev,
|
||||
int bufferevent_decrement_read_buckets_(struct bufferevent_private *bev,
|
||||
ev_ssize_t bytes);
|
||||
ev_ssize_t _bufferevent_get_read_max(struct bufferevent_private *bev);
|
||||
ev_ssize_t _bufferevent_get_write_max(struct bufferevent_private *bev);
|
||||
ev_ssize_t bufferevent_get_read_max_(struct bufferevent_private *bev);
|
||||
ev_ssize_t bufferevent_get_write_max_(struct bufferevent_private *bev);
|
||||
|
||||
int bufferevent_ratelim_init_(struct bufferevent_private *bev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _BUFFEREVENT_INTERNAL_H_ */
|
||||
#endif /* BUFFEREVENT_INTERNAL_H_INCLUDED_ */
|
||||
|
|
|
@ -25,11 +25,12 @@
|
|||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "event2/event-config.h"
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "event2/event-config.h"
|
||||
|
||||
#ifdef _EVENT_HAVE_SYS_TIME_H
|
||||
#ifdef EVENT__HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
|
@ -37,14 +38,13 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef _EVENT_HAVE_STDARG_H
|
||||
#ifdef EVENT__HAVE_STDARG_H
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
|
||||
#include "event2/util.h"
|
||||
#include "event2/buffer.h"
|
||||
|
@ -53,17 +53,18 @@
|
|||
#include "event2/bufferevent_struct.h"
|
||||
#include "event2/bufferevent_compat.h"
|
||||
#include "event2/event.h"
|
||||
#include "event-internal.h"
|
||||
#include "log-internal.h"
|
||||
#include "mm-internal.h"
|
||||
#include "bufferevent-internal.h"
|
||||
#include "evbuffer-internal.h"
|
||||
#include "util-internal.h"
|
||||
|
||||
static void _bufferevent_cancel_all(struct bufferevent *bev);
|
||||
|
||||
static void bufferevent_cancel_all_(struct bufferevent *bev);
|
||||
static void bufferevent_finalize_cb_(struct event_callback *evcb, void *arg_);
|
||||
|
||||
void
|
||||
bufferevent_suspend_read(struct bufferevent *bufev, bufferevent_suspend_flags what)
|
||||
bufferevent_suspend_read_(struct bufferevent *bufev, bufferevent_suspend_flags what)
|
||||
{
|
||||
struct bufferevent_private *bufev_private =
|
||||
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
|
||||
|
@ -75,7 +76,7 @@ bufferevent_suspend_read(struct bufferevent *bufev, bufferevent_suspend_flags wh
|
|||
}
|
||||
|
||||
void
|
||||
bufferevent_unsuspend_read(struct bufferevent *bufev, bufferevent_suspend_flags what)
|
||||
bufferevent_unsuspend_read_(struct bufferevent *bufev, bufferevent_suspend_flags what)
|
||||
{
|
||||
struct bufferevent_private *bufev_private =
|
||||
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
|
||||
|
@ -87,7 +88,7 @@ bufferevent_unsuspend_read(struct bufferevent *bufev, bufferevent_suspend_flags
|
|||
}
|
||||
|
||||
void
|
||||
bufferevent_suspend_write(struct bufferevent *bufev, bufferevent_suspend_flags what)
|
||||
bufferevent_suspend_write_(struct bufferevent *bufev, bufferevent_suspend_flags what)
|
||||
{
|
||||
struct bufferevent_private *bufev_private =
|
||||
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
|
||||
|
@ -99,7 +100,7 @@ bufferevent_suspend_write(struct bufferevent *bufev, bufferevent_suspend_flags w
|
|||
}
|
||||
|
||||
void
|
||||
bufferevent_unsuspend_write(struct bufferevent *bufev, bufferevent_suspend_flags what)
|
||||
bufferevent_unsuspend_write_(struct bufferevent *bufev, bufferevent_suspend_flags what)
|
||||
{
|
||||
struct bufferevent_private *bufev_private =
|
||||
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
|
||||
|
@ -130,7 +131,7 @@ bufferevent_inbuf_wm_cb(struct evbuffer *buf,
|
|||
}
|
||||
|
||||
static void
|
||||
bufferevent_run_deferred_callbacks_locked(struct deferred_cb *_, void *arg)
|
||||
bufferevent_run_deferred_callbacks_locked(struct event_callback *cb, void *arg)
|
||||
{
|
||||
struct bufferevent_private *bufev_private = arg;
|
||||
struct bufferevent *bufev = &bufev_private->bev;
|
||||
|
@ -159,11 +160,11 @@ bufferevent_run_deferred_callbacks_locked(struct deferred_cb *_, void *arg)
|
|||
EVUTIL_SET_SOCKET_ERROR(err);
|
||||
bufev->errorcb(bufev, what, bufev->cbarg);
|
||||
}
|
||||
_bufferevent_decref_and_unlock(bufev);
|
||||
bufferevent_decref_and_unlock_(bufev);
|
||||
}
|
||||
|
||||
static void
|
||||
bufferevent_run_deferred_callbacks_unlocked(struct deferred_cb *_, void *arg)
|
||||
bufferevent_run_deferred_callbacks_unlocked(struct event_callback *cb, void *arg)
|
||||
{
|
||||
struct bufferevent_private *bufev_private = arg;
|
||||
struct bufferevent *bufev = &bufev_private->bev;
|
||||
|
@ -203,73 +204,91 @@ bufferevent_run_deferred_callbacks_unlocked(struct deferred_cb *_, void *arg)
|
|||
EVUTIL_SET_SOCKET_ERROR(err);
|
||||
UNLOCKED(errorcb(bufev,what,cbarg));
|
||||
}
|
||||
_bufferevent_decref_and_unlock(bufev);
|
||||
bufferevent_decref_and_unlock_(bufev);
|
||||
#undef UNLOCKED
|
||||
}
|
||||
|
||||
#define SCHEDULE_DEFERRED(bevp) \
|
||||
do { \
|
||||
bufferevent_incref(&(bevp)->bev); \
|
||||
event_deferred_cb_schedule( \
|
||||
event_base_get_deferred_cb_queue((bevp)->bev.ev_base), \
|
||||
&(bevp)->deferred); \
|
||||
if (event_deferred_cb_schedule_( \
|
||||
(bevp)->bev.ev_base, \
|
||||
&(bevp)->deferred)) \
|
||||
bufferevent_incref_(&(bevp)->bev); \
|
||||
} while (0)
|
||||
|
||||
|
||||
void
|
||||
_bufferevent_run_readcb(struct bufferevent *bufev)
|
||||
bufferevent_run_readcb_(struct bufferevent *bufev, int options)
|
||||
{
|
||||
/* Requires that we hold the lock and a reference */
|
||||
struct bufferevent_private *p =
|
||||
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
|
||||
if (bufev->readcb == NULL)
|
||||
return;
|
||||
if (p->options & BEV_OPT_DEFER_CALLBACKS) {
|
||||
if ((p->options|options) & BEV_OPT_DEFER_CALLBACKS) {
|
||||
p->readcb_pending = 1;
|
||||
if (!p->deferred.queued)
|
||||
SCHEDULE_DEFERRED(p);
|
||||
SCHEDULE_DEFERRED(p);
|
||||
} else {
|
||||
bufev->readcb(bufev, bufev->cbarg);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_bufferevent_run_writecb(struct bufferevent *bufev)
|
||||
bufferevent_run_writecb_(struct bufferevent *bufev, int options)
|
||||
{
|
||||
/* Requires that we hold the lock and a reference */
|
||||
struct bufferevent_private *p =
|
||||
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
|
||||
if (bufev->writecb == NULL)
|
||||
return;
|
||||
if (p->options & BEV_OPT_DEFER_CALLBACKS) {
|
||||
if ((p->options|options) & BEV_OPT_DEFER_CALLBACKS) {
|
||||
p->writecb_pending = 1;
|
||||
if (!p->deferred.queued)
|
||||
SCHEDULE_DEFERRED(p);
|
||||
SCHEDULE_DEFERRED(p);
|
||||
} else {
|
||||
bufev->writecb(bufev, bufev->cbarg);
|
||||
}
|
||||
}
|
||||
|
||||
#define BEV_TRIG_ALL_OPTS ( \
|
||||
BEV_TRIG_IGNORE_WATERMARKS| \
|
||||
BEV_TRIG_DEFER_CALLBACKS \
|
||||
)
|
||||
|
||||
void
|
||||
_bufferevent_run_eventcb(struct bufferevent *bufev, short what)
|
||||
bufferevent_trigger(struct bufferevent *bufev, short iotype, int options)
|
||||
{
|
||||
bufferevent_incref_and_lock_(bufev);
|
||||
bufferevent_trigger_nolock_(bufev, iotype, options&BEV_TRIG_ALL_OPTS);
|
||||
bufferevent_decref_and_unlock_(bufev);
|
||||
}
|
||||
|
||||
void
|
||||
bufferevent_run_eventcb_(struct bufferevent *bufev, short what, int options)
|
||||
{
|
||||
/* Requires that we hold the lock and a reference */
|
||||
struct bufferevent_private *p =
|
||||
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
|
||||
if (bufev->errorcb == NULL)
|
||||
return;
|
||||
if (p->options & BEV_OPT_DEFER_CALLBACKS) {
|
||||
if ((p->options|options) & BEV_OPT_DEFER_CALLBACKS) {
|
||||
p->eventcb_pending |= what;
|
||||
p->errno_pending = EVUTIL_SOCKET_ERROR();
|
||||
if (!p->deferred.queued)
|
||||
SCHEDULE_DEFERRED(p);
|
||||
SCHEDULE_DEFERRED(p);
|
||||
} else {
|
||||
bufev->errorcb(bufev, what, bufev->cbarg);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bufferevent_trigger_event(struct bufferevent *bufev, short what, int options)
|
||||
{
|
||||
bufferevent_incref_and_lock_(bufev);
|
||||
bufferevent_run_eventcb_(bufev, what, options&BEV_TRIG_ALL_OPTS);
|
||||
bufferevent_decref_and_unlock_(bufev);
|
||||
}
|
||||
|
||||
int
|
||||
bufferevent_init_common(struct bufferevent_private *bufev_private,
|
||||
bufferevent_init_common_(struct bufferevent_private *bufev_private,
|
||||
struct event_base *base,
|
||||
const struct bufferevent_ops *ops,
|
||||
enum bufferevent_options options)
|
||||
|
@ -297,6 +316,8 @@ bufferevent_init_common(struct bufferevent_private *bufev_private,
|
|||
|
||||
bufev->be_ops = ops;
|
||||
|
||||
bufferevent_ratelim_init_(bufev_private);
|
||||
|
||||
/*
|
||||
* Set to EV_WRITE so that using bufferevent_write is going to
|
||||
* trigger a callback. Reading needs to be explicitly enabled
|
||||
|
@ -304,9 +325,9 @@ bufferevent_init_common(struct bufferevent_private *bufev_private,
|
|||
*/
|
||||
bufev->enabled = EV_WRITE;
|
||||
|
||||
#ifndef _EVENT_DISABLE_THREAD_SUPPORT
|
||||
#ifndef EVENT__DISABLE_THREAD_SUPPORT
|
||||
if (options & BEV_OPT_THREADSAFE) {
|
||||
if (bufferevent_enable_locking(bufev, NULL) < 0) {
|
||||
if (bufferevent_enable_locking_(bufev, NULL) < 0) {
|
||||
/* cleanup */
|
||||
evbuffer_free(bufev->input);
|
||||
evbuffer_free(bufev->output);
|
||||
|
@ -321,21 +342,23 @@ bufferevent_init_common(struct bufferevent_private *bufev_private,
|
|||
event_warnx("UNLOCK_CALLBACKS requires DEFER_CALLBACKS");
|
||||
return -1;
|
||||
}
|
||||
if (options & BEV_OPT_DEFER_CALLBACKS) {
|
||||
if (options & BEV_OPT_UNLOCK_CALLBACKS)
|
||||
event_deferred_cb_init(&bufev_private->deferred,
|
||||
bufferevent_run_deferred_callbacks_unlocked,
|
||||
bufev_private);
|
||||
else
|
||||
event_deferred_cb_init(&bufev_private->deferred,
|
||||
bufferevent_run_deferred_callbacks_locked,
|
||||
bufev_private);
|
||||
}
|
||||
if (options & BEV_OPT_UNLOCK_CALLBACKS)
|
||||
event_deferred_cb_init_(
|
||||
&bufev_private->deferred,
|
||||
event_base_get_npriorities(base) / 2,
|
||||
bufferevent_run_deferred_callbacks_unlocked,
|
||||
bufev_private);
|
||||
else
|
||||
event_deferred_cb_init_(
|
||||
&bufev_private->deferred,
|
||||
event_base_get_npriorities(base) / 2,
|
||||
bufferevent_run_deferred_callbacks_locked,
|
||||
bufev_private);
|
||||
|
||||
bufev_private->options = options;
|
||||
|
||||
evbuffer_set_parent(bufev->input, bufev);
|
||||
evbuffer_set_parent(bufev->output, bufev);
|
||||
evbuffer_set_parent_(bufev->input, bufev);
|
||||
evbuffer_set_parent_(bufev->output, bufev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -355,6 +378,26 @@ bufferevent_setcb(struct bufferevent *bufev,
|
|||
BEV_UNLOCK(bufev);
|
||||
}
|
||||
|
||||
void
|
||||
bufferevent_getcb(struct bufferevent *bufev,
|
||||
bufferevent_data_cb *readcb_ptr,
|
||||
bufferevent_data_cb *writecb_ptr,
|
||||
bufferevent_event_cb *eventcb_ptr,
|
||||
void **cbarg_ptr)
|
||||
{
|
||||
BEV_LOCK(bufev);
|
||||
if (readcb_ptr)
|
||||
*readcb_ptr = bufev->readcb;
|
||||
if (writecb_ptr)
|
||||
*writecb_ptr = bufev->writecb;
|
||||
if (eventcb_ptr)
|
||||
*eventcb_ptr = bufev->errorcb;
|
||||
if (cbarg_ptr)
|
||||
*cbarg_ptr = bufev->cbarg;
|
||||
|
||||
BEV_UNLOCK(bufev);
|
||||
}
|
||||
|
||||
struct evbuffer *
|
||||
bufferevent_get_input(struct bufferevent *bufev)
|
||||
{
|
||||
|
@ -373,6 +416,16 @@ bufferevent_get_base(struct bufferevent *bufev)
|
|||
return bufev->ev_base;
|
||||
}
|
||||
|
||||
int
|
||||
bufferevent_get_priority(const struct bufferevent *bufev)
|
||||
{
|
||||
if (event_initialized(&bufev->ev_read)) {
|
||||
return event_get_priority(&bufev->ev_read);
|
||||
} else {
|
||||
return event_base_get_npriorities(bufev->ev_base) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
bufferevent_write(struct bufferevent *bufev, const void *data, size_t size)
|
||||
{
|
||||
|
@ -411,7 +464,7 @@ bufferevent_enable(struct bufferevent *bufev, short event)
|
|||
short impl_events = event;
|
||||
int r = 0;
|
||||
|
||||
_bufferevent_incref_and_lock(bufev);
|
||||
bufferevent_incref_and_lock_(bufev);
|
||||
if (bufev_private->read_suspended)
|
||||
impl_events &= ~EV_READ;
|
||||
if (bufev_private->write_suspended)
|
||||
|
@ -422,7 +475,7 @@ bufferevent_enable(struct bufferevent *bufev, short event)
|
|||
if (impl_events && bufev->be_ops->enable(bufev, impl_events) < 0)
|
||||
r = -1;
|
||||
|
||||
_bufferevent_decref_and_unlock(bufev);
|
||||
bufferevent_decref_and_unlock_(bufev);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -477,7 +530,7 @@ bufferevent_settimeout(struct bufferevent *bufev,
|
|||
|
||||
|
||||
int
|
||||
bufferevent_disable_hard(struct bufferevent *bufev, short event)
|
||||
bufferevent_disable_hard_(struct bufferevent *bufev, short event)
|
||||
{
|
||||
int r = 0;
|
||||
struct bufferevent_private *bufev_private =
|
||||
|
@ -561,6 +614,32 @@ bufferevent_setwatermark(struct bufferevent *bufev, short events,
|
|||
BEV_UNLOCK(bufev);
|
||||
}
|
||||
|
||||
int
|
||||
bufferevent_getwatermark(struct bufferevent *bufev, short events,
|
||||
size_t *lowmark, size_t *highmark)
|
||||
{
|
||||
if (events == EV_WRITE) {
|
||||
BEV_LOCK(bufev);
|
||||
if (lowmark)
|
||||
*lowmark = bufev->wm_write.low;
|
||||
if (highmark)
|
||||
*highmark = bufev->wm_write.high;
|
||||
BEV_UNLOCK(bufev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (events == EV_READ) {
|
||||
BEV_LOCK(bufev);
|
||||
if (lowmark)
|
||||
*lowmark = bufev->wm_read.low;
|
||||
if (highmark)
|
||||
*highmark = bufev->wm_read.high;
|
||||
BEV_UNLOCK(bufev);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
bufferevent_flush(struct bufferevent *bufev,
|
||||
short iotype,
|
||||
|
@ -575,7 +654,7 @@ bufferevent_flush(struct bufferevent *bufev,
|
|||
}
|
||||
|
||||
void
|
||||
_bufferevent_incref_and_lock(struct bufferevent *bufev)
|
||||
bufferevent_incref_and_lock_(struct bufferevent *bufev)
|
||||
{
|
||||
struct bufferevent_private *bufev_private =
|
||||
BEV_UPCAST(bufev);
|
||||
|
@ -585,7 +664,7 @@ _bufferevent_incref_and_lock(struct bufferevent *bufev)
|
|||
|
||||
#if 0
|
||||
static void
|
||||
_bufferevent_transfer_lock_ownership(struct bufferevent *donor,
|
||||
bufferevent_transfer_lock_ownership_(struct bufferevent *donor,
|
||||
struct bufferevent *recipient)
|
||||
{
|
||||
struct bufferevent_private *d = BEV_UPCAST(donor);
|
||||
|
@ -602,11 +681,13 @@ _bufferevent_transfer_lock_ownership(struct bufferevent *donor,
|
|||
#endif
|
||||
|
||||
int
|
||||
_bufferevent_decref_and_unlock(struct bufferevent *bufev)
|
||||
bufferevent_decref_and_unlock_(struct bufferevent *bufev)
|
||||
{
|
||||
struct bufferevent_private *bufev_private =
|
||||
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
|
||||
struct bufferevent *underlying;
|
||||
int n_cbs = 0;
|
||||
#define MAX_CBS 16
|
||||
struct event_callback *cbs[MAX_CBS];
|
||||
|
||||
EVUTIL_ASSERT(bufev_private->refcnt > 0);
|
||||
|
||||
|
@ -615,6 +696,41 @@ _bufferevent_decref_and_unlock(struct bufferevent *bufev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (bufev->be_ops->unlink)
|
||||
bufev->be_ops->unlink(bufev);
|
||||
|
||||
/* Okay, we're out of references. Let's finalize this once all the
|
||||
* callbacks are done running. */
|
||||
cbs[0] = &bufev->ev_read.ev_evcallback;
|
||||
cbs[1] = &bufev->ev_write.ev_evcallback;
|
||||
cbs[2] = &bufev_private->deferred;
|
||||
n_cbs = 3;
|
||||
if (bufev_private->rate_limiting) {
|
||||
struct event *e = &bufev_private->rate_limiting->refill_bucket_event;
|
||||
if (event_initialized(e))
|
||||
cbs[n_cbs++] = &e->ev_evcallback;
|
||||
}
|
||||
n_cbs += evbuffer_get_callbacks_(bufev->input, cbs+n_cbs, MAX_CBS-n_cbs);
|
||||
n_cbs += evbuffer_get_callbacks_(bufev->output, cbs+n_cbs, MAX_CBS-n_cbs);
|
||||
|
||||
event_callback_finalize_many_(bufev->ev_base, n_cbs, cbs,
|
||||
bufferevent_finalize_cb_);
|
||||
|
||||
#undef MAX_CBS
|
||||
BEV_UNLOCK(bufev);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
bufferevent_finalize_cb_(struct event_callback *evcb, void *arg_)
|
||||
{
|
||||
struct bufferevent *bufev = arg_;
|
||||
struct bufferevent *underlying;
|
||||
struct bufferevent_private *bufev_private =
|
||||
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
|
||||
|
||||
BEV_LOCK(bufev);
|
||||
underlying = bufferevent_get_underlying(bufev);
|
||||
|
||||
/* Clean up the shared info */
|
||||
|
@ -630,18 +746,14 @@ _bufferevent_decref_and_unlock(struct bufferevent *bufev)
|
|||
|
||||
if (bufev_private->rate_limiting) {
|
||||
if (bufev_private->rate_limiting->group)
|
||||
bufferevent_remove_from_rate_limit_group_internal(bufev,0);
|
||||
if (event_initialized(&bufev_private->rate_limiting->refill_bucket_event))
|
||||
event_del(&bufev_private->rate_limiting->refill_bucket_event);
|
||||
event_debug_unassign(&bufev_private->rate_limiting->refill_bucket_event);
|
||||
bufferevent_remove_from_rate_limit_group_internal_(bufev,0);
|
||||
mm_free(bufev_private->rate_limiting);
|
||||
bufev_private->rate_limiting = NULL;
|
||||
}
|
||||
|
||||
event_debug_unassign(&bufev->ev_read);
|
||||
event_debug_unassign(&bufev->ev_write);
|
||||
|
||||
BEV_UNLOCK(bufev);
|
||||
|
||||
if (bufev_private->own_lock)
|
||||
EVTHREAD_FREE_LOCK(bufev_private->lock,
|
||||
EVTHREAD_LOCKTYPE_RECURSIVE);
|
||||
|
@ -660,16 +772,14 @@ _bufferevent_decref_and_unlock(struct bufferevent *bufev)
|
|||
* It would probably save us some headaches.
|
||||
*/
|
||||
if (underlying)
|
||||
bufferevent_decref(underlying);
|
||||
|
||||
return 1;
|
||||
bufferevent_decref_(underlying);
|
||||
}
|
||||
|
||||
int
|
||||
bufferevent_decref(struct bufferevent *bufev)
|
||||
{
|
||||
BEV_LOCK(bufev);
|
||||
return _bufferevent_decref_and_unlock(bufev);
|
||||
return bufferevent_decref_and_unlock_(bufev);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -677,8 +787,8 @@ bufferevent_free(struct bufferevent *bufev)
|
|||
{
|
||||
BEV_LOCK(bufev);
|
||||
bufferevent_setcb(bufev, NULL, NULL, NULL, NULL);
|
||||
_bufferevent_cancel_all(bufev);
|
||||
_bufferevent_decref_and_unlock(bufev);
|
||||
bufferevent_cancel_all_(bufev);
|
||||
bufferevent_decref_and_unlock_(bufev);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -687,15 +797,19 @@ bufferevent_incref(struct bufferevent *bufev)
|
|||
struct bufferevent_private *bufev_private =
|
||||
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
|
||||
|
||||
/* XXX: now that this function is public, we might want to
|
||||
* - return the count from this function
|
||||
* - create a new function to atomically grab the current refcount
|
||||
*/
|
||||
BEV_LOCK(bufev);
|
||||
++bufev_private->refcnt;
|
||||
BEV_UNLOCK(bufev);
|
||||
}
|
||||
|
||||
int
|
||||
bufferevent_enable_locking(struct bufferevent *bufev, void *lock)
|
||||
bufferevent_enable_locking_(struct bufferevent *bufev, void *lock)
|
||||
{
|
||||
#ifdef _EVENT_DISABLE_THREAD_SUPPORT
|
||||
#ifdef EVENT__DISABLE_THREAD_SUPPORT
|
||||
return -1;
|
||||
#else
|
||||
struct bufferevent *underlying;
|
||||
|
@ -722,7 +836,7 @@ bufferevent_enable_locking(struct bufferevent *bufev, void *lock)
|
|||
evbuffer_enable_locking(bufev->output, lock);
|
||||
|
||||
if (underlying && !BEV_UPCAST(underlying)->lock)
|
||||
bufferevent_enable_locking(underlying, lock);
|
||||
bufferevent_enable_locking_(underlying, lock);
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
|
@ -754,8 +868,22 @@ bufferevent_getfd(struct bufferevent *bev)
|
|||
return (res<0) ? -1 : d.fd;
|
||||
}
|
||||
|
||||
enum bufferevent_options
|
||||
bufferevent_get_options_(struct bufferevent *bev)
|
||||
{
|
||||
struct bufferevent_private *bev_p =
|
||||
EVUTIL_UPCAST(bev, struct bufferevent_private, bev);
|
||||
enum bufferevent_options options;
|
||||
|
||||
BEV_LOCK(bev);
|
||||
options = bev_p->options;
|
||||
BEV_UNLOCK(bev);
|
||||
return options;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_bufferevent_cancel_all(struct bufferevent *bev)
|
||||
bufferevent_cancel_all_(struct bufferevent *bev)
|
||||
{
|
||||
union bufferevent_ctrl_data d;
|
||||
memset(&d, 0, sizeof(d));
|
||||
|
@ -792,43 +920,32 @@ static void
|
|||
bufferevent_generic_read_timeout_cb(evutil_socket_t fd, short event, void *ctx)
|
||||
{
|
||||
struct bufferevent *bev = ctx;
|
||||
_bufferevent_incref_and_lock(bev);
|
||||
bufferevent_incref_and_lock_(bev);
|
||||
bufferevent_disable(bev, EV_READ);
|
||||
_bufferevent_run_eventcb(bev, BEV_EVENT_TIMEOUT|BEV_EVENT_READING);
|
||||
_bufferevent_decref_and_unlock(bev);
|
||||
bufferevent_run_eventcb_(bev, BEV_EVENT_TIMEOUT|BEV_EVENT_READING, 0);
|
||||
bufferevent_decref_and_unlock_(bev);
|
||||
}
|
||||
static void
|
||||
bufferevent_generic_write_timeout_cb(evutil_socket_t fd, short event, void *ctx)
|
||||
{
|
||||
struct bufferevent *bev = ctx;
|
||||
_bufferevent_incref_and_lock(bev);
|
||||
bufferevent_incref_and_lock_(bev);
|
||||
bufferevent_disable(bev, EV_WRITE);
|
||||
_bufferevent_run_eventcb(bev, BEV_EVENT_TIMEOUT|BEV_EVENT_WRITING);
|
||||
_bufferevent_decref_and_unlock(bev);
|
||||
bufferevent_run_eventcb_(bev, BEV_EVENT_TIMEOUT|BEV_EVENT_WRITING, 0);
|
||||
bufferevent_decref_and_unlock_(bev);
|
||||
}
|
||||
|
||||
void
|
||||
_bufferevent_init_generic_timeout_cbs(struct bufferevent *bev)
|
||||
bufferevent_init_generic_timeout_cbs_(struct bufferevent *bev)
|
||||
{
|
||||
evtimer_assign(&bev->ev_read, bev->ev_base,
|
||||
event_assign(&bev->ev_read, bev->ev_base, -1, EV_FINALIZE,
|
||||
bufferevent_generic_read_timeout_cb, bev);
|
||||
evtimer_assign(&bev->ev_write, bev->ev_base,
|
||||
event_assign(&bev->ev_write, bev->ev_base, -1, EV_FINALIZE,
|
||||
bufferevent_generic_write_timeout_cb, bev);
|
||||
}
|
||||
|
||||
int
|
||||
_bufferevent_del_generic_timeout_cbs(struct bufferevent *bev)
|
||||
{
|
||||
int r1,r2;
|
||||
r1 = event_del(&bev->ev_read);
|
||||
r2 = event_del(&bev->ev_write);
|
||||
if (r1<0 || r2<0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
_bufferevent_generic_adj_timeouts(struct bufferevent *bev)
|
||||
bufferevent_generic_adj_timeouts_(struct bufferevent *bev)
|
||||
{
|
||||
const short enabled = bev->enabled;
|
||||
struct bufferevent_private *bev_p =
|
||||
|
@ -852,24 +969,47 @@ _bufferevent_generic_adj_timeouts(struct bufferevent *bev)
|
|||
}
|
||||
|
||||
int
|
||||
_bufferevent_add_event(struct event *ev, const struct timeval *tv)
|
||||
bufferevent_generic_adj_existing_timeouts_(struct bufferevent *bev)
|
||||
{
|
||||
if (tv->tv_sec == 0 && tv->tv_usec == 0)
|
||||
int r = 0;
|
||||
if (event_pending(&bev->ev_read, EV_READ, NULL)) {
|
||||
if (evutil_timerisset(&bev->timeout_read)) {
|
||||
if (bufferevent_add_event_(&bev->ev_read, &bev->timeout_read) < 0)
|
||||
r = -1;
|
||||
} else {
|
||||
event_remove_timer(&bev->ev_read);
|
||||
}
|
||||
}
|
||||
if (event_pending(&bev->ev_write, EV_WRITE, NULL)) {
|
||||
if (evutil_timerisset(&bev->timeout_write)) {
|
||||
if (bufferevent_add_event_(&bev->ev_write, &bev->timeout_write) < 0)
|
||||
r = -1;
|
||||
} else {
|
||||
event_remove_timer(&bev->ev_write);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
bufferevent_add_event_(struct event *ev, const struct timeval *tv)
|
||||
{
|
||||
if (!evutil_timerisset(tv))
|
||||
return event_add(ev, NULL);
|
||||
else
|
||||
return event_add(ev, tv);
|
||||
}
|
||||
|
||||
/* For use by user programs only; internally, we should be calling
|
||||
either _bufferevent_incref_and_lock(), or BEV_LOCK. */
|
||||
either bufferevent_incref_and_lock_(), or BEV_LOCK. */
|
||||
void
|
||||
bufferevent_lock(struct bufferevent *bev)
|
||||
{
|
||||
_bufferevent_incref_and_lock(bev);
|
||||
bufferevent_incref_and_lock_(bev);
|
||||
}
|
||||
|
||||
void
|
||||
bufferevent_unlock(struct bufferevent *bev)
|
||||
{
|
||||
_bufferevent_decref_and_unlock(bev);
|
||||
bufferevent_decref_and_unlock_(bev);
|
||||
}
|
||||
|
|
|
@ -27,8 +27,9 @@
|
|||
*/
|
||||
|
||||
#include "event2/event-config.h"
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#ifdef _EVENT_HAVE_SYS_TIME_H
|
||||
#ifdef EVENT__HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
|
@ -36,14 +37,14 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef _EVENT_HAVE_STDARG_H
|
||||
#ifdef EVENT__HAVE_STDARG_H
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
#ifdef _EVENT_HAVE_UNISTD_H
|
||||
#ifdef EVENT__HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
|
@ -92,8 +93,9 @@ const struct bufferevent_ops bufferevent_ops_async = {
|
|||
evutil_offsetof(struct bufferevent_async, bev.bev),
|
||||
be_async_enable,
|
||||
be_async_disable,
|
||||
NULL, /* Unlink */
|
||||
be_async_destruct,
|
||||
_bufferevent_generic_adj_timeouts,
|
||||
bufferevent_generic_adj_timeouts_,
|
||||
be_async_flush,
|
||||
be_async_ctrl,
|
||||
};
|
||||
|
@ -142,7 +144,7 @@ bev_async_del_write(struct bufferevent_async *beva)
|
|||
|
||||
if (beva->write_added) {
|
||||
beva->write_added = 0;
|
||||
event_base_del_virtual(bev->ev_base);
|
||||
event_base_del_virtual_(bev->ev_base);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,7 +155,7 @@ bev_async_del_read(struct bufferevent_async *beva)
|
|||
|
||||
if (beva->read_added) {
|
||||
beva->read_added = 0;
|
||||
event_base_del_virtual(bev->ev_base);
|
||||
event_base_del_virtual_(bev->ev_base);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,7 +166,7 @@ bev_async_add_write(struct bufferevent_async *beva)
|
|||
|
||||
if (!beva->write_added) {
|
||||
beva->write_added = 1;
|
||||
event_base_add_virtual(bev->ev_base);
|
||||
event_base_add_virtual_(bev->ev_base);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,7 +177,7 @@ bev_async_add_read(struct bufferevent_async *beva)
|
|||
|
||||
if (!beva->read_added) {
|
||||
beva->read_added = 1;
|
||||
event_base_add_virtual(bev->ev_base);
|
||||
event_base_add_virtual_(bev->ev_base);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,7 +202,7 @@ bev_async_consider_writing(struct bufferevent_async *beva)
|
|||
|
||||
/* This is safe so long as bufferevent_get_write_max never returns
|
||||
* more than INT_MAX. That's true for now. XXXX */
|
||||
limit = (int)_bufferevent_get_write_max(&beva->bev);
|
||||
limit = (int)bufferevent_get_write_max_(&beva->bev);
|
||||
if (at_most >= (size_t)limit && limit >= 0)
|
||||
at_most = limit;
|
||||
|
||||
|
@ -210,15 +212,15 @@ bev_async_consider_writing(struct bufferevent_async *beva)
|
|||
}
|
||||
|
||||
/* XXXX doesn't respect low-water mark very well. */
|
||||
bufferevent_incref(bev);
|
||||
if (evbuffer_launch_write(bev->output, at_most,
|
||||
bufferevent_incref_(bev);
|
||||
if (evbuffer_launch_write_(bev->output, at_most,
|
||||
&beva->write_overlapped)) {
|
||||
bufferevent_decref(bev);
|
||||
bufferevent_decref_(bev);
|
||||
beva->ok = 0;
|
||||
_bufferevent_run_eventcb(bev, BEV_EVENT_ERROR);
|
||||
bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR, 0);
|
||||
} else {
|
||||
beva->write_in_progress = at_most;
|
||||
_bufferevent_decrement_write_buckets(&beva->bev, at_most);
|
||||
bufferevent_decrement_write_buckets_(&beva->bev, at_most);
|
||||
bev_async_add_write(beva);
|
||||
}
|
||||
}
|
||||
|
@ -255,8 +257,8 @@ bev_async_consider_reading(struct bufferevent_async *beva)
|
|||
}
|
||||
|
||||
/* XXXX This over-commits. */
|
||||
/* XXXX see also not above on cast on _bufferevent_get_write_max() */
|
||||
limit = (int)_bufferevent_get_read_max(&beva->bev);
|
||||
/* XXXX see also not above on cast on bufferevent_get_write_max_() */
|
||||
limit = (int)bufferevent_get_read_max_(&beva->bev);
|
||||
if (at_most >= (size_t)limit && limit >= 0)
|
||||
at_most = limit;
|
||||
|
||||
|
@ -265,14 +267,14 @@ bev_async_consider_reading(struct bufferevent_async *beva)
|
|||
return;
|
||||
}
|
||||
|
||||
bufferevent_incref(bev);
|
||||
if (evbuffer_launch_read(bev->input, at_most, &beva->read_overlapped)) {
|
||||
bufferevent_incref_(bev);
|
||||
if (evbuffer_launch_read_(bev->input, at_most, &beva->read_overlapped)) {
|
||||
beva->ok = 0;
|
||||
_bufferevent_run_eventcb(bev, BEV_EVENT_ERROR);
|
||||
bufferevent_decref(bev);
|
||||
bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR, 0);
|
||||
bufferevent_decref_(bev);
|
||||
} else {
|
||||
beva->read_in_progress = at_most;
|
||||
_bufferevent_decrement_read_buckets(&beva->bev, at_most);
|
||||
bufferevent_decrement_read_buckets_(&beva->bev, at_most);
|
||||
bev_async_add_read(beva);
|
||||
}
|
||||
|
||||
|
@ -290,12 +292,12 @@ be_async_outbuf_callback(struct evbuffer *buf,
|
|||
/* If we added data to the outbuf and were not writing before,
|
||||
* we may want to write now. */
|
||||
|
||||
_bufferevent_incref_and_lock(bev);
|
||||
bufferevent_incref_and_lock_(bev);
|
||||
|
||||
if (cbinfo->n_added)
|
||||
bev_async_consider_writing(bev_async);
|
||||
|
||||
_bufferevent_decref_and_unlock(bev);
|
||||
bufferevent_decref_and_unlock_(bev);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -309,12 +311,12 @@ be_async_inbuf_callback(struct evbuffer *buf,
|
|||
/* If we drained data from the inbuf and were not reading before,
|
||||
* we may want to read now */
|
||||
|
||||
_bufferevent_incref_and_lock(bev);
|
||||
bufferevent_incref_and_lock_(bev);
|
||||
|
||||
if (cbinfo->n_deleted)
|
||||
bev_async_consider_reading(bev_async);
|
||||
|
||||
_bufferevent_decref_and_unlock(bev);
|
||||
bufferevent_decref_and_unlock_(bev);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -378,15 +380,11 @@ be_async_destruct(struct bufferevent *bev)
|
|||
bev_async_del_read(bev_async);
|
||||
bev_async_del_write(bev_async);
|
||||
|
||||
fd = _evbuffer_overlapped_get_fd(bev->input);
|
||||
if (bev_p->options & BEV_OPT_CLOSE_ON_FREE) {
|
||||
/* XXXX possible double-close */
|
||||
fd = evbuffer_overlapped_get_fd_(bev->input);
|
||||
if (fd != (evutil_socket_t)INVALID_SOCKET &&
|
||||
(bev_p->options & BEV_OPT_CLOSE_ON_FREE)) {
|
||||
evutil_closesocket(fd);
|
||||
}
|
||||
/* delete this in case non-blocking connect was used */
|
||||
if (event_initialized(&bev->ev_write)) {
|
||||
event_del(&bev->ev_write);
|
||||
_bufferevent_del_generic_timeout_cbs(bev);
|
||||
evbuffer_overlapped_set_fd_(bev->input, INVALID_SOCKET);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -398,7 +396,7 @@ bev_async_set_wsa_error(struct bufferevent *bev, struct event_overlapped *eo)
|
|||
DWORD bytes, flags;
|
||||
evutil_socket_t fd;
|
||||
|
||||
fd = _evbuffer_overlapped_get_fd(bev->input);
|
||||
fd = evbuffer_overlapped_get_fd_(bev->input);
|
||||
WSAGetOverlappedResult(fd, &eo->overlapped, &bytes, FALSE, &flags);
|
||||
}
|
||||
|
||||
|
@ -421,21 +419,21 @@ connect_complete(struct event_overlapped *eo, ev_uintptr_t key,
|
|||
|
||||
EVUTIL_ASSERT(bev_a->bev.connecting);
|
||||
bev_a->bev.connecting = 0;
|
||||
sock = _evbuffer_overlapped_get_fd(bev_a->bev.bev.input);
|
||||
sock = evbuffer_overlapped_get_fd_(bev_a->bev.bev.input);
|
||||
/* XXXX Handle error? */
|
||||
setsockopt(sock, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0);
|
||||
|
||||
if (ok)
|
||||
bufferevent_async_set_connected(bev);
|
||||
bufferevent_async_set_connected_(bev);
|
||||
else
|
||||
bev_async_set_wsa_error(bev, eo);
|
||||
|
||||
_bufferevent_run_eventcb(bev,
|
||||
ok? BEV_EVENT_CONNECTED : BEV_EVENT_ERROR);
|
||||
bufferevent_run_eventcb_(bev,
|
||||
ok? BEV_EVENT_CONNECTED : BEV_EVENT_ERROR, 0);
|
||||
|
||||
event_base_del_virtual(bev->ev_base);
|
||||
event_base_del_virtual_(bev->ev_base);
|
||||
|
||||
_bufferevent_decref_and_unlock(bev);
|
||||
bufferevent_decref_and_unlock_(bev);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -450,10 +448,10 @@ read_complete(struct event_overlapped *eo, ev_uintptr_t key,
|
|||
EVUTIL_ASSERT(bev_a->read_in_progress);
|
||||
|
||||
amount_unread = bev_a->read_in_progress - nbytes;
|
||||
evbuffer_commit_read(bev->input, nbytes);
|
||||
evbuffer_commit_read_(bev->input, nbytes);
|
||||
bev_a->read_in_progress = 0;
|
||||
if (amount_unread)
|
||||
_bufferevent_decrement_read_buckets(&bev_a->bev, -amount_unread);
|
||||
bufferevent_decrement_read_buckets_(&bev_a->bev, -amount_unread);
|
||||
|
||||
if (!ok)
|
||||
bev_async_set_wsa_error(bev, eo);
|
||||
|
@ -461,21 +459,20 @@ read_complete(struct event_overlapped *eo, ev_uintptr_t key,
|
|||
if (bev_a->ok) {
|
||||
if (ok && nbytes) {
|
||||
BEV_RESET_GENERIC_READ_TIMEOUT(bev);
|
||||
if (evbuffer_get_length(bev->input) >= bev->wm_read.low)
|
||||
_bufferevent_run_readcb(bev);
|
||||
bufferevent_trigger_nolock_(bev, EV_READ, 0);
|
||||
bev_async_consider_reading(bev_a);
|
||||
} else if (!ok) {
|
||||
what |= BEV_EVENT_ERROR;
|
||||
bev_a->ok = 0;
|
||||
_bufferevent_run_eventcb(bev, what);
|
||||
bufferevent_run_eventcb_(bev, what, 0);
|
||||
} else if (!nbytes) {
|
||||
what |= BEV_EVENT_EOF;
|
||||
bev_a->ok = 0;
|
||||
_bufferevent_run_eventcb(bev, what);
|
||||
bufferevent_run_eventcb_(bev, what, 0);
|
||||
}
|
||||
}
|
||||
|
||||
_bufferevent_decref_and_unlock(bev);
|
||||
bufferevent_decref_and_unlock_(bev);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -491,11 +488,11 @@ write_complete(struct event_overlapped *eo, ev_uintptr_t key,
|
|||
EVUTIL_ASSERT(bev_a->write_in_progress);
|
||||
|
||||
amount_unwritten = bev_a->write_in_progress - nbytes;
|
||||
evbuffer_commit_write(bev->output, nbytes);
|
||||
evbuffer_commit_write_(bev->output, nbytes);
|
||||
bev_a->write_in_progress = 0;
|
||||
|
||||
if (amount_unwritten)
|
||||
_bufferevent_decrement_write_buckets(&bev_a->bev,
|
||||
bufferevent_decrement_write_buckets_(&bev_a->bev,
|
||||
-amount_unwritten);
|
||||
|
||||
|
||||
|
@ -505,26 +502,24 @@ write_complete(struct event_overlapped *eo, ev_uintptr_t key,
|
|||
if (bev_a->ok) {
|
||||
if (ok && nbytes) {
|
||||
BEV_RESET_GENERIC_WRITE_TIMEOUT(bev);
|
||||
if (evbuffer_get_length(bev->output) <=
|
||||
bev->wm_write.low)
|
||||
_bufferevent_run_writecb(bev);
|
||||
bufferevent_trigger_nolock_(bev, EV_WRITE, 0);
|
||||
bev_async_consider_writing(bev_a);
|
||||
} else if (!ok) {
|
||||
what |= BEV_EVENT_ERROR;
|
||||
bev_a->ok = 0;
|
||||
_bufferevent_run_eventcb(bev, what);
|
||||
bufferevent_run_eventcb_(bev, what, 0);
|
||||
} else if (!nbytes) {
|
||||
what |= BEV_EVENT_EOF;
|
||||
bev_a->ok = 0;
|
||||
_bufferevent_run_eventcb(bev, what);
|
||||
bufferevent_run_eventcb_(bev, what, 0);
|
||||
}
|
||||
}
|
||||
|
||||
_bufferevent_decref_and_unlock(bev);
|
||||
bufferevent_decref_and_unlock_(bev);
|
||||
}
|
||||
|
||||
struct bufferevent *
|
||||
bufferevent_async_new(struct event_base *base,
|
||||
bufferevent_async_new_(struct event_base *base,
|
||||
evutil_socket_t fd, int options)
|
||||
{
|
||||
struct bufferevent_async *bev_a;
|
||||
|
@ -533,10 +528,10 @@ bufferevent_async_new(struct event_base *base,
|
|||
|
||||
options |= BEV_OPT_THREADSAFE;
|
||||
|
||||
if (!(iocp = event_base_get_iocp(base)))
|
||||
if (!(iocp = event_base_get_iocp_(base)))
|
||||
return NULL;
|
||||
|
||||
if (fd >= 0 && event_iocp_port_associate(iocp, fd, 1)<0) {
|
||||
if (fd >= 0 && event_iocp_port_associate_(iocp, fd, 1)<0) {
|
||||
int err = GetLastError();
|
||||
/* We may have alrady associated this fd with a port.
|
||||
* Let's hope it's this port, and that the error code
|
||||
|
@ -549,30 +544,30 @@ bufferevent_async_new(struct event_base *base,
|
|||
return NULL;
|
||||
|
||||
bev = &bev_a->bev.bev;
|
||||
if (!(bev->input = evbuffer_overlapped_new(fd))) {
|
||||
if (!(bev->input = evbuffer_overlapped_new_(fd))) {
|
||||
mm_free(bev_a);
|
||||
return NULL;
|
||||
}
|
||||
if (!(bev->output = evbuffer_overlapped_new(fd))) {
|
||||
if (!(bev->output = evbuffer_overlapped_new_(fd))) {
|
||||
evbuffer_free(bev->input);
|
||||
mm_free(bev_a);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (bufferevent_init_common(&bev_a->bev, base, &bufferevent_ops_async,
|
||||
if (bufferevent_init_common_(&bev_a->bev, base, &bufferevent_ops_async,
|
||||
options)<0)
|
||||
goto err;
|
||||
|
||||
evbuffer_add_cb(bev->input, be_async_inbuf_callback, bev);
|
||||
evbuffer_add_cb(bev->output, be_async_outbuf_callback, bev);
|
||||
|
||||
event_overlapped_init(&bev_a->connect_overlapped, connect_complete);
|
||||
event_overlapped_init(&bev_a->read_overlapped, read_complete);
|
||||
event_overlapped_init(&bev_a->write_overlapped, write_complete);
|
||||
event_overlapped_init_(&bev_a->connect_overlapped, connect_complete);
|
||||
event_overlapped_init_(&bev_a->read_overlapped, read_complete);
|
||||
event_overlapped_init_(&bev_a->write_overlapped, write_complete);
|
||||
|
||||
bufferevent_init_generic_timeout_cbs_(bev);
|
||||
|
||||
bev_a->ok = fd >= 0;
|
||||
if (bev_a->ok)
|
||||
_bufferevent_init_generic_timeout_cbs(bev);
|
||||
|
||||
return bev;
|
||||
err:
|
||||
|
@ -581,23 +576,23 @@ err:
|
|||
}
|
||||
|
||||
void
|
||||
bufferevent_async_set_connected(struct bufferevent *bev)
|
||||
bufferevent_async_set_connected_(struct bufferevent *bev)
|
||||
{
|
||||
struct bufferevent_async *bev_async = upcast(bev);
|
||||
bev_async->ok = 1;
|
||||
_bufferevent_init_generic_timeout_cbs(bev);
|
||||
bufferevent_init_generic_timeout_cbs_(bev);
|
||||
/* Now's a good time to consider reading/writing */
|
||||
be_async_enable(bev, bev->enabled);
|
||||
}
|
||||
|
||||
int
|
||||
bufferevent_async_can_connect(struct bufferevent *bev)
|
||||
bufferevent_async_can_connect_(struct bufferevent *bev)
|
||||
{
|
||||
const struct win32_extension_fns *ext =
|
||||
event_get_win32_extension_fns();
|
||||
event_get_win32_extension_fns_();
|
||||
|
||||
if (BEV_IS_ASYNC(bev) &&
|
||||
event_base_get_iocp(bev->ev_base) &&
|
||||
event_base_get_iocp_(bev->ev_base) &&
|
||||
ext && ext->ConnectEx)
|
||||
return 1;
|
||||
|
||||
|
@ -605,14 +600,14 @@ bufferevent_async_can_connect(struct bufferevent *bev)
|
|||
}
|
||||
|
||||
int
|
||||
bufferevent_async_connect(struct bufferevent *bev, evutil_socket_t fd,
|
||||
bufferevent_async_connect_(struct bufferevent *bev, evutil_socket_t fd,
|
||||
const struct sockaddr *sa, int socklen)
|
||||
{
|
||||
BOOL rc;
|
||||
struct bufferevent_async *bev_async = upcast(bev);
|
||||
struct sockaddr_storage ss;
|
||||
const struct win32_extension_fns *ext =
|
||||
event_get_win32_extension_fns();
|
||||
event_get_win32_extension_fns_();
|
||||
|
||||
EVUTIL_ASSERT(ext && ext->ConnectEx && fd >= 0 && sa != NULL);
|
||||
|
||||
|
@ -637,15 +632,15 @@ bufferevent_async_connect(struct bufferevent *bev, evutil_socket_t fd,
|
|||
WSAGetLastError() != WSAEINVAL)
|
||||
return -1;
|
||||
|
||||
event_base_add_virtual(bev->ev_base);
|
||||
bufferevent_incref(bev);
|
||||
event_base_add_virtual_(bev->ev_base);
|
||||
bufferevent_incref_(bev);
|
||||
rc = ext->ConnectEx(fd, sa, socklen, NULL, 0, NULL,
|
||||
&bev_async->connect_overlapped.overlapped);
|
||||
if (rc || WSAGetLastError() == ERROR_IO_PENDING)
|
||||
return 0;
|
||||
|
||||
event_base_del_virtual(bev->ev_base);
|
||||
bufferevent_decref(bev);
|
||||
event_base_del_virtual_(bev->ev_base);
|
||||
bufferevent_decref_(bev);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@ -656,27 +651,28 @@ be_async_ctrl(struct bufferevent *bev, enum bufferevent_ctrl_op op,
|
|||
{
|
||||
switch (op) {
|
||||
case BEV_CTRL_GET_FD:
|
||||
data->fd = _evbuffer_overlapped_get_fd(bev->input);
|
||||
data->fd = evbuffer_overlapped_get_fd_(bev->input);
|
||||
return 0;
|
||||
case BEV_CTRL_SET_FD: {
|
||||
struct event_iocp_port *iocp;
|
||||
|
||||
if (data->fd == _evbuffer_overlapped_get_fd(bev->input))
|
||||
if (data->fd == evbuffer_overlapped_get_fd_(bev->input))
|
||||
return 0;
|
||||
if (!(iocp = event_base_get_iocp(bev->ev_base)))
|
||||
if (!(iocp = event_base_get_iocp_(bev->ev_base)))
|
||||
return -1;
|
||||
if (event_iocp_port_associate(iocp, data->fd, 1) < 0)
|
||||
if (event_iocp_port_associate_(iocp, data->fd, 1) < 0)
|
||||
return -1;
|
||||
_evbuffer_overlapped_set_fd(bev->input, data->fd);
|
||||
_evbuffer_overlapped_set_fd(bev->output, data->fd);
|
||||
evbuffer_overlapped_set_fd_(bev->input, data->fd);
|
||||
evbuffer_overlapped_set_fd_(bev->output, data->fd);
|
||||
return 0;
|
||||
}
|
||||
case BEV_CTRL_CANCEL_ALL: {
|
||||
struct bufferevent_async *bev_a = upcast(bev);
|
||||
evutil_socket_t fd = _evbuffer_overlapped_get_fd(bev->input);
|
||||
evutil_socket_t fd = evbuffer_overlapped_get_fd_(bev->input);
|
||||
if (fd != (evutil_socket_t)INVALID_SOCKET &&
|
||||
(bev_a->bev.options & BEV_OPT_CLOSE_ON_FREE)) {
|
||||
closesocket(fd);
|
||||
evbuffer_overlapped_set_fd_(bev->input, INVALID_SOCKET);
|
||||
}
|
||||
bev_a->ok = 0;
|
||||
return 0;
|
||||
|
|
|
@ -26,11 +26,13 @@
|
|||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "event2/event-config.h"
|
||||
|
||||
#ifdef _EVENT_HAVE_SYS_TIME_H
|
||||
#ifdef EVENT__HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
|
@ -38,11 +40,11 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef _EVENT_HAVE_STDARG_H
|
||||
#ifdef EVENT__HAVE_STDARG_H
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
|
@ -59,6 +61,7 @@
|
|||
/* prototypes */
|
||||
static int be_filter_enable(struct bufferevent *, short);
|
||||
static int be_filter_disable(struct bufferevent *, short);
|
||||
static void be_filter_unlink(struct bufferevent *);
|
||||
static void be_filter_destruct(struct bufferevent *);
|
||||
|
||||
static void be_filter_readcb(struct bufferevent *, void *);
|
||||
|
@ -68,6 +71,9 @@ static int be_filter_flush(struct bufferevent *bufev,
|
|||
short iotype, enum bufferevent_flush_mode mode);
|
||||
static int be_filter_ctrl(struct bufferevent *, enum bufferevent_ctrl_op, union bufferevent_ctrl_data *);
|
||||
|
||||
static void bufferevent_filtered_inbuf_cb(struct evbuffer *buf,
|
||||
const struct evbuffer_cb_info *cbinfo, void *arg);
|
||||
|
||||
static void bufferevent_filtered_outbuf_cb(struct evbuffer *buf,
|
||||
const struct evbuffer_cb_info *info, void *arg);
|
||||
|
||||
|
@ -76,6 +82,8 @@ struct bufferevent_filtered {
|
|||
|
||||
/** The bufferevent that we read/write filtered data from/to. */
|
||||
struct bufferevent *underlying;
|
||||
/** A callback on our inbuf to notice somebory removes data */
|
||||
struct evbuffer_cb_entry *inbuf_cb;
|
||||
/** A callback on our outbuf to notice when somebody adds data */
|
||||
struct evbuffer_cb_entry *outbuf_cb;
|
||||
/** True iff we have received an EOF callback from the underlying
|
||||
|
@ -97,8 +105,9 @@ const struct bufferevent_ops bufferevent_ops_filter = {
|
|||
evutil_offsetof(struct bufferevent_filtered, bev.bev),
|
||||
be_filter_enable,
|
||||
be_filter_disable,
|
||||
be_filter_unlink,
|
||||
be_filter_destruct,
|
||||
_bufferevent_generic_adj_timeouts,
|
||||
bufferevent_generic_adj_timeouts_,
|
||||
be_filter_flush,
|
||||
be_filter_ctrl,
|
||||
};
|
||||
|
@ -180,13 +189,13 @@ bufferevent_filter_new(struct bufferevent *underlying,
|
|||
if (!bufev_f)
|
||||
return NULL;
|
||||
|
||||
if (bufferevent_init_common(&bufev_f->bev, underlying->ev_base,
|
||||
if (bufferevent_init_common_(&bufev_f->bev, underlying->ev_base,
|
||||
&bufferevent_ops_filter, tmp_options) < 0) {
|
||||
mm_free(bufev_f);
|
||||
return NULL;
|
||||
}
|
||||
if (options & BEV_OPT_THREADSAFE) {
|
||||
bufferevent_enable_locking(downcast(bufev_f), NULL);
|
||||
bufferevent_enable_locking_(downcast(bufev_f), NULL);
|
||||
}
|
||||
|
||||
bufev_f->underlying = underlying;
|
||||
|
@ -199,28 +208,31 @@ bufferevent_filter_new(struct bufferevent *underlying,
|
|||
bufferevent_setcb(bufev_f->underlying,
|
||||
be_filter_readcb, be_filter_writecb, be_filter_eventcb, bufev_f);
|
||||
|
||||
bufev_f->inbuf_cb = evbuffer_add_cb(downcast(bufev_f)->input,
|
||||
bufferevent_filtered_inbuf_cb, bufev_f);
|
||||
evbuffer_cb_clear_flags(downcast(bufev_f)->input, bufev_f->inbuf_cb,
|
||||
EVBUFFER_CB_ENABLED);
|
||||
|
||||
bufev_f->outbuf_cb = evbuffer_add_cb(downcast(bufev_f)->output,
|
||||
bufferevent_filtered_outbuf_cb, bufev_f);
|
||||
|
||||
_bufferevent_init_generic_timeout_cbs(downcast(bufev_f));
|
||||
bufferevent_incref(underlying);
|
||||
bufferevent_init_generic_timeout_cbs_(downcast(bufev_f));
|
||||
bufferevent_incref_(underlying);
|
||||
|
||||
bufferevent_enable(underlying, EV_READ|EV_WRITE);
|
||||
bufferevent_suspend_read(underlying, BEV_SUSPEND_FILT_READ);
|
||||
bufferevent_suspend_read_(underlying, BEV_SUSPEND_FILT_READ);
|
||||
|
||||
return downcast(bufev_f);
|
||||
}
|
||||
|
||||
static void
|
||||
be_filter_destruct(struct bufferevent *bev)
|
||||
be_filter_unlink(struct bufferevent *bev)
|
||||
{
|
||||
struct bufferevent_filtered *bevf = upcast(bev);
|
||||
EVUTIL_ASSERT(bevf);
|
||||
if (bevf->free_context)
|
||||
bevf->free_context(bevf->context);
|
||||
|
||||
if (bevf->bev.options & BEV_OPT_CLOSE_ON_FREE) {
|
||||
/* Yes, there is also a decref in bufferevent_decref.
|
||||
/* Yes, there is also a decref in bufferevent_decref_.
|
||||
* That decref corresponds to the incref when we set
|
||||
* underlying for the first time. This decref is an
|
||||
* extra one to remove the last reference.
|
||||
|
@ -236,12 +248,25 @@ be_filter_destruct(struct bufferevent *bev)
|
|||
if (bevf->underlying->errorcb == be_filter_eventcb)
|
||||
bufferevent_setcb(bevf->underlying,
|
||||
NULL, NULL, NULL, NULL);
|
||||
bufferevent_unsuspend_read(bevf->underlying,
|
||||
bufferevent_unsuspend_read_(bevf->underlying,
|
||||
BEV_SUSPEND_FILT_READ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_bufferevent_del_generic_timeout_cbs(bev);
|
||||
static void
|
||||
be_filter_destruct(struct bufferevent *bev)
|
||||
{
|
||||
struct bufferevent_filtered *bevf = upcast(bev);
|
||||
EVUTIL_ASSERT(bevf);
|
||||
if (bevf->free_context)
|
||||
bevf->free_context(bevf->context);
|
||||
|
||||
if (bevf->inbuf_cb)
|
||||
evbuffer_remove_cb_entry(bev->input, bevf->inbuf_cb);
|
||||
|
||||
if (bevf->outbuf_cb)
|
||||
evbuffer_remove_cb_entry(bev->output, bevf->outbuf_cb);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -253,7 +278,7 @@ be_filter_enable(struct bufferevent *bev, short event)
|
|||
|
||||
if (event & EV_READ) {
|
||||
BEV_RESET_GENERIC_READ_TIMEOUT(bev);
|
||||
bufferevent_unsuspend_read(bevf->underlying,
|
||||
bufferevent_unsuspend_read_(bevf->underlying,
|
||||
BEV_SUSPEND_FILT_READ);
|
||||
}
|
||||
return 0;
|
||||
|
@ -267,7 +292,7 @@ be_filter_disable(struct bufferevent *bev, short event)
|
|||
BEV_DEL_GENERIC_WRITE_TIMEOUT(bev);
|
||||
if (event & EV_READ) {
|
||||
BEV_DEL_GENERIC_READ_TIMEOUT(bev);
|
||||
bufferevent_suspend_read(bevf->underlying,
|
||||
bufferevent_suspend_read_(bevf->underlying,
|
||||
BEV_SUSPEND_FILT_READ);
|
||||
}
|
||||
return 0;
|
||||
|
@ -336,7 +361,8 @@ be_filter_process_output(struct bufferevent_filtered *bevf,
|
|||
|
||||
/* disable the callback that calls this function
|
||||
when the user adds to the output buffer. */
|
||||
evbuffer_cb_set_flags(bufev->output, bevf->outbuf_cb, 0);
|
||||
evbuffer_cb_clear_flags(bufev->output, bevf->outbuf_cb,
|
||||
EVBUFFER_CB_ENABLED);
|
||||
|
||||
do {
|
||||
int processed = 0;
|
||||
|
@ -367,10 +393,9 @@ be_filter_process_output(struct bufferevent_filtered *bevf,
|
|||
/* Or if we have filled the underlying output buffer. */
|
||||
!be_underlying_writebuf_full(bevf,state));
|
||||
|
||||
if (processed &&
|
||||
evbuffer_get_length(bufev->output) <= bufev->wm_write.low) {
|
||||
if (processed) {
|
||||
/* call the write callback.*/
|
||||
_bufferevent_run_writecb(bufev);
|
||||
bufferevent_trigger_nolock_(bufev, EV_WRITE, 0);
|
||||
|
||||
if (res == BEV_OK &&
|
||||
(bufev->enabled & EV_WRITE) &&
|
||||
|
@ -403,68 +428,145 @@ bufferevent_filtered_outbuf_cb(struct evbuffer *buf,
|
|||
int processed_any = 0;
|
||||
/* Somebody added more data to the output buffer. Try to
|
||||
* process it, if we should. */
|
||||
_bufferevent_incref_and_lock(bev);
|
||||
bufferevent_incref_and_lock_(bev);
|
||||
be_filter_process_output(bevf, BEV_NORMAL, &processed_any);
|
||||
_bufferevent_decref_and_unlock(bev);
|
||||
bufferevent_decref_and_unlock_(bev);
|
||||
}
|
||||
}
|
||||
|
||||
/* Called when the underlying socket has read. */
|
||||
static void
|
||||
be_filter_readcb(struct bufferevent *underlying, void *_me)
|
||||
be_filter_read_nolock_(struct bufferevent *underlying, void *me_)
|
||||
{
|
||||
struct bufferevent_filtered *bevf = _me;
|
||||
struct bufferevent_filtered *bevf = me_;
|
||||
enum bufferevent_filter_result res;
|
||||
enum bufferevent_flush_mode state;
|
||||
struct bufferevent *bufev = downcast(bevf);
|
||||
struct bufferevent_private *bufev_private = BEV_UPCAST(bufev);
|
||||
int processed_any = 0;
|
||||
|
||||
_bufferevent_incref_and_lock(bufev);
|
||||
// It's possible our refcount is 0 at this point if another thread free'd our filterevent
|
||||
EVUTIL_ASSERT(bufev_private->refcnt >= 0);
|
||||
|
||||
// If our refcount is > 0
|
||||
if (bufev_private->refcnt > 0) {
|
||||
|
||||
if (bevf->got_eof)
|
||||
state = BEV_FINISHED;
|
||||
else
|
||||
state = BEV_NORMAL;
|
||||
|
||||
/* XXXX use return value */
|
||||
res = be_filter_process_input(bevf, state, &processed_any);
|
||||
(void)res;
|
||||
|
||||
/* XXX This should be in process_input, not here. There are
|
||||
* other places that can call process-input, and they should
|
||||
* force readcb calls as needed. */
|
||||
if (processed_any) {
|
||||
bufferevent_trigger_nolock_(bufev, EV_READ, 0);
|
||||
if (evbuffer_get_length(underlying->input) > 0 &&
|
||||
be_readbuf_full(bevf, state)) {
|
||||
/* data left in underlying buffer and filter input buffer
|
||||
* hit its read high watermark.
|
||||
* Schedule callback to avoid data gets stuck in underlying
|
||||
* input buffer.
|
||||
*/
|
||||
evbuffer_cb_set_flags(bufev->input, bevf->inbuf_cb,
|
||||
EVBUFFER_CB_ENABLED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Called when the size of our inbuf changes. */
|
||||
static void
|
||||
bufferevent_filtered_inbuf_cb(struct evbuffer *buf,
|
||||
const struct evbuffer_cb_info *cbinfo, void *arg)
|
||||
{
|
||||
struct bufferevent_filtered *bevf = arg;
|
||||
enum bufferevent_flush_mode state;
|
||||
struct bufferevent *bev = downcast(bevf);
|
||||
|
||||
BEV_LOCK(bev);
|
||||
|
||||
if (bevf->got_eof)
|
||||
state = BEV_FINISHED;
|
||||
else
|
||||
state = BEV_NORMAL;
|
||||
|
||||
/* XXXX use return value */
|
||||
res = be_filter_process_input(bevf, state, &processed_any);
|
||||
(void)res;
|
||||
|
||||
/* XXX This should be in process_input, not here. There are
|
||||
* other places that can call process-input, and they should
|
||||
* force readcb calls as needed. */
|
||||
if (processed_any &&
|
||||
evbuffer_get_length(bufev->input) >= bufev->wm_read.low)
|
||||
_bufferevent_run_readcb(bufev);
|
||||
if (!be_readbuf_full(bevf, state)) {
|
||||
/* opportunity to read data which was left in underlying
|
||||
* input buffer because filter input buffer hit read
|
||||
* high watermark.
|
||||
*/
|
||||
evbuffer_cb_clear_flags(bev->input, bevf->inbuf_cb,
|
||||
EVBUFFER_CB_ENABLED);
|
||||
if (evbuffer_get_length(bevf->underlying->input) > 0)
|
||||
be_filter_read_nolock_(bevf->underlying, bevf);
|
||||
}
|
||||
|
||||
_bufferevent_decref_and_unlock(bufev);
|
||||
BEV_UNLOCK(bev);
|
||||
}
|
||||
|
||||
/* Called when the underlying socket has read. */
|
||||
static void
|
||||
be_filter_readcb(struct bufferevent *underlying, void *me_)
|
||||
{
|
||||
struct bufferevent_filtered *bevf = me_;
|
||||
struct bufferevent *bev = downcast(bevf);
|
||||
|
||||
BEV_LOCK(bev);
|
||||
|
||||
be_filter_read_nolock_(underlying, me_);
|
||||
|
||||
BEV_UNLOCK(bev);
|
||||
}
|
||||
|
||||
/* Called when the underlying socket has drained enough that we can write to
|
||||
it. */
|
||||
static void
|
||||
be_filter_writecb(struct bufferevent *underlying, void *_me)
|
||||
be_filter_writecb(struct bufferevent *underlying, void *me_)
|
||||
{
|
||||
struct bufferevent_filtered *bevf = _me;
|
||||
struct bufferevent_filtered *bevf = me_;
|
||||
struct bufferevent *bev = downcast(bevf);
|
||||
struct bufferevent_private *bufev_private = BEV_UPCAST(bev);
|
||||
int processed_any = 0;
|
||||
|
||||
_bufferevent_incref_and_lock(bev);
|
||||
be_filter_process_output(bevf, BEV_NORMAL, &processed_any);
|
||||
_bufferevent_decref_and_unlock(bev);
|
||||
BEV_LOCK(bev);
|
||||
|
||||
// It's possible our refcount is 0 at this point if another thread free'd our filterevent
|
||||
EVUTIL_ASSERT(bufev_private->refcnt >= 0);
|
||||
|
||||
// If our refcount is > 0
|
||||
if (bufev_private->refcnt > 0) {
|
||||
be_filter_process_output(bevf, BEV_NORMAL, &processed_any);
|
||||
}
|
||||
|
||||
BEV_UNLOCK(bev);
|
||||
}
|
||||
|
||||
/* Called when the underlying socket has given us an error */
|
||||
static void
|
||||
be_filter_eventcb(struct bufferevent *underlying, short what, void *_me)
|
||||
be_filter_eventcb(struct bufferevent *underlying, short what, void *me_)
|
||||
{
|
||||
struct bufferevent_filtered *bevf = _me;
|
||||
struct bufferevent_filtered *bevf = me_;
|
||||
struct bufferevent *bev = downcast(bevf);
|
||||
struct bufferevent_private *bufev_private = BEV_UPCAST(bev);
|
||||
|
||||
_bufferevent_incref_and_lock(bev);
|
||||
/* All we can really to is tell our own eventcb. */
|
||||
_bufferevent_run_eventcb(bev, what);
|
||||
_bufferevent_decref_and_unlock(bev);
|
||||
BEV_LOCK(bev);
|
||||
|
||||
// It's possible our refcount is 0 at this point if another thread free'd our filterevent
|
||||
EVUTIL_ASSERT(bufev_private->refcnt >= 0);
|
||||
|
||||
// If our refcount is > 0
|
||||
if (bufev_private->refcnt > 0) {
|
||||
|
||||
/* All we can really to is tell our own eventcb. */
|
||||
bufferevent_run_eventcb_(bev, what, 0);
|
||||
}
|
||||
|
||||
BEV_UNLOCK(bev);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -475,7 +577,7 @@ be_filter_flush(struct bufferevent *bufev,
|
|||
int processed_any = 0;
|
||||
EVUTIL_ASSERT(bevf);
|
||||
|
||||
_bufferevent_incref_and_lock(bufev);
|
||||
bufferevent_incref_and_lock_(bufev);
|
||||
|
||||
if (iotype & EV_READ) {
|
||||
be_filter_process_input(bevf, mode, &processed_any);
|
||||
|
@ -487,7 +589,7 @@ be_filter_flush(struct bufferevent *bufev,
|
|||
/* XXX does this want to recursively call lower-level flushes? */
|
||||
bufferevent_flush(bevf->underlying, iotype, mode);
|
||||
|
||||
_bufferevent_decref_and_unlock(bufev);
|
||||
bufferevent_decref_and_unlock_(bufev);
|
||||
|
||||
return processed_any;
|
||||
}
|
||||
|
@ -502,10 +604,20 @@ be_filter_ctrl(struct bufferevent *bev, enum bufferevent_ctrl_op op,
|
|||
bevf = upcast(bev);
|
||||
data->ptr = bevf->underlying;
|
||||
return 0;
|
||||
case BEV_CTRL_GET_FD:
|
||||
case BEV_CTRL_SET_FD:
|
||||
bevf = upcast(bev);
|
||||
|
||||
if (bevf->underlying &&
|
||||
bevf->underlying->be_ops &&
|
||||
bevf->underlying->be_ops->ctrl) {
|
||||
return (bevf->underlying->be_ops->ctrl)(bevf->underlying, op, data);
|
||||
}
|
||||
|
||||
case BEV_CTRL_GET_FD:
|
||||
case BEV_CTRL_CANCEL_ALL:
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -24,11 +24,17 @@
|
|||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
// Get rid of OSX 10.7 and greater deprecation warnings.
|
||||
#if defined(__APPLE__) && defined(__clang__)
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
#include "event2/event-config.h"
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#ifdef _EVENT_HAVE_SYS_TIME_H
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef EVENT__HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
|
@ -36,14 +42,14 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef _EVENT_HAVE_STDARG_H
|
||||
#ifdef EVENT__HAVE_STDARG_H
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
#ifdef _EVENT_HAVE_UNISTD_H
|
||||
#ifdef EVENT__HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
|
@ -60,6 +66,7 @@
|
|||
#include <openssl/bio.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include "openssl-compat.h"
|
||||
|
||||
/*
|
||||
* Define an OpenSSL bio that targets a bufferevent.
|
||||
|
@ -103,10 +110,8 @@ print_err(int val)
|
|||
static int
|
||||
bio_bufferevent_new(BIO *b)
|
||||
{
|
||||
b->init = 0;
|
||||
b->num = -1;
|
||||
b->ptr = NULL; /* We'll be putting the bufferevent in this field.*/
|
||||
b->flags = 0;
|
||||
BIO_set_init(b, 0);
|
||||
BIO_set_data(b, NULL); /* We'll be putting the bufferevent in this field.*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -116,12 +121,10 @@ bio_bufferevent_free(BIO *b)
|
|||
{
|
||||
if (!b)
|
||||
return 0;
|
||||
if (b->shutdown) {
|
||||
if (b->init && b->ptr)
|
||||
bufferevent_free(b->ptr);
|
||||
b->init = 0;
|
||||
b->flags = 0;
|
||||
b->ptr = NULL;
|
||||
if (BIO_get_shutdown(b)) {
|
||||
if (BIO_get_init(b) && BIO_get_data(b))
|
||||
bufferevent_free(BIO_get_data(b));
|
||||
BIO_free(b);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -137,10 +140,10 @@ bio_bufferevent_read(BIO *b, char *out, int outlen)
|
|||
|
||||
if (!out)
|
||||
return 0;
|
||||
if (!b->ptr)
|
||||
if (!BIO_get_data(b))
|
||||
return -1;
|
||||
|
||||
input = bufferevent_get_input(b->ptr);
|
||||
input = bufferevent_get_input(BIO_get_data(b));
|
||||
if (evbuffer_get_length(input) == 0) {
|
||||
/* If there's no data to read, say so. */
|
||||
BIO_set_retry_read(b);
|
||||
|
@ -156,13 +159,13 @@ bio_bufferevent_read(BIO *b, char *out, int outlen)
|
|||
static int
|
||||
bio_bufferevent_write(BIO *b, const char *in, int inlen)
|
||||
{
|
||||
struct bufferevent *bufev = b->ptr;
|
||||
struct bufferevent *bufev = BIO_get_data(b);
|
||||
struct evbuffer *output;
|
||||
size_t outlen;
|
||||
|
||||
BIO_clear_retry_flags(b);
|
||||
|
||||
if (!b->ptr)
|
||||
if (!BIO_get_data(b))
|
||||
return -1;
|
||||
|
||||
output = bufferevent_get_output(bufev);
|
||||
|
@ -188,15 +191,15 @@ bio_bufferevent_write(BIO *b, const char *in, int inlen)
|
|||
static long
|
||||
bio_bufferevent_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
{
|
||||
struct bufferevent *bufev = b->ptr;
|
||||
struct bufferevent *bufev = BIO_get_data(b);
|
||||
long ret = 1;
|
||||
|
||||
switch (cmd) {
|
||||
case BIO_CTRL_GET_CLOSE:
|
||||
ret = b->shutdown;
|
||||
ret = BIO_get_shutdown(b);
|
||||
break;
|
||||
case BIO_CTRL_SET_CLOSE:
|
||||
b->shutdown = (int)num;
|
||||
BIO_set_shutdown(b, (int)num);
|
||||
break;
|
||||
case BIO_CTRL_PENDING:
|
||||
ret = evbuffer_get_length(bufferevent_get_input(bufev)) != 0;
|
||||
|
@ -225,23 +228,24 @@ bio_bufferevent_puts(BIO *b, const char *s)
|
|||
}
|
||||
|
||||
/* Method table for the bufferevent BIO */
|
||||
static BIO_METHOD methods_bufferevent = {
|
||||
BIO_TYPE_LIBEVENT, "bufferevent",
|
||||
bio_bufferevent_write,
|
||||
bio_bufferevent_read,
|
||||
bio_bufferevent_puts,
|
||||
NULL /* bio_bufferevent_gets */,
|
||||
bio_bufferevent_ctrl,
|
||||
bio_bufferevent_new,
|
||||
bio_bufferevent_free,
|
||||
NULL /* callback_ctrl */,
|
||||
};
|
||||
static BIO_METHOD *methods_bufferevent;
|
||||
|
||||
/* Return the method table for the bufferevents BIO */
|
||||
static BIO_METHOD *
|
||||
BIO_s_bufferevent(void)
|
||||
{
|
||||
return &methods_bufferevent;
|
||||
if (methods_bufferevent == NULL) {
|
||||
methods_bufferevent = BIO_meth_new(BIO_TYPE_LIBEVENT, "bufferevent");
|
||||
if (methods_bufferevent == NULL)
|
||||
return NULL;
|
||||
BIO_meth_set_write(methods_bufferevent, bio_bufferevent_write);
|
||||
BIO_meth_set_read(methods_bufferevent, bio_bufferevent_read);
|
||||
BIO_meth_set_puts(methods_bufferevent, bio_bufferevent_puts);
|
||||
BIO_meth_set_ctrl(methods_bufferevent, bio_bufferevent_ctrl);
|
||||
BIO_meth_set_create(methods_bufferevent, bio_bufferevent_new);
|
||||
BIO_meth_set_destroy(methods_bufferevent, bio_bufferevent_free);
|
||||
}
|
||||
return methods_bufferevent;
|
||||
}
|
||||
|
||||
/* Create a new BIO to wrap communication around a bufferevent. If close_flag
|
||||
|
@ -254,9 +258,9 @@ BIO_new_bufferevent(struct bufferevent *bufferevent, int close_flag)
|
|||
return NULL;
|
||||
if (!(result = BIO_new(BIO_s_bufferevent())))
|
||||
return NULL;
|
||||
result->init = 1;
|
||||
result->ptr = bufferevent;
|
||||
result->shutdown = close_flag ? 1 : 0;
|
||||
BIO_set_init(result, 1);
|
||||
BIO_set_data(result, bufferevent);
|
||||
BIO_set_shutdown(result, close_flag ? 1 : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -312,19 +316,20 @@ struct bufferevent_openssl {
|
|||
unsigned read_blocked_on_write : 1;
|
||||
/* When we next get data, we should say "write" instead of "read". */
|
||||
unsigned write_blocked_on_read : 1;
|
||||
/* XXX */
|
||||
/* Treat TCP close before SSL close on SSL >= v3 as clean EOF. */
|
||||
unsigned allow_dirty_shutdown : 1;
|
||||
/* XXXX */
|
||||
unsigned fd_is_set : 1;
|
||||
/* XXX */
|
||||
unsigned n_errors : 2;
|
||||
|
||||
/* Are we currently connecting, accepting, or doing IO? */
|
||||
unsigned state : 2;
|
||||
/* If we reset fd, we sould reset state too */
|
||||
unsigned old_state : 2;
|
||||
};
|
||||
|
||||
static int be_openssl_enable(struct bufferevent *, short);
|
||||
static int be_openssl_disable(struct bufferevent *, short);
|
||||
static void be_openssl_unlink(struct bufferevent *);
|
||||
static void be_openssl_destruct(struct bufferevent *);
|
||||
static int be_openssl_adj_timeouts(struct bufferevent *);
|
||||
static int be_openssl_flush(struct bufferevent *bufev,
|
||||
|
@ -336,6 +341,7 @@ const struct bufferevent_ops bufferevent_ops_openssl = {
|
|||
evutil_offsetof(struct bufferevent_openssl, bev.bev),
|
||||
be_openssl_enable,
|
||||
be_openssl_disable,
|
||||
be_openssl_unlink,
|
||||
be_openssl_destruct,
|
||||
be_openssl_adj_timeouts,
|
||||
be_openssl_flush,
|
||||
|
@ -376,15 +382,15 @@ static int
|
|||
start_reading(struct bufferevent_openssl *bev_ssl)
|
||||
{
|
||||
if (bev_ssl->underlying) {
|
||||
bufferevent_unsuspend_read(bev_ssl->underlying,
|
||||
bufferevent_unsuspend_read_(bev_ssl->underlying,
|
||||
BEV_SUSPEND_FILT_READ);
|
||||
return 0;
|
||||
} else {
|
||||
struct bufferevent *bev = &bev_ssl->bev.bev;
|
||||
int r;
|
||||
r = _bufferevent_add_event(&bev->ev_read, &bev->timeout_read);
|
||||
r = bufferevent_add_event_(&bev->ev_read, &bev->timeout_read);
|
||||
if (r == 0 && bev_ssl->read_blocked_on_write)
|
||||
r = _bufferevent_add_event(&bev->ev_write,
|
||||
r = bufferevent_add_event_(&bev->ev_write,
|
||||
&bev->timeout_write);
|
||||
return r;
|
||||
}
|
||||
|
@ -398,12 +404,15 @@ start_writing(struct bufferevent_openssl *bev_ssl)
|
|||
{
|
||||
int r = 0;
|
||||
if (bev_ssl->underlying) {
|
||||
;
|
||||
if (bev_ssl->write_blocked_on_read) {
|
||||
bufferevent_unsuspend_read_(bev_ssl->underlying,
|
||||
BEV_SUSPEND_FILT_READ);
|
||||
}
|
||||
} else {
|
||||
struct bufferevent *bev = &bev_ssl->bev.bev;
|
||||
r = _bufferevent_add_event(&bev->ev_write, &bev->timeout_write);
|
||||
r = bufferevent_add_event_(&bev->ev_write, &bev->timeout_write);
|
||||
if (!r && bev_ssl->write_blocked_on_read)
|
||||
r = _bufferevent_add_event(&bev->ev_read,
|
||||
r = bufferevent_add_event_(&bev->ev_read,
|
||||
&bev->timeout_read);
|
||||
}
|
||||
return r;
|
||||
|
@ -415,7 +424,7 @@ stop_reading(struct bufferevent_openssl *bev_ssl)
|
|||
if (bev_ssl->write_blocked_on_read)
|
||||
return;
|
||||
if (bev_ssl->underlying) {
|
||||
bufferevent_suspend_read(bev_ssl->underlying,
|
||||
bufferevent_suspend_read_(bev_ssl->underlying,
|
||||
BEV_SUSPEND_FILT_READ);
|
||||
} else {
|
||||
struct bufferevent *bev = &bev_ssl->bev.bev;
|
||||
|
@ -429,7 +438,8 @@ stop_writing(struct bufferevent_openssl *bev_ssl)
|
|||
if (bev_ssl->read_blocked_on_write)
|
||||
return;
|
||||
if (bev_ssl->underlying) {
|
||||
;
|
||||
bufferevent_unsuspend_read_(bev_ssl->underlying,
|
||||
BEV_SUSPEND_FILT_READ);
|
||||
} else {
|
||||
struct bufferevent *bev = &bev_ssl->bev.bev;
|
||||
event_del(&bev->ev_write);
|
||||
|
@ -482,7 +492,7 @@ clear_wbor(struct bufferevent_openssl *bev_ssl)
|
|||
}
|
||||
|
||||
static void
|
||||
conn_closed(struct bufferevent_openssl *bev_ssl, int errcode, int ret)
|
||||
conn_closed(struct bufferevent_openssl *bev_ssl, int when, int errcode, int ret)
|
||||
{
|
||||
int event = BEV_EVENT_ERROR;
|
||||
int dirty_shutdown = 0;
|
||||
|
@ -498,7 +508,7 @@ conn_closed(struct bufferevent_openssl *bev_ssl, int errcode, int ret)
|
|||
break;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
/* IO error; possibly a dirty shutdown. */
|
||||
if (ret == 0 && ERR_peek_error() == 0)
|
||||
if ((ret == 0 || ret == -1) && ERR_peek_error() == 0)
|
||||
dirty_shutdown = 1;
|
||||
break;
|
||||
case SSL_ERROR_SSL:
|
||||
|
@ -528,16 +538,20 @@ conn_closed(struct bufferevent_openssl *bev_ssl, int errcode, int ret)
|
|||
stop_reading(bev_ssl);
|
||||
stop_writing(bev_ssl);
|
||||
|
||||
_bufferevent_run_eventcb(&bev_ssl->bev.bev, event);
|
||||
/* when is BEV_EVENT_{READING|WRITING} */
|
||||
event = when | event;
|
||||
bufferevent_run_eventcb_(&bev_ssl->bev.bev, event, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
init_bio_counts(struct bufferevent_openssl *bev_ssl)
|
||||
{
|
||||
bev_ssl->counts.n_written =
|
||||
BIO_number_written(SSL_get_wbio(bev_ssl->ssl));
|
||||
bev_ssl->counts.n_read =
|
||||
BIO_number_read(SSL_get_rbio(bev_ssl->ssl));
|
||||
BIO *rbio, *wbio;
|
||||
|
||||
wbio = SSL_get_wbio(bev_ssl->ssl);
|
||||
bev_ssl->counts.n_written = wbio ? BIO_number_written(wbio) : 0;
|
||||
rbio = SSL_get_rbio(bev_ssl->ssl);
|
||||
bev_ssl->counts.n_read = rbio ? BIO_number_read(rbio) : 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@ -549,9 +563,9 @@ decrement_buckets(struct bufferevent_openssl *bev_ssl)
|
|||
unsigned long w = num_w - bev_ssl->counts.n_written;
|
||||
unsigned long r = num_r - bev_ssl->counts.n_read;
|
||||
if (w)
|
||||
_bufferevent_decrement_write_buckets(&bev_ssl->bev, w);
|
||||
bufferevent_decrement_write_buckets_(&bev_ssl->bev, w);
|
||||
if (r)
|
||||
_bufferevent_decrement_read_buckets(&bev_ssl->bev, r);
|
||||
bufferevent_decrement_read_buckets_(&bev_ssl->bev, r);
|
||||
bev_ssl->counts.n_written = num_w;
|
||||
bev_ssl->counts.n_read = num_r;
|
||||
}
|
||||
|
@ -574,7 +588,7 @@ do_read(struct bufferevent_openssl *bev_ssl, int n_to_read) {
|
|||
if (bev_ssl->bev.read_suspended)
|
||||
return 0;
|
||||
|
||||
atmost = _bufferevent_get_read_max(&bev_ssl->bev);
|
||||
atmost = bufferevent_get_read_max_(&bev_ssl->bev);
|
||||
if (n_to_read > atmost)
|
||||
n_to_read = atmost;
|
||||
|
||||
|
@ -585,6 +599,7 @@ do_read(struct bufferevent_openssl *bev_ssl, int n_to_read) {
|
|||
for (i=0; i<n; ++i) {
|
||||
if (bev_ssl->bev.read_suspended)
|
||||
break;
|
||||
ERR_clear_error();
|
||||
r = SSL_read(bev_ssl->ssl, space[i].iov_base, space[i].iov_len);
|
||||
if (r>0) {
|
||||
result |= OP_MADE_PROGRESS;
|
||||
|
@ -612,7 +627,7 @@ do_read(struct bufferevent_openssl *bev_ssl, int n_to_read) {
|
|||
return OP_ERR | result;
|
||||
break;
|
||||
default:
|
||||
conn_closed(bev_ssl, err, r);
|
||||
conn_closed(bev_ssl, BEV_EVENT_READING, err, r);
|
||||
break;
|
||||
}
|
||||
result |= OP_BLOCKED;
|
||||
|
@ -643,7 +658,7 @@ do_write(struct bufferevent_openssl *bev_ssl, int atmost)
|
|||
if (bev_ssl->last_write > 0)
|
||||
atmost = bev_ssl->last_write;
|
||||
else
|
||||
atmost = _bufferevent_get_write_max(&bev_ssl->bev);
|
||||
atmost = bufferevent_get_write_max_(&bev_ssl->bev);
|
||||
|
||||
n = evbuffer_peek(output, atmost, NULL, space, 8);
|
||||
if (n < 0)
|
||||
|
@ -661,6 +676,7 @@ do_write(struct bufferevent_openssl *bev_ssl, int atmost)
|
|||
if (space[i].iov_len == 0)
|
||||
continue;
|
||||
|
||||
ERR_clear_error();
|
||||
r = SSL_write(bev_ssl->ssl, space[i].iov_base,
|
||||
space[i].iov_len);
|
||||
if (r > 0) {
|
||||
|
@ -691,7 +707,7 @@ do_write(struct bufferevent_openssl *bev_ssl, int atmost)
|
|||
bev_ssl->last_write = space[i].iov_len;
|
||||
break;
|
||||
default:
|
||||
conn_closed(bev_ssl, err, r);
|
||||
conn_closed(bev_ssl, BEV_EVENT_WRITING, err, r);
|
||||
bev_ssl->last_write = -1;
|
||||
break;
|
||||
}
|
||||
|
@ -704,8 +720,7 @@ do_write(struct bufferevent_openssl *bev_ssl, int atmost)
|
|||
if (bev_ssl->underlying)
|
||||
BEV_RESET_GENERIC_WRITE_TIMEOUT(bev);
|
||||
|
||||
if (evbuffer_get_length(output) <= bev->wm_write.low)
|
||||
_bufferevent_run_writecb(bev);
|
||||
bufferevent_trigger_nolock_(bev, EV_WRITE, BEV_OPT_DEFER_CALLBACKS);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -749,7 +764,7 @@ bytes_to_read(struct bufferevent_openssl *bev)
|
|||
}
|
||||
|
||||
/* Respect the rate limit */
|
||||
limit = _bufferevent_get_read_max(&bev->bev);
|
||||
limit = bufferevent_get_read_max_(&bev->bev);
|
||||
if (result > limit) {
|
||||
result = limit;
|
||||
}
|
||||
|
@ -819,11 +834,8 @@ consider_reading(struct bufferevent_openssl *bev_ssl)
|
|||
|
||||
if (all_result_flags & OP_MADE_PROGRESS) {
|
||||
struct bufferevent *bev = &bev_ssl->bev.bev;
|
||||
struct evbuffer *input = bev->input;
|
||||
|
||||
if (evbuffer_get_length(input) >= bev->wm_read.low) {
|
||||
_bufferevent_run_readcb(bev);
|
||||
}
|
||||
bufferevent_trigger_nolock_(bev, EV_READ, 0);
|
||||
}
|
||||
|
||||
if (!bev_ssl->underlying) {
|
||||
|
@ -847,11 +859,8 @@ consider_writing(struct bufferevent_openssl *bev_ssl)
|
|||
r = do_read(bev_ssl, 1024); /* XXXX 1024 is a hack */
|
||||
if (r & OP_MADE_PROGRESS) {
|
||||
struct bufferevent *bev = &bev_ssl->bev.bev;
|
||||
struct evbuffer *input = bev->input;
|
||||
|
||||
if (evbuffer_get_length(input) >= bev->wm_read.low) {
|
||||
_bufferevent_run_readcb(bev);
|
||||
}
|
||||
bufferevent_trigger_nolock_(bev, EV_READ, 0);
|
||||
}
|
||||
if (r & (OP_ERR|OP_BLOCKED))
|
||||
break;
|
||||
|
@ -923,35 +932,47 @@ be_openssl_eventcb(struct bufferevent *bev_base, short what, void *ctx)
|
|||
eat it. */
|
||||
}
|
||||
if (event)
|
||||
_bufferevent_run_eventcb(&bev_ssl->bev.bev, event);
|
||||
bufferevent_run_eventcb_(&bev_ssl->bev.bev, event, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
be_openssl_readeventcb(evutil_socket_t fd, short what, void *ptr)
|
||||
{
|
||||
struct bufferevent_openssl *bev_ssl = ptr;
|
||||
_bufferevent_incref_and_lock(&bev_ssl->bev.bev);
|
||||
bufferevent_incref_and_lock_(&bev_ssl->bev.bev);
|
||||
if (what == EV_TIMEOUT) {
|
||||
_bufferevent_run_eventcb(&bev_ssl->bev.bev,
|
||||
BEV_EVENT_TIMEOUT|BEV_EVENT_READING);
|
||||
bufferevent_run_eventcb_(&bev_ssl->bev.bev,
|
||||
BEV_EVENT_TIMEOUT|BEV_EVENT_READING, 0);
|
||||
} else {
|
||||
consider_reading(bev_ssl);
|
||||
}
|
||||
_bufferevent_decref_and_unlock(&bev_ssl->bev.bev);
|
||||
bufferevent_decref_and_unlock_(&bev_ssl->bev.bev);
|
||||
}
|
||||
|
||||
static void
|
||||
be_openssl_writeeventcb(evutil_socket_t fd, short what, void *ptr)
|
||||
{
|
||||
struct bufferevent_openssl *bev_ssl = ptr;
|
||||
_bufferevent_incref_and_lock(&bev_ssl->bev.bev);
|
||||
bufferevent_incref_and_lock_(&bev_ssl->bev.bev);
|
||||
if (what == EV_TIMEOUT) {
|
||||
_bufferevent_run_eventcb(&bev_ssl->bev.bev,
|
||||
BEV_EVENT_TIMEOUT|BEV_EVENT_WRITING);
|
||||
bufferevent_run_eventcb_(&bev_ssl->bev.bev,
|
||||
BEV_EVENT_TIMEOUT|BEV_EVENT_WRITING, 0);
|
||||
} else {
|
||||
consider_writing(bev_ssl);
|
||||
}
|
||||
_bufferevent_decref_and_unlock(&bev_ssl->bev.bev);
|
||||
bufferevent_decref_and_unlock_(&bev_ssl->bev.bev);
|
||||
}
|
||||
|
||||
static int
|
||||
be_openssl_auto_fd(struct bufferevent_openssl *bev_ssl, int fd)
|
||||
{
|
||||
if (!bev_ssl->underlying) {
|
||||
struct bufferevent *bev = &bev_ssl->bev.bev;
|
||||
if (event_initialized(&bev->ev_read) && fd < 0) {
|
||||
fd = event_get_fd(&bev->ev_read);
|
||||
}
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -965,25 +986,27 @@ set_open_callbacks(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd)
|
|||
} else {
|
||||
struct bufferevent *bev = &bev_ssl->bev.bev;
|
||||
int rpending=0, wpending=0, r1=0, r2=0;
|
||||
if (fd < 0 && bev_ssl->fd_is_set)
|
||||
fd = event_get_fd(&bev->ev_read);
|
||||
if (bev_ssl->fd_is_set) {
|
||||
|
||||
if (event_initialized(&bev->ev_read)) {
|
||||
rpending = event_pending(&bev->ev_read, EV_READ, NULL);
|
||||
wpending = event_pending(&bev->ev_write, EV_WRITE, NULL);
|
||||
|
||||
event_del(&bev->ev_read);
|
||||
event_del(&bev->ev_write);
|
||||
}
|
||||
|
||||
event_assign(&bev->ev_read, bev->ev_base, fd,
|
||||
EV_READ|EV_PERSIST, be_openssl_readeventcb, bev_ssl);
|
||||
EV_READ|EV_PERSIST|EV_FINALIZE,
|
||||
be_openssl_readeventcb, bev_ssl);
|
||||
event_assign(&bev->ev_write, bev->ev_base, fd,
|
||||
EV_WRITE|EV_PERSIST, be_openssl_writeeventcb, bev_ssl);
|
||||
EV_WRITE|EV_PERSIST|EV_FINALIZE,
|
||||
be_openssl_writeeventcb, bev_ssl);
|
||||
|
||||
if (rpending)
|
||||
r1 = _bufferevent_add_event(&bev->ev_read, &bev->timeout_read);
|
||||
r1 = bufferevent_add_event_(&bev->ev_read, &bev->timeout_read);
|
||||
if (wpending)
|
||||
r2 = _bufferevent_add_event(&bev->ev_write, &bev->timeout_write);
|
||||
if (fd >= 0) {
|
||||
bev_ssl->fd_is_set = 1;
|
||||
}
|
||||
r2 = bufferevent_add_event_(&bev->ev_write, &bev->timeout_write);
|
||||
|
||||
return (r1<0 || r2<0) ? -1 : 0;
|
||||
}
|
||||
}
|
||||
|
@ -1000,38 +1023,34 @@ do_handshake(struct bufferevent_openssl *bev_ssl)
|
|||
return -1;
|
||||
case BUFFEREVENT_SSL_CONNECTING:
|
||||
case BUFFEREVENT_SSL_ACCEPTING:
|
||||
ERR_clear_error();
|
||||
r = SSL_do_handshake(bev_ssl->ssl);
|
||||
break;
|
||||
}
|
||||
decrement_buckets(bev_ssl);
|
||||
|
||||
if (r==1) {
|
||||
int fd = event_get_fd(&bev_ssl->bev.bev.ev_read);
|
||||
/* We're done! */
|
||||
bev_ssl->state = BUFFEREVENT_SSL_OPEN;
|
||||
set_open_callbacks(bev_ssl, -1); /* XXXX handle failure */
|
||||
set_open_callbacks(bev_ssl, fd); /* XXXX handle failure */
|
||||
/* Call do_read and do_write as needed */
|
||||
bufferevent_enable(&bev_ssl->bev.bev, bev_ssl->bev.bev.enabled);
|
||||
_bufferevent_run_eventcb(&bev_ssl->bev.bev,
|
||||
BEV_EVENT_CONNECTED);
|
||||
bufferevent_run_eventcb_(&bev_ssl->bev.bev,
|
||||
BEV_EVENT_CONNECTED, 0);
|
||||
return 1;
|
||||
} else {
|
||||
int err = SSL_get_error(bev_ssl->ssl, r);
|
||||
print_err(err);
|
||||
switch (err) {
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
if (!bev_ssl->underlying) {
|
||||
stop_reading(bev_ssl);
|
||||
return start_writing(bev_ssl);
|
||||
}
|
||||
return 0;
|
||||
stop_reading(bev_ssl);
|
||||
return start_writing(bev_ssl);
|
||||
case SSL_ERROR_WANT_READ:
|
||||
if (!bev_ssl->underlying) {
|
||||
stop_writing(bev_ssl);
|
||||
return start_reading(bev_ssl);
|
||||
}
|
||||
return 0;
|
||||
stop_writing(bev_ssl);
|
||||
return start_reading(bev_ssl);
|
||||
default:
|
||||
conn_closed(bev_ssl, err, r);
|
||||
conn_closed(bev_ssl, BEV_EVENT_READING, err, r);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -1049,12 +1068,12 @@ be_openssl_handshakeeventcb(evutil_socket_t fd, short what, void *ptr)
|
|||
{
|
||||
struct bufferevent_openssl *bev_ssl = ptr;
|
||||
|
||||
_bufferevent_incref_and_lock(&bev_ssl->bev.bev);
|
||||
bufferevent_incref_and_lock_(&bev_ssl->bev.bev);
|
||||
if (what & EV_TIMEOUT) {
|
||||
_bufferevent_run_eventcb(&bev_ssl->bev.bev, BEV_EVENT_TIMEOUT);
|
||||
bufferevent_run_eventcb_(&bev_ssl->bev.bev, BEV_EVENT_TIMEOUT, 0);
|
||||
} else
|
||||
do_handshake(bev_ssl);/* XXX handle failure */
|
||||
_bufferevent_decref_and_unlock(&bev_ssl->bev.bev);
|
||||
bufferevent_decref_and_unlock_(&bev_ssl->bev.bev);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1065,26 +1084,31 @@ set_handshake_callbacks(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd)
|
|||
be_openssl_handshakecb, be_openssl_handshakecb,
|
||||
be_openssl_eventcb,
|
||||
bev_ssl);
|
||||
|
||||
if (fd < 0)
|
||||
return 0;
|
||||
|
||||
if (bufferevent_setfd(bev_ssl->underlying, fd))
|
||||
return 1;
|
||||
|
||||
return do_handshake(bev_ssl);
|
||||
} else {
|
||||
struct bufferevent *bev = &bev_ssl->bev.bev;
|
||||
int r1=0, r2=0;
|
||||
if (fd < 0 && bev_ssl->fd_is_set)
|
||||
fd = event_get_fd(&bev->ev_read);
|
||||
if (bev_ssl->fd_is_set) {
|
||||
|
||||
if (event_initialized(&bev->ev_read)) {
|
||||
event_del(&bev->ev_read);
|
||||
event_del(&bev->ev_write);
|
||||
}
|
||||
|
||||
event_assign(&bev->ev_read, bev->ev_base, fd,
|
||||
EV_READ|EV_PERSIST, be_openssl_handshakeeventcb, bev_ssl);
|
||||
EV_READ|EV_PERSIST|EV_FINALIZE,
|
||||
be_openssl_handshakeeventcb, bev_ssl);
|
||||
event_assign(&bev->ev_write, bev->ev_base, fd,
|
||||
EV_WRITE|EV_PERSIST, be_openssl_handshakeeventcb, bev_ssl);
|
||||
if (fd >= 0) {
|
||||
r1 = _bufferevent_add_event(&bev->ev_read, &bev->timeout_read);
|
||||
r2 = _bufferevent_add_event(&bev->ev_write, &bev->timeout_write);
|
||||
bev_ssl->fd_is_set = 1;
|
||||
}
|
||||
return (r1<0 || r2<0) ? -1 : 0;
|
||||
EV_WRITE|EV_PERSIST|EV_FINALIZE,
|
||||
be_openssl_handshakeeventcb, bev_ssl);
|
||||
if (fd >= 0)
|
||||
bufferevent_enable(bev, bev->enabled);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1097,7 +1121,7 @@ bufferevent_ssl_renegotiate(struct bufferevent *bev)
|
|||
if (SSL_renegotiate(bev_ssl->ssl) < 0)
|
||||
return -1;
|
||||
bev_ssl->state = BUFFEREVENT_SSL_CONNECTING;
|
||||
if (set_handshake_callbacks(bev_ssl, -1) < 0)
|
||||
if (set_handshake_callbacks(bev_ssl, be_openssl_auto_fd(bev_ssl, -1)) < 0)
|
||||
return -1;
|
||||
if (!bev_ssl->underlying)
|
||||
return do_handshake(bev_ssl);
|
||||
|
@ -1114,12 +1138,14 @@ be_openssl_outbuf_cb(struct evbuffer *buf,
|
|||
|
||||
if (cbinfo->n_added && bev_ssl->state == BUFFEREVENT_SSL_OPEN) {
|
||||
if (cbinfo->orig_size == 0)
|
||||
r = _bufferevent_add_event(&bev_ssl->bev.bev.ev_write,
|
||||
r = bufferevent_add_event_(&bev_ssl->bev.bev.ev_write,
|
||||
&bev_ssl->bev.bev.timeout_write);
|
||||
consider_writing(bev_ssl);
|
||||
|
||||
if (bev_ssl->underlying)
|
||||
consider_writing(bev_ssl);
|
||||
}
|
||||
/* XXX Handle r < 0 */
|
||||
(void)r;
|
||||
(void)r;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1129,9 +1155,6 @@ be_openssl_enable(struct bufferevent *bev, short events)
|
|||
struct bufferevent_openssl *bev_ssl = upcast(bev);
|
||||
int r1 = 0, r2 = 0;
|
||||
|
||||
if (bev_ssl->state != BUFFEREVENT_SSL_OPEN)
|
||||
return 0;
|
||||
|
||||
if (events & EV_READ)
|
||||
r1 = start_reading(bev_ssl);
|
||||
if (events & EV_WRITE)
|
||||
|
@ -1155,8 +1178,6 @@ static int
|
|||
be_openssl_disable(struct bufferevent *bev, short events)
|
||||
{
|
||||
struct bufferevent_openssl *bev_ssl = upcast(bev);
|
||||
if (bev_ssl->state != BUFFEREVENT_SSL_OPEN)
|
||||
return 0;
|
||||
|
||||
if (events & EV_READ)
|
||||
stop_reading(bev_ssl);
|
||||
|
@ -1173,17 +1194,10 @@ be_openssl_disable(struct bufferevent *bev, short events)
|
|||
}
|
||||
|
||||
static void
|
||||
be_openssl_destruct(struct bufferevent *bev)
|
||||
be_openssl_unlink(struct bufferevent *bev)
|
||||
{
|
||||
struct bufferevent_openssl *bev_ssl = upcast(bev);
|
||||
|
||||
if (bev_ssl->underlying) {
|
||||
_bufferevent_del_generic_timeout_cbs(bev);
|
||||
} else {
|
||||
event_del(&bev->ev_read);
|
||||
event_del(&bev->ev_write);
|
||||
}
|
||||
|
||||
if (bev_ssl->bev.options & BEV_OPT_CLOSE_ON_FREE) {
|
||||
if (bev_ssl->underlying) {
|
||||
if (BEV_UPCAST(bev_ssl->underlying)->refcnt < 2) {
|
||||
|
@ -1191,9 +1205,29 @@ be_openssl_destruct(struct bufferevent *bev)
|
|||
"bufferevent with too few references");
|
||||
} else {
|
||||
bufferevent_free(bev_ssl->underlying);
|
||||
bev_ssl->underlying = NULL;
|
||||
/* We still have a reference to it, via our
|
||||
* BIO. So we don't drop this. */
|
||||
// bev_ssl->underlying = NULL;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
if (bev_ssl->underlying) {
|
||||
if (bev_ssl->underlying->errorcb == be_openssl_eventcb)
|
||||
bufferevent_setcb(bev_ssl->underlying,
|
||||
NULL,NULL,NULL,NULL);
|
||||
bufferevent_unsuspend_read_(bev_ssl->underlying,
|
||||
BEV_SUSPEND_FILT_READ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
be_openssl_destruct(struct bufferevent *bev)
|
||||
{
|
||||
struct bufferevent_openssl *bev_ssl = upcast(bev);
|
||||
|
||||
if (bev_ssl->bev.options & BEV_OPT_CLOSE_ON_FREE) {
|
||||
if (! bev_ssl->underlying) {
|
||||
evutil_socket_t fd = -1;
|
||||
BIO *bio = SSL_get_wbio(bev_ssl->ssl);
|
||||
if (bio)
|
||||
|
@ -1202,14 +1236,6 @@ be_openssl_destruct(struct bufferevent *bev)
|
|||
evutil_closesocket(fd);
|
||||
}
|
||||
SSL_free(bev_ssl->ssl);
|
||||
} else {
|
||||
if (bev_ssl->underlying) {
|
||||
if (bev_ssl->underlying->errorcb == be_openssl_eventcb)
|
||||
bufferevent_setcb(bev_ssl->underlying,
|
||||
NULL,NULL,NULL,NULL);
|
||||
bufferevent_unsuspend_read(bev_ssl->underlying,
|
||||
BEV_SUSPEND_FILT_READ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1218,15 +1244,10 @@ be_openssl_adj_timeouts(struct bufferevent *bev)
|
|||
{
|
||||
struct bufferevent_openssl *bev_ssl = upcast(bev);
|
||||
|
||||
if (bev_ssl->underlying)
|
||||
return _bufferevent_generic_adj_timeouts(bev);
|
||||
else {
|
||||
int r1=0, r2=0;
|
||||
if (event_pending(&bev->ev_read, EV_READ, NULL))
|
||||
r1 = _bufferevent_add_event(&bev->ev_read, &bev->timeout_read);
|
||||
if (event_pending(&bev->ev_write, EV_WRITE, NULL))
|
||||
r2 = _bufferevent_add_event(&bev->ev_write, &bev->timeout_write);
|
||||
return (r1<0 || r2<0) ? -1 : 0;
|
||||
if (bev_ssl->underlying) {
|
||||
return bufferevent_generic_adj_timeouts_(bev);
|
||||
} else {
|
||||
return bufferevent_generic_adj_existing_timeouts_(bev);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1238,6 +1259,34 @@ be_openssl_flush(struct bufferevent *bufev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
be_openssl_set_fd(struct bufferevent_openssl *bev_ssl,
|
||||
enum bufferevent_ssl_state state, int fd)
|
||||
{
|
||||
bev_ssl->state = state;
|
||||
|
||||
switch (state) {
|
||||
case BUFFEREVENT_SSL_ACCEPTING:
|
||||
SSL_set_accept_state(bev_ssl->ssl);
|
||||
if (set_handshake_callbacks(bev_ssl, fd) < 0)
|
||||
return -1;
|
||||
break;
|
||||
case BUFFEREVENT_SSL_CONNECTING:
|
||||
SSL_set_connect_state(bev_ssl->ssl);
|
||||
if (set_handshake_callbacks(bev_ssl, fd) < 0)
|
||||
return -1;
|
||||
break;
|
||||
case BUFFEREVENT_SSL_OPEN:
|
||||
if (set_open_callbacks(bev_ssl, fd) < 0)
|
||||
return -1;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
be_openssl_ctrl(struct bufferevent *bev,
|
||||
enum bufferevent_ctrl_op op, union bufferevent_ctrl_data *data)
|
||||
|
@ -1245,29 +1294,26 @@ be_openssl_ctrl(struct bufferevent *bev,
|
|||
struct bufferevent_openssl *bev_ssl = upcast(bev);
|
||||
switch (op) {
|
||||
case BEV_CTRL_SET_FD:
|
||||
if (bev_ssl->underlying)
|
||||
return -1;
|
||||
{
|
||||
if (!bev_ssl->underlying) {
|
||||
BIO *bio;
|
||||
bio = BIO_new_socket(data->fd, 0);
|
||||
SSL_set_bio(bev_ssl->ssl, bio, bio);
|
||||
bev_ssl->fd_is_set = 1;
|
||||
}
|
||||
if (bev_ssl->state == BUFFEREVENT_SSL_OPEN)
|
||||
return set_open_callbacks(bev_ssl, data->fd);
|
||||
else {
|
||||
return set_handshake_callbacks(bev_ssl, data->fd);
|
||||
} else {
|
||||
BIO *bio;
|
||||
if (!(bio = BIO_new_bufferevent(bev_ssl->underlying, 0)))
|
||||
return -1;
|
||||
SSL_set_bio(bev_ssl->ssl, bio, bio);
|
||||
}
|
||||
|
||||
return be_openssl_set_fd(bev_ssl, bev_ssl->old_state, data->fd);
|
||||
case BEV_CTRL_GET_FD:
|
||||
if (bev_ssl->underlying)
|
||||
return -1;
|
||||
if (!bev_ssl->fd_is_set)
|
||||
return -1;
|
||||
data->fd = event_get_fd(&bev->ev_read);
|
||||
if (bev_ssl->underlying) {
|
||||
data->fd = event_get_fd(&bev_ssl->underlying->ev_read);
|
||||
} else {
|
||||
data->fd = event_get_fd(&bev->ev_read);
|
||||
}
|
||||
return 0;
|
||||
case BEV_CTRL_GET_UNDERLYING:
|
||||
if (!bev_ssl->underlying)
|
||||
return -1;
|
||||
data->ptr = bev_ssl->underlying;
|
||||
return 0;
|
||||
case BEV_CTRL_CANCEL_ALL:
|
||||
|
@ -1305,7 +1351,7 @@ bufferevent_openssl_new_impl(struct event_base *base,
|
|||
|
||||
bev_p = &bev_ssl->bev;
|
||||
|
||||
if (bufferevent_init_common(bev_p, base,
|
||||
if (bufferevent_init_common_(bev_p, base,
|
||||
&bufferevent_ops_openssl, tmp_options) < 0)
|
||||
goto err;
|
||||
|
||||
|
@ -1320,52 +1366,28 @@ bufferevent_openssl_new_impl(struct event_base *base,
|
|||
be_openssl_outbuf_cb, bev_ssl);
|
||||
|
||||
if (options & BEV_OPT_THREADSAFE)
|
||||
bufferevent_enable_locking(&bev_ssl->bev.bev, NULL);
|
||||
bufferevent_enable_locking_(&bev_ssl->bev.bev, NULL);
|
||||
|
||||
if (underlying) {
|
||||
_bufferevent_init_generic_timeout_cbs(&bev_ssl->bev.bev);
|
||||
bufferevent_incref(underlying);
|
||||
bufferevent_init_generic_timeout_cbs_(&bev_ssl->bev.bev);
|
||||
bufferevent_incref_(underlying);
|
||||
}
|
||||
|
||||
bev_ssl->state = state;
|
||||
bev_ssl->old_state = state;
|
||||
bev_ssl->last_write = -1;
|
||||
|
||||
init_bio_counts(bev_ssl);
|
||||
|
||||
switch (state) {
|
||||
case BUFFEREVENT_SSL_ACCEPTING:
|
||||
SSL_set_accept_state(bev_ssl->ssl);
|
||||
if (set_handshake_callbacks(bev_ssl, fd) < 0)
|
||||
goto err;
|
||||
break;
|
||||
case BUFFEREVENT_SSL_CONNECTING:
|
||||
SSL_set_connect_state(bev_ssl->ssl);
|
||||
if (set_handshake_callbacks(bev_ssl, fd) < 0)
|
||||
goto err;
|
||||
break;
|
||||
case BUFFEREVENT_SSL_OPEN:
|
||||
if (set_open_callbacks(bev_ssl, fd) < 0)
|
||||
goto err;
|
||||
break;
|
||||
default:
|
||||
fd = be_openssl_auto_fd(bev_ssl, fd);
|
||||
if (be_openssl_set_fd(bev_ssl, state, fd))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (underlying) {
|
||||
bufferevent_setwatermark(underlying, EV_READ, 0, 0);
|
||||
bufferevent_enable(underlying, EV_READ|EV_WRITE);
|
||||
if (state == BUFFEREVENT_SSL_OPEN)
|
||||
bufferevent_suspend_read(underlying,
|
||||
bufferevent_suspend_read_(underlying,
|
||||
BEV_SUSPEND_FILT_READ);
|
||||
} else {
|
||||
bev_ssl->bev.bev.enabled = EV_READ|EV_WRITE;
|
||||
if (bev_ssl->fd_is_set) {
|
||||
if (state != BUFFEREVENT_SSL_OPEN)
|
||||
if (event_add(&bev_ssl->bev.bev.ev_read, NULL) < 0)
|
||||
goto err;
|
||||
if (event_add(&bev_ssl->bev.bev.ev_write, NULL) < 0)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
return &bev_ssl->bev.bev;
|
||||
|
@ -1439,6 +1461,31 @@ bufferevent_openssl_socket_new(struct event_base *base,
|
|||
base, NULL, fd, ssl, state, options);
|
||||
}
|
||||
|
||||
int
|
||||
bufferevent_openssl_get_allow_dirty_shutdown(struct bufferevent *bev)
|
||||
{
|
||||
int allow_dirty_shutdown = -1;
|
||||
struct bufferevent_openssl *bev_ssl;
|
||||
BEV_LOCK(bev);
|
||||
bev_ssl = upcast(bev);
|
||||
if (bev_ssl)
|
||||
allow_dirty_shutdown = bev_ssl->allow_dirty_shutdown;
|
||||
BEV_UNLOCK(bev);
|
||||
return allow_dirty_shutdown;
|
||||
}
|
||||
|
||||
void
|
||||
bufferevent_openssl_set_allow_dirty_shutdown(struct bufferevent *bev,
|
||||
int allow_dirty_shutdown)
|
||||
{
|
||||
struct bufferevent_openssl *bev_ssl;
|
||||
BEV_LOCK(bev);
|
||||
bev_ssl = upcast(bev);
|
||||
if (bev_ssl)
|
||||
bev_ssl->allow_dirty_shutdown = !!allow_dirty_shutdown;
|
||||
BEV_UNLOCK(bev);
|
||||
}
|
||||
|
||||
unsigned long
|
||||
bufferevent_get_openssl_error(struct bufferevent *bev)
|
||||
{
|
||||
|
|
|
@ -23,15 +23,15 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "event2/event-config.h"
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#include "event2/event-config.h"
|
||||
|
||||
#include "event2/util.h"
|
||||
#include "event2/buffer.h"
|
||||
#include "event2/bufferevent.h"
|
||||
|
@ -45,6 +45,8 @@
|
|||
struct bufferevent_pair {
|
||||
struct bufferevent_private bev;
|
||||
struct bufferevent_pair *partner;
|
||||
/* For ->destruct() lock checking */
|
||||
struct bufferevent_pair *unlinked_partner;
|
||||
};
|
||||
|
||||
|
||||
|
@ -67,10 +69,10 @@ static inline void
|
|||
incref_and_lock(struct bufferevent *b)
|
||||
{
|
||||
struct bufferevent_pair *bevp;
|
||||
_bufferevent_incref_and_lock(b);
|
||||
bufferevent_incref_and_lock_(b);
|
||||
bevp = upcast(b);
|
||||
if (bevp->partner)
|
||||
_bufferevent_incref_and_lock(downcast(bevp->partner));
|
||||
bufferevent_incref_and_lock_(downcast(bevp->partner));
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@ -78,8 +80,8 @@ decref_and_unlock(struct bufferevent *b)
|
|||
{
|
||||
struct bufferevent_pair *bevp = upcast(b);
|
||||
if (bevp->partner)
|
||||
_bufferevent_decref_and_unlock(downcast(bevp->partner));
|
||||
_bufferevent_decref_and_unlock(b);
|
||||
bufferevent_decref_and_unlock_(downcast(bevp->partner));
|
||||
bufferevent_decref_and_unlock_(b);
|
||||
}
|
||||
|
||||
/* XXX Handle close */
|
||||
|
@ -94,7 +96,7 @@ bufferevent_pair_elt_new(struct event_base *base,
|
|||
struct bufferevent_pair *bufev;
|
||||
if (! (bufev = mm_calloc(1, sizeof(struct bufferevent_pair))))
|
||||
return NULL;
|
||||
if (bufferevent_init_common(&bufev->bev, base, &bufferevent_ops_pair,
|
||||
if (bufferevent_init_common_(&bufev->bev, base, &bufferevent_ops_pair,
|
||||
options)) {
|
||||
mm_free(bufev);
|
||||
return NULL;
|
||||
|
@ -104,7 +106,7 @@ bufferevent_pair_elt_new(struct event_base *base,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
_bufferevent_init_generic_timeout_cbs(&bufev->bev.bev);
|
||||
bufferevent_init_generic_timeout_cbs_(&bufev->bev.bev);
|
||||
|
||||
return bufev;
|
||||
}
|
||||
|
@ -130,7 +132,7 @@ bufferevent_pair_new(struct event_base *base, int options,
|
|||
|
||||
if (options & BEV_OPT_THREADSAFE) {
|
||||
/*XXXX check return */
|
||||
bufferevent_enable_locking(downcast(bufev2), bufev1->bev.lock);
|
||||
bufferevent_enable_locking_(downcast(bufev2), bufev1->bev.lock);
|
||||
}
|
||||
|
||||
bufev1->partner = bufev2;
|
||||
|
@ -151,7 +153,7 @@ static void
|
|||
be_pair_transfer(struct bufferevent *src, struct bufferevent *dst,
|
||||
int ignore_wm)
|
||||
{
|
||||
size_t src_size, dst_size;
|
||||
size_t dst_size;
|
||||
size_t n;
|
||||
|
||||
evbuffer_unfreeze(src->output, 1);
|
||||
|
@ -182,15 +184,8 @@ be_pair_transfer(struct bufferevent *src, struct bufferevent *dst,
|
|||
BEV_DEL_GENERIC_WRITE_TIMEOUT(dst);
|
||||
}
|
||||
|
||||
src_size = evbuffer_get_length(src->output);
|
||||
dst_size = evbuffer_get_length(dst->input);
|
||||
|
||||
if (dst_size >= dst->wm_read.low) {
|
||||
_bufferevent_run_readcb(dst);
|
||||
}
|
||||
if (src_size <= src->wm_write.low) {
|
||||
_bufferevent_run_writecb(src);
|
||||
}
|
||||
bufferevent_trigger_nolock_(dst, EV_READ, 0);
|
||||
bufferevent_trigger_nolock_(src, EV_WRITE, 0);
|
||||
done:
|
||||
evbuffer_freeze(src->output, 1);
|
||||
evbuffer_freeze(dst->input, 0);
|
||||
|
@ -260,22 +255,50 @@ be_pair_disable(struct bufferevent *bev, short events)
|
|||
if (events & EV_READ) {
|
||||
BEV_DEL_GENERIC_READ_TIMEOUT(bev);
|
||||
}
|
||||
if (events & EV_WRITE)
|
||||
if (events & EV_WRITE) {
|
||||
BEV_DEL_GENERIC_WRITE_TIMEOUT(bev);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
be_pair_unlink(struct bufferevent *bev)
|
||||
{
|
||||
struct bufferevent_pair *bev_p = upcast(bev);
|
||||
|
||||
if (bev_p->partner) {
|
||||
bev_p->unlinked_partner = bev_p->partner;
|
||||
bev_p->partner->partner = NULL;
|
||||
bev_p->partner = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Free *shared* lock in the latest be (since we share it between two of them). */
|
||||
static void
|
||||
be_pair_destruct(struct bufferevent *bev)
|
||||
{
|
||||
struct bufferevent_pair *bev_p = upcast(bev);
|
||||
|
||||
if (bev_p->partner) {
|
||||
bev_p->partner->partner = NULL;
|
||||
bev_p->partner = NULL;
|
||||
/* Transfer ownership of the lock into partner, otherwise we will use
|
||||
* already free'd lock during freeing second bev, see next example:
|
||||
*
|
||||
* bev1->own_lock = 1
|
||||
* bev2->own_lock = 0
|
||||
* bev2->lock = bev1->lock
|
||||
*
|
||||
* bufferevent_free(bev1) # refcnt == 0 -> unlink
|
||||
* bufferevent_free(bev2) # refcnt == 0 -> unlink
|
||||
*
|
||||
* event_base_free() -> finilizers -> EVTHREAD_FREE_LOCK(bev1->lock)
|
||||
* -> BEV_LOCK(bev2->lock) <-- already freed
|
||||
*
|
||||
* Where bev1 == pair[0], bev2 == pair[1].
|
||||
*/
|
||||
if (bev_p->unlinked_partner && bev_p->bev.own_lock) {
|
||||
bev_p->unlinked_partner->bev.own_lock = 1;
|
||||
bev_p->bev.own_lock = 0;
|
||||
}
|
||||
|
||||
_bufferevent_del_generic_timeout_cbs(bev);
|
||||
bev_p->unlinked_partner = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -284,15 +307,17 @@ be_pair_flush(struct bufferevent *bev, short iotype,
|
|||
{
|
||||
struct bufferevent_pair *bev_p = upcast(bev);
|
||||
struct bufferevent *partner;
|
||||
incref_and_lock(bev);
|
||||
|
||||
if (!bev_p->partner)
|
||||
return -1;
|
||||
|
||||
partner = downcast(bev_p->partner);
|
||||
|
||||
if (mode == BEV_NORMAL)
|
||||
return 0;
|
||||
|
||||
incref_and_lock(bev);
|
||||
|
||||
partner = downcast(bev_p->partner);
|
||||
|
||||
if ((iotype & EV_READ) != 0)
|
||||
be_pair_transfer(partner, bev, 1);
|
||||
|
||||
|
@ -300,7 +325,12 @@ be_pair_flush(struct bufferevent *bev, short iotype,
|
|||
be_pair_transfer(bev, partner, 1);
|
||||
|
||||
if (mode == BEV_FINISHED) {
|
||||
_bufferevent_run_eventcb(partner, iotype|BEV_EVENT_EOF);
|
||||
short what = BEV_EVENT_EOF;
|
||||
if (iotype & EV_READ)
|
||||
what |= BEV_EVENT_WRITING;
|
||||
if (iotype & EV_WRITE)
|
||||
what |= BEV_EVENT_READING;
|
||||
bufferevent_run_eventcb_(partner, what, 0);
|
||||
}
|
||||
decref_and_unlock(bev);
|
||||
return 0;
|
||||
|
@ -327,8 +357,9 @@ const struct bufferevent_ops bufferevent_ops_pair = {
|
|||
evutil_offsetof(struct bufferevent_pair, bev.bev),
|
||||
be_pair_enable,
|
||||
be_pair_disable,
|
||||
be_pair_unlink,
|
||||
be_pair_destruct,
|
||||
_bufferevent_generic_adj_timeouts,
|
||||
bufferevent_generic_adj_timeouts_,
|
||||
be_pair_flush,
|
||||
NULL, /* ctrl */
|
||||
};
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <limits.h>
|
||||
|
@ -46,7 +47,7 @@
|
|||
#include "event-internal.h"
|
||||
|
||||
int
|
||||
ev_token_bucket_init(struct ev_token_bucket *bucket,
|
||||
ev_token_bucket_init_(struct ev_token_bucket *bucket,
|
||||
const struct ev_token_bucket_cfg *cfg,
|
||||
ev_uint32_t current_tick,
|
||||
int reinitialize)
|
||||
|
@ -70,7 +71,7 @@ ev_token_bucket_init(struct ev_token_bucket *bucket,
|
|||
}
|
||||
|
||||
int
|
||||
ev_token_bucket_update(struct ev_token_bucket *bucket,
|
||||
ev_token_bucket_update_(struct ev_token_bucket *bucket,
|
||||
const struct ev_token_bucket_cfg *cfg,
|
||||
ev_uint32_t current_tick)
|
||||
{
|
||||
|
@ -116,14 +117,14 @@ bufferevent_update_buckets(struct bufferevent_private *bev)
|
|||
struct timeval now;
|
||||
unsigned tick;
|
||||
event_base_gettimeofday_cached(bev->bev.ev_base, &now);
|
||||
tick = ev_token_bucket_get_tick(&now, bev->rate_limiting->cfg);
|
||||
tick = ev_token_bucket_get_tick_(&now, bev->rate_limiting->cfg);
|
||||
if (tick != bev->rate_limiting->limit.last_updated)
|
||||
ev_token_bucket_update(&bev->rate_limiting->limit,
|
||||
ev_token_bucket_update_(&bev->rate_limiting->limit,
|
||||
bev->rate_limiting->cfg, tick);
|
||||
}
|
||||
|
||||
ev_uint32_t
|
||||
ev_token_bucket_get_tick(const struct timeval *tv,
|
||||
ev_token_bucket_get_tick_(const struct timeval *tv,
|
||||
const struct ev_token_bucket_cfg *cfg)
|
||||
{
|
||||
/* This computation uses two multiplies and a divide. We could do
|
||||
|
@ -177,30 +178,27 @@ ev_token_bucket_cfg_free(struct ev_token_bucket_cfg *cfg)
|
|||
mm_free(cfg);
|
||||
}
|
||||
|
||||
/* No matter how big our bucket gets, don't try to read more than this
|
||||
* much in a single read operation. */
|
||||
#define MAX_TO_READ_EVER 16384
|
||||
/* No matter how big our bucket gets, don't try to write more than this
|
||||
* much in a single write operation. */
|
||||
#define MAX_TO_WRITE_EVER 16384
|
||||
/* Default values for max_single_read & max_single_write variables. */
|
||||
#define MAX_SINGLE_READ_DEFAULT 16384
|
||||
#define MAX_SINGLE_WRITE_DEFAULT 16384
|
||||
|
||||
#define LOCK_GROUP(g) EVLOCK_LOCK((g)->lock, 0)
|
||||
#define UNLOCK_GROUP(g) EVLOCK_UNLOCK((g)->lock, 0)
|
||||
|
||||
static int _bev_group_suspend_reading(struct bufferevent_rate_limit_group *g);
|
||||
static int _bev_group_suspend_writing(struct bufferevent_rate_limit_group *g);
|
||||
static void _bev_group_unsuspend_reading(struct bufferevent_rate_limit_group *g);
|
||||
static void _bev_group_unsuspend_writing(struct bufferevent_rate_limit_group *g);
|
||||
static int bev_group_suspend_reading_(struct bufferevent_rate_limit_group *g);
|
||||
static int bev_group_suspend_writing_(struct bufferevent_rate_limit_group *g);
|
||||
static void bev_group_unsuspend_reading_(struct bufferevent_rate_limit_group *g);
|
||||
static void bev_group_unsuspend_writing_(struct bufferevent_rate_limit_group *g);
|
||||
|
||||
/** Helper: figure out the maximum amount we should write if is_write, or
|
||||
the maximum amount we should read if is_read. Return that maximum, or
|
||||
0 if our bucket is wholly exhausted.
|
||||
*/
|
||||
static inline ev_ssize_t
|
||||
_bufferevent_get_rlim_max(struct bufferevent_private *bev, int is_write)
|
||||
bufferevent_get_rlim_max_(struct bufferevent_private *bev, int is_write)
|
||||
{
|
||||
/* needs lock on bev. */
|
||||
ev_ssize_t max_so_far = is_write?MAX_TO_WRITE_EVER:MAX_TO_READ_EVER;
|
||||
ev_ssize_t max_so_far = is_write?bev->max_single_write:bev->max_single_read;
|
||||
|
||||
#define LIM(x) \
|
||||
(is_write ? (x).write_limit : (x).read_limit)
|
||||
|
@ -237,10 +235,10 @@ _bufferevent_get_rlim_max(struct bufferevent_private *bev, int is_write)
|
|||
* particular bufferevent while suspending the whole
|
||||
* group. */
|
||||
if (is_write)
|
||||
bufferevent_suspend_write(&bev->bev,
|
||||
bufferevent_suspend_write_(&bev->bev,
|
||||
BEV_SUSPEND_BW_GROUP);
|
||||
else
|
||||
bufferevent_suspend_read(&bev->bev,
|
||||
bufferevent_suspend_read_(&bev->bev,
|
||||
BEV_SUSPEND_BW_GROUP);
|
||||
share = 0;
|
||||
} else {
|
||||
|
@ -260,19 +258,19 @@ _bufferevent_get_rlim_max(struct bufferevent_private *bev, int is_write)
|
|||
}
|
||||
|
||||
ev_ssize_t
|
||||
_bufferevent_get_read_max(struct bufferevent_private *bev)
|
||||
bufferevent_get_read_max_(struct bufferevent_private *bev)
|
||||
{
|
||||
return _bufferevent_get_rlim_max(bev, 0);
|
||||
return bufferevent_get_rlim_max_(bev, 0);
|
||||
}
|
||||
|
||||
ev_ssize_t
|
||||
_bufferevent_get_write_max(struct bufferevent_private *bev)
|
||||
bufferevent_get_write_max_(struct bufferevent_private *bev)
|
||||
{
|
||||
return _bufferevent_get_rlim_max(bev, 1);
|
||||
return bufferevent_get_rlim_max_(bev, 1);
|
||||
}
|
||||
|
||||
int
|
||||
_bufferevent_decrement_read_buckets(struct bufferevent_private *bev, ev_ssize_t bytes)
|
||||
bufferevent_decrement_read_buckets_(struct bufferevent_private *bev, ev_ssize_t bytes)
|
||||
{
|
||||
/* XXXXX Make sure all users of this function check its return value */
|
||||
int r = 0;
|
||||
|
@ -283,14 +281,14 @@ _bufferevent_decrement_read_buckets(struct bufferevent_private *bev, ev_ssize_t
|
|||
if (bev->rate_limiting->cfg) {
|
||||
bev->rate_limiting->limit.read_limit -= bytes;
|
||||
if (bev->rate_limiting->limit.read_limit <= 0) {
|
||||
bufferevent_suspend_read(&bev->bev, BEV_SUSPEND_BW);
|
||||
bufferevent_suspend_read_(&bev->bev, BEV_SUSPEND_BW);
|
||||
if (event_add(&bev->rate_limiting->refill_bucket_event,
|
||||
&bev->rate_limiting->cfg->tick_timeout) < 0)
|
||||
r = -1;
|
||||
} else if (bev->read_suspended & BEV_SUSPEND_BW) {
|
||||
if (!(bev->write_suspended & BEV_SUSPEND_BW))
|
||||
event_del(&bev->rate_limiting->refill_bucket_event);
|
||||
bufferevent_unsuspend_read(&bev->bev, BEV_SUSPEND_BW);
|
||||
bufferevent_unsuspend_read_(&bev->bev, BEV_SUSPEND_BW);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -299,9 +297,9 @@ _bufferevent_decrement_read_buckets(struct bufferevent_private *bev, ev_ssize_t
|
|||
bev->rate_limiting->group->rate_limit.read_limit -= bytes;
|
||||
bev->rate_limiting->group->total_read += bytes;
|
||||
if (bev->rate_limiting->group->rate_limit.read_limit <= 0) {
|
||||
_bev_group_suspend_reading(bev->rate_limiting->group);
|
||||
bev_group_suspend_reading_(bev->rate_limiting->group);
|
||||
} else if (bev->rate_limiting->group->read_suspended) {
|
||||
_bev_group_unsuspend_reading(bev->rate_limiting->group);
|
||||
bev_group_unsuspend_reading_(bev->rate_limiting->group);
|
||||
}
|
||||
UNLOCK_GROUP(bev->rate_limiting->group);
|
||||
}
|
||||
|
@ -310,7 +308,7 @@ _bufferevent_decrement_read_buckets(struct bufferevent_private *bev, ev_ssize_t
|
|||
}
|
||||
|
||||
int
|
||||
_bufferevent_decrement_write_buckets(struct bufferevent_private *bev, ev_ssize_t bytes)
|
||||
bufferevent_decrement_write_buckets_(struct bufferevent_private *bev, ev_ssize_t bytes)
|
||||
{
|
||||
/* XXXXX Make sure all users of this function check its return value */
|
||||
int r = 0;
|
||||
|
@ -321,14 +319,14 @@ _bufferevent_decrement_write_buckets(struct bufferevent_private *bev, ev_ssize_t
|
|||
if (bev->rate_limiting->cfg) {
|
||||
bev->rate_limiting->limit.write_limit -= bytes;
|
||||
if (bev->rate_limiting->limit.write_limit <= 0) {
|
||||
bufferevent_suspend_write(&bev->bev, BEV_SUSPEND_BW);
|
||||
bufferevent_suspend_write_(&bev->bev, BEV_SUSPEND_BW);
|
||||
if (event_add(&bev->rate_limiting->refill_bucket_event,
|
||||
&bev->rate_limiting->cfg->tick_timeout) < 0)
|
||||
r = -1;
|
||||
} else if (bev->write_suspended & BEV_SUSPEND_BW) {
|
||||
if (!(bev->read_suspended & BEV_SUSPEND_BW))
|
||||
event_del(&bev->rate_limiting->refill_bucket_event);
|
||||
bufferevent_unsuspend_write(&bev->bev, BEV_SUSPEND_BW);
|
||||
bufferevent_unsuspend_write_(&bev->bev, BEV_SUSPEND_BW);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -337,9 +335,9 @@ _bufferevent_decrement_write_buckets(struct bufferevent_private *bev, ev_ssize_t
|
|||
bev->rate_limiting->group->rate_limit.write_limit -= bytes;
|
||||
bev->rate_limiting->group->total_written += bytes;
|
||||
if (bev->rate_limiting->group->rate_limit.write_limit <= 0) {
|
||||
_bev_group_suspend_writing(bev->rate_limiting->group);
|
||||
bev_group_suspend_writing_(bev->rate_limiting->group);
|
||||
} else if (bev->rate_limiting->group->write_suspended) {
|
||||
_bev_group_unsuspend_writing(bev->rate_limiting->group);
|
||||
bev_group_unsuspend_writing_(bev->rate_limiting->group);
|
||||
}
|
||||
UNLOCK_GROUP(bev->rate_limiting->group);
|
||||
}
|
||||
|
@ -349,22 +347,22 @@ _bufferevent_decrement_write_buckets(struct bufferevent_private *bev, ev_ssize_t
|
|||
|
||||
/** Stop reading on every bufferevent in <b>g</b> */
|
||||
static int
|
||||
_bev_group_suspend_reading(struct bufferevent_rate_limit_group *g)
|
||||
bev_group_suspend_reading_(struct bufferevent_rate_limit_group *g)
|
||||
{
|
||||
/* Needs group lock */
|
||||
struct bufferevent_private *bev;
|
||||
g->read_suspended = 1;
|
||||
g->pending_unsuspend_read = 0;
|
||||
|
||||
/* Note that in this loop we call EVLOCK_TRY_LOCK instead of BEV_LOCK,
|
||||
/* Note that in this loop we call EVLOCK_TRY_LOCK_ instead of BEV_LOCK,
|
||||
to prevent a deadlock. (Ordinarily, the group lock nests inside
|
||||
the bufferevent locks. If we are unable to lock any individual
|
||||
bufferevent, it will find out later when it looks at its limit
|
||||
and sees that its group is suspended.
|
||||
and sees that its group is suspended.)
|
||||
*/
|
||||
TAILQ_FOREACH(bev, &g->members, rate_limiting->next_in_group) {
|
||||
if (EVLOCK_TRY_LOCK(bev->lock)) {
|
||||
bufferevent_suspend_read(&bev->bev,
|
||||
LIST_FOREACH(bev, &g->members, rate_limiting->next_in_group) {
|
||||
if (EVLOCK_TRY_LOCK_(bev->lock)) {
|
||||
bufferevent_suspend_read_(&bev->bev,
|
||||
BEV_SUSPEND_BW_GROUP);
|
||||
EVLOCK_UNLOCK(bev->lock, 0);
|
||||
}
|
||||
|
@ -374,15 +372,15 @@ _bev_group_suspend_reading(struct bufferevent_rate_limit_group *g)
|
|||
|
||||
/** Stop writing on every bufferevent in <b>g</b> */
|
||||
static int
|
||||
_bev_group_suspend_writing(struct bufferevent_rate_limit_group *g)
|
||||
bev_group_suspend_writing_(struct bufferevent_rate_limit_group *g)
|
||||
{
|
||||
/* Needs group lock */
|
||||
struct bufferevent_private *bev;
|
||||
g->write_suspended = 1;
|
||||
g->pending_unsuspend_write = 0;
|
||||
TAILQ_FOREACH(bev, &g->members, rate_limiting->next_in_group) {
|
||||
if (EVLOCK_TRY_LOCK(bev->lock)) {
|
||||
bufferevent_suspend_write(&bev->bev,
|
||||
LIST_FOREACH(bev, &g->members, rate_limiting->next_in_group) {
|
||||
if (EVLOCK_TRY_LOCK_(bev->lock)) {
|
||||
bufferevent_suspend_write_(&bev->bev,
|
||||
BEV_SUSPEND_BW_GROUP);
|
||||
EVLOCK_UNLOCK(bev->lock, 0);
|
||||
}
|
||||
|
@ -393,7 +391,7 @@ _bev_group_suspend_writing(struct bufferevent_rate_limit_group *g)
|
|||
/** Timer callback invoked on a single bufferevent with one or more exhausted
|
||||
buckets when they are ready to refill. */
|
||||
static void
|
||||
_bev_refill_callback(evutil_socket_t fd, short what, void *arg)
|
||||
bev_refill_callback_(evutil_socket_t fd, short what, void *arg)
|
||||
{
|
||||
unsigned tick;
|
||||
struct timeval now;
|
||||
|
@ -407,22 +405,22 @@ _bev_refill_callback(evutil_socket_t fd, short what, void *arg)
|
|||
|
||||
/* First, update the bucket */
|
||||
event_base_gettimeofday_cached(bev->bev.ev_base, &now);
|
||||
tick = ev_token_bucket_get_tick(&now,
|
||||
tick = ev_token_bucket_get_tick_(&now,
|
||||
bev->rate_limiting->cfg);
|
||||
ev_token_bucket_update(&bev->rate_limiting->limit,
|
||||
ev_token_bucket_update_(&bev->rate_limiting->limit,
|
||||
bev->rate_limiting->cfg,
|
||||
tick);
|
||||
|
||||
/* Now unsuspend any read/write operations as appropriate. */
|
||||
if ((bev->read_suspended & BEV_SUSPEND_BW)) {
|
||||
if (bev->rate_limiting->limit.read_limit > 0)
|
||||
bufferevent_unsuspend_read(&bev->bev, BEV_SUSPEND_BW);
|
||||
bufferevent_unsuspend_read_(&bev->bev, BEV_SUSPEND_BW);
|
||||
else
|
||||
again = 1;
|
||||
}
|
||||
if ((bev->write_suspended & BEV_SUSPEND_BW)) {
|
||||
if (bev->rate_limiting->limit.write_limit > 0)
|
||||
bufferevent_unsuspend_write(&bev->bev, BEV_SUSPEND_BW);
|
||||
bufferevent_unsuspend_write_(&bev->bev, BEV_SUSPEND_BW);
|
||||
else
|
||||
again = 1;
|
||||
}
|
||||
|
@ -440,9 +438,12 @@ _bev_refill_callback(evutil_socket_t fd, short what, void *arg)
|
|||
BEV_UNLOCK(&bev->bev);
|
||||
}
|
||||
|
||||
/** Helper: grab a random element from a bufferevent group. */
|
||||
/** Helper: grab a random element from a bufferevent group.
|
||||
*
|
||||
* Requires that we hold the lock on the group.
|
||||
*/
|
||||
static struct bufferevent_private *
|
||||
_bev_group_random_element(struct bufferevent_rate_limit_group *group)
|
||||
bev_group_random_element_(struct bufferevent_rate_limit_group *group)
|
||||
{
|
||||
int which;
|
||||
struct bufferevent_private *bev;
|
||||
|
@ -452,13 +453,13 @@ _bev_group_random_element(struct bufferevent_rate_limit_group *group)
|
|||
if (!group->n_members)
|
||||
return NULL;
|
||||
|
||||
EVUTIL_ASSERT(! TAILQ_EMPTY(&group->members));
|
||||
EVUTIL_ASSERT(! LIST_EMPTY(&group->members));
|
||||
|
||||
which = _evutil_weakrand() % group->n_members;
|
||||
which = evutil_weakrand_range_(&group->weakrand_seed, group->n_members);
|
||||
|
||||
bev = TAILQ_FIRST(&group->members);
|
||||
bev = LIST_FIRST(&group->members);
|
||||
while (which--)
|
||||
bev = TAILQ_NEXT(bev, rate_limiting->next_in_group);
|
||||
bev = LIST_NEXT(bev, rate_limiting->next_in_group);
|
||||
|
||||
return bev;
|
||||
}
|
||||
|
@ -472,27 +473,27 @@ _bev_group_random_element(struct bufferevent_rate_limit_group *group)
|
|||
*/
|
||||
#define FOREACH_RANDOM_ORDER(block) \
|
||||
do { \
|
||||
first = _bev_group_random_element(g); \
|
||||
for (bev = first; bev != TAILQ_END(&g->members); \
|
||||
bev = TAILQ_NEXT(bev, rate_limiting->next_in_group)) { \
|
||||
first = bev_group_random_element_(g); \
|
||||
for (bev = first; bev != LIST_END(&g->members); \
|
||||
bev = LIST_NEXT(bev, rate_limiting->next_in_group)) { \
|
||||
block ; \
|
||||
} \
|
||||
for (bev = TAILQ_FIRST(&g->members); bev && bev != first; \
|
||||
bev = TAILQ_NEXT(bev, rate_limiting->next_in_group)) { \
|
||||
for (bev = LIST_FIRST(&g->members); bev && bev != first; \
|
||||
bev = LIST_NEXT(bev, rate_limiting->next_in_group)) { \
|
||||
block ; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static void
|
||||
_bev_group_unsuspend_reading(struct bufferevent_rate_limit_group *g)
|
||||
bev_group_unsuspend_reading_(struct bufferevent_rate_limit_group *g)
|
||||
{
|
||||
int again = 0;
|
||||
struct bufferevent_private *bev, *first;
|
||||
|
||||
g->read_suspended = 0;
|
||||
FOREACH_RANDOM_ORDER({
|
||||
if (EVLOCK_TRY_LOCK(bev->lock)) {
|
||||
bufferevent_unsuspend_read(&bev->bev,
|
||||
if (EVLOCK_TRY_LOCK_(bev->lock)) {
|
||||
bufferevent_unsuspend_read_(&bev->bev,
|
||||
BEV_SUSPEND_BW_GROUP);
|
||||
EVLOCK_UNLOCK(bev->lock, 0);
|
||||
} else {
|
||||
|
@ -503,15 +504,15 @@ _bev_group_unsuspend_reading(struct bufferevent_rate_limit_group *g)
|
|||
}
|
||||
|
||||
static void
|
||||
_bev_group_unsuspend_writing(struct bufferevent_rate_limit_group *g)
|
||||
bev_group_unsuspend_writing_(struct bufferevent_rate_limit_group *g)
|
||||
{
|
||||
int again = 0;
|
||||
struct bufferevent_private *bev, *first;
|
||||
g->write_suspended = 0;
|
||||
|
||||
FOREACH_RANDOM_ORDER({
|
||||
if (EVLOCK_TRY_LOCK(bev->lock)) {
|
||||
bufferevent_unsuspend_write(&bev->bev,
|
||||
if (EVLOCK_TRY_LOCK_(bev->lock)) {
|
||||
bufferevent_unsuspend_write_(&bev->bev,
|
||||
BEV_SUSPEND_BW_GROUP);
|
||||
EVLOCK_UNLOCK(bev->lock, 0);
|
||||
} else {
|
||||
|
@ -525,7 +526,7 @@ _bev_group_unsuspend_writing(struct bufferevent_rate_limit_group *g)
|
|||
and unsuspend group members as needed.
|
||||
*/
|
||||
static void
|
||||
_bev_group_refill_callback(evutil_socket_t fd, short what, void *arg)
|
||||
bev_group_refill_callback_(evutil_socket_t fd, short what, void *arg)
|
||||
{
|
||||
struct bufferevent_rate_limit_group *g = arg;
|
||||
unsigned tick;
|
||||
|
@ -535,16 +536,16 @@ _bev_group_refill_callback(evutil_socket_t fd, short what, void *arg)
|
|||
|
||||
LOCK_GROUP(g);
|
||||
|
||||
tick = ev_token_bucket_get_tick(&now, &g->rate_limit_cfg);
|
||||
ev_token_bucket_update(&g->rate_limit, &g->rate_limit_cfg, tick);
|
||||
tick = ev_token_bucket_get_tick_(&now, &g->rate_limit_cfg);
|
||||
ev_token_bucket_update_(&g->rate_limit, &g->rate_limit_cfg, tick);
|
||||
|
||||
if (g->pending_unsuspend_read ||
|
||||
(g->read_suspended && (g->rate_limit.read_limit >= g->min_share))) {
|
||||
_bev_group_unsuspend_reading(g);
|
||||
bev_group_unsuspend_reading_(g);
|
||||
}
|
||||
if (g->pending_unsuspend_write ||
|
||||
(g->write_suspended && (g->rate_limit.write_limit >= g->min_share))){
|
||||
_bev_group_unsuspend_writing(g);
|
||||
bev_group_unsuspend_writing_(g);
|
||||
}
|
||||
|
||||
/* XXXX Rather than waiting to the next tick to unsuspend stuff
|
||||
|
@ -574,8 +575,8 @@ bufferevent_set_rate_limit(struct bufferevent *bev,
|
|||
if (bevp->rate_limiting) {
|
||||
rlim = bevp->rate_limiting;
|
||||
rlim->cfg = NULL;
|
||||
bufferevent_unsuspend_read(bev, BEV_SUSPEND_BW);
|
||||
bufferevent_unsuspend_write(bev, BEV_SUSPEND_BW);
|
||||
bufferevent_unsuspend_read_(bev, BEV_SUSPEND_BW);
|
||||
bufferevent_unsuspend_write_(bev, BEV_SUSPEND_BW);
|
||||
if (event_initialized(&rlim->refill_bucket_event))
|
||||
event_del(&rlim->refill_bucket_event);
|
||||
}
|
||||
|
@ -584,7 +585,7 @@ bufferevent_set_rate_limit(struct bufferevent *bev,
|
|||
}
|
||||
|
||||
event_base_gettimeofday_cached(bev->ev_base, &now);
|
||||
tick = ev_token_bucket_get_tick(&now, cfg);
|
||||
tick = ev_token_bucket_get_tick_(&now, cfg);
|
||||
|
||||
if (bevp->rate_limiting && bevp->rate_limiting->cfg == cfg) {
|
||||
/* no-op */
|
||||
|
@ -602,25 +603,25 @@ bufferevent_set_rate_limit(struct bufferevent *bev,
|
|||
reinit = rlim->cfg != NULL;
|
||||
|
||||
rlim->cfg = cfg;
|
||||
ev_token_bucket_init(&rlim->limit, cfg, tick, reinit);
|
||||
ev_token_bucket_init_(&rlim->limit, cfg, tick, reinit);
|
||||
|
||||
if (reinit) {
|
||||
EVUTIL_ASSERT(event_initialized(&rlim->refill_bucket_event));
|
||||
event_del(&rlim->refill_bucket_event);
|
||||
}
|
||||
evtimer_assign(&rlim->refill_bucket_event, bev->ev_base,
|
||||
_bev_refill_callback, bevp);
|
||||
event_assign(&rlim->refill_bucket_event, bev->ev_base,
|
||||
-1, EV_FINALIZE, bev_refill_callback_, bevp);
|
||||
|
||||
if (rlim->limit.read_limit > 0) {
|
||||
bufferevent_unsuspend_read(bev, BEV_SUSPEND_BW);
|
||||
bufferevent_unsuspend_read_(bev, BEV_SUSPEND_BW);
|
||||
} else {
|
||||
bufferevent_suspend_read(bev, BEV_SUSPEND_BW);
|
||||
bufferevent_suspend_read_(bev, BEV_SUSPEND_BW);
|
||||
suspended=1;
|
||||
}
|
||||
if (rlim->limit.write_limit > 0) {
|
||||
bufferevent_unsuspend_write(bev, BEV_SUSPEND_BW);
|
||||
bufferevent_unsuspend_write_(bev, BEV_SUSPEND_BW);
|
||||
} else {
|
||||
bufferevent_suspend_write(bev, BEV_SUSPEND_BW);
|
||||
bufferevent_suspend_write_(bev, BEV_SUSPEND_BW);
|
||||
suspended = 1;
|
||||
}
|
||||
|
||||
|
@ -643,18 +644,18 @@ bufferevent_rate_limit_group_new(struct event_base *base,
|
|||
ev_uint32_t tick;
|
||||
|
||||
event_base_gettimeofday_cached(base, &now);
|
||||
tick = ev_token_bucket_get_tick(&now, cfg);
|
||||
tick = ev_token_bucket_get_tick_(&now, cfg);
|
||||
|
||||
g = mm_calloc(1, sizeof(struct bufferevent_rate_limit_group));
|
||||
if (!g)
|
||||
return NULL;
|
||||
memcpy(&g->rate_limit_cfg, cfg, sizeof(g->rate_limit_cfg));
|
||||
TAILQ_INIT(&g->members);
|
||||
LIST_INIT(&g->members);
|
||||
|
||||
ev_token_bucket_init(&g->rate_limit, cfg, tick, 0);
|
||||
ev_token_bucket_init_(&g->rate_limit, cfg, tick, 0);
|
||||
|
||||
event_assign(&g->master_refill_event, base, -1, EV_PERSIST,
|
||||
_bev_group_refill_callback, g);
|
||||
event_assign(&g->master_refill_event, base, -1, EV_PERSIST|EV_FINALIZE,
|
||||
bev_group_refill_callback_, g);
|
||||
/*XXXX handle event_add failure */
|
||||
event_add(&g->master_refill_event, &cfg->tick_timeout);
|
||||
|
||||
|
@ -662,6 +663,9 @@ bufferevent_rate_limit_group_new(struct event_base *base,
|
|||
|
||||
bufferevent_rate_limit_group_set_min_share(g, 64);
|
||||
|
||||
evutil_weakrand_seed_(&g->weakrand_seed,
|
||||
(ev_uint32_t) ((now.tv_sec + now.tv_usec) + (ev_intptr_t)g));
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
|
@ -744,8 +748,8 @@ bufferevent_add_to_rate_limit_group(struct bufferevent *bev,
|
|||
BEV_UNLOCK(bev);
|
||||
return -1;
|
||||
}
|
||||
evtimer_assign(&rlim->refill_bucket_event, bev->ev_base,
|
||||
_bev_refill_callback, bevp);
|
||||
event_assign(&rlim->refill_bucket_event, bev->ev_base,
|
||||
-1, EV_FINALIZE, bev_refill_callback_, bevp);
|
||||
bevp->rate_limiting = rlim;
|
||||
}
|
||||
|
||||
|
@ -759,7 +763,7 @@ bufferevent_add_to_rate_limit_group(struct bufferevent *bev,
|
|||
LOCK_GROUP(g);
|
||||
bevp->rate_limiting->group = g;
|
||||
++g->n_members;
|
||||
TAILQ_INSERT_TAIL(&g->members, bevp, rate_limiting->next_in_group);
|
||||
LIST_INSERT_HEAD(&g->members, bevp, rate_limiting->next_in_group);
|
||||
|
||||
rsuspend = g->read_suspended;
|
||||
wsuspend = g->write_suspended;
|
||||
|
@ -767,9 +771,9 @@ bufferevent_add_to_rate_limit_group(struct bufferevent *bev,
|
|||
UNLOCK_GROUP(g);
|
||||
|
||||
if (rsuspend)
|
||||
bufferevent_suspend_read(bev, BEV_SUSPEND_BW_GROUP);
|
||||
bufferevent_suspend_read_(bev, BEV_SUSPEND_BW_GROUP);
|
||||
if (wsuspend)
|
||||
bufferevent_suspend_write(bev, BEV_SUSPEND_BW_GROUP);
|
||||
bufferevent_suspend_write_(bev, BEV_SUSPEND_BW_GROUP);
|
||||
|
||||
BEV_UNLOCK(bev);
|
||||
return 0;
|
||||
|
@ -778,11 +782,11 @@ bufferevent_add_to_rate_limit_group(struct bufferevent *bev,
|
|||
int
|
||||
bufferevent_remove_from_rate_limit_group(struct bufferevent *bev)
|
||||
{
|
||||
return bufferevent_remove_from_rate_limit_group_internal(bev, 1);
|
||||
return bufferevent_remove_from_rate_limit_group_internal_(bev, 1);
|
||||
}
|
||||
|
||||
int
|
||||
bufferevent_remove_from_rate_limit_group_internal(struct bufferevent *bev,
|
||||
bufferevent_remove_from_rate_limit_group_internal_(struct bufferevent *bev,
|
||||
int unsuspend)
|
||||
{
|
||||
struct bufferevent_private *bevp =
|
||||
|
@ -794,12 +798,12 @@ bufferevent_remove_from_rate_limit_group_internal(struct bufferevent *bev,
|
|||
LOCK_GROUP(g);
|
||||
bevp->rate_limiting->group = NULL;
|
||||
--g->n_members;
|
||||
TAILQ_REMOVE(&g->members, bevp, rate_limiting->next_in_group);
|
||||
LIST_REMOVE(bevp, rate_limiting->next_in_group);
|
||||
UNLOCK_GROUP(g);
|
||||
}
|
||||
if (unsuspend) {
|
||||
bufferevent_unsuspend_read(bev, BEV_SUSPEND_BW_GROUP);
|
||||
bufferevent_unsuspend_write(bev, BEV_SUSPEND_BW_GROUP);
|
||||
bufferevent_unsuspend_read_(bev, BEV_SUSPEND_BW_GROUP);
|
||||
bufferevent_unsuspend_write_(bev, BEV_SUSPEND_BW_GROUP);
|
||||
}
|
||||
BEV_UNLOCK(bev);
|
||||
return 0;
|
||||
|
@ -813,7 +817,7 @@ bufferevent_remove_from_rate_limit_group_internal(struct bufferevent *bev,
|
|||
* === */
|
||||
|
||||
/* Mostly you don't want to use this function from inside libevent;
|
||||
* _bufferevent_get_read_max() is more likely what you want*/
|
||||
* bufferevent_get_read_max_() is more likely what you want*/
|
||||
ev_ssize_t
|
||||
bufferevent_get_read_limit(struct bufferevent *bev)
|
||||
{
|
||||
|
@ -832,7 +836,7 @@ bufferevent_get_read_limit(struct bufferevent *bev)
|
|||
}
|
||||
|
||||
/* Mostly you don't want to use this function from inside libevent;
|
||||
* _bufferevent_get_write_max() is more likely what you want*/
|
||||
* bufferevent_get_write_max_() is more likely what you want*/
|
||||
ev_ssize_t
|
||||
bufferevent_get_write_limit(struct bufferevent *bev)
|
||||
{
|
||||
|
@ -850,12 +854,62 @@ bufferevent_get_write_limit(struct bufferevent *bev)
|
|||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
bufferevent_set_max_single_read(struct bufferevent *bev, size_t size)
|
||||
{
|
||||
struct bufferevent_private *bevp;
|
||||
BEV_LOCK(bev);
|
||||
bevp = BEV_UPCAST(bev);
|
||||
if (size == 0 || size > EV_SSIZE_MAX)
|
||||
bevp->max_single_read = MAX_SINGLE_READ_DEFAULT;
|
||||
else
|
||||
bevp->max_single_read = size;
|
||||
BEV_UNLOCK(bev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bufferevent_set_max_single_write(struct bufferevent *bev, size_t size)
|
||||
{
|
||||
struct bufferevent_private *bevp;
|
||||
BEV_LOCK(bev);
|
||||
bevp = BEV_UPCAST(bev);
|
||||
if (size == 0 || size > EV_SSIZE_MAX)
|
||||
bevp->max_single_write = MAX_SINGLE_WRITE_DEFAULT;
|
||||
else
|
||||
bevp->max_single_write = size;
|
||||
BEV_UNLOCK(bev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ev_ssize_t
|
||||
bufferevent_get_max_single_read(struct bufferevent *bev)
|
||||
{
|
||||
ev_ssize_t r;
|
||||
|
||||
BEV_LOCK(bev);
|
||||
r = BEV_UPCAST(bev)->max_single_read;
|
||||
BEV_UNLOCK(bev);
|
||||
return r;
|
||||
}
|
||||
|
||||
ev_ssize_t
|
||||
bufferevent_get_max_single_write(struct bufferevent *bev)
|
||||
{
|
||||
ev_ssize_t r;
|
||||
|
||||
BEV_LOCK(bev);
|
||||
r = BEV_UPCAST(bev)->max_single_write;
|
||||
BEV_UNLOCK(bev);
|
||||
return r;
|
||||
}
|
||||
|
||||
ev_ssize_t
|
||||
bufferevent_get_max_to_read(struct bufferevent *bev)
|
||||
{
|
||||
ev_ssize_t r;
|
||||
BEV_LOCK(bev);
|
||||
r = _bufferevent_get_read_max(BEV_UPCAST(bev));
|
||||
r = bufferevent_get_read_max_(BEV_UPCAST(bev));
|
||||
BEV_UNLOCK(bev);
|
||||
return r;
|
||||
}
|
||||
|
@ -865,14 +919,31 @@ bufferevent_get_max_to_write(struct bufferevent *bev)
|
|||
{
|
||||
ev_ssize_t r;
|
||||
BEV_LOCK(bev);
|
||||
r = _bufferevent_get_write_max(BEV_UPCAST(bev));
|
||||
r = bufferevent_get_write_max_(BEV_UPCAST(bev));
|
||||
BEV_UNLOCK(bev);
|
||||
return r;
|
||||
}
|
||||
|
||||
const struct ev_token_bucket_cfg *
|
||||
bufferevent_get_token_bucket_cfg(const struct bufferevent *bev) {
|
||||
struct bufferevent_private *bufev_private = BEV_UPCAST(bev);
|
||||
struct ev_token_bucket_cfg *cfg;
|
||||
|
||||
BEV_LOCK(bev);
|
||||
|
||||
if (bufev_private->rate_limiting) {
|
||||
cfg = bufev_private->rate_limiting->cfg;
|
||||
} else {
|
||||
cfg = NULL;
|
||||
}
|
||||
|
||||
BEV_UNLOCK(bev);
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
/* Mostly you don't want to use this function from inside libevent;
|
||||
* _bufferevent_get_read_max() is more likely what you want*/
|
||||
* bufferevent_get_read_max_() is more likely what you want*/
|
||||
ev_ssize_t
|
||||
bufferevent_rate_limit_group_get_read_limit(
|
||||
struct bufferevent_rate_limit_group *grp)
|
||||
|
@ -885,7 +956,7 @@ bufferevent_rate_limit_group_get_read_limit(
|
|||
}
|
||||
|
||||
/* Mostly you don't want to use this function from inside libevent;
|
||||
* _bufferevent_get_write_max() is more likely what you want. */
|
||||
* bufferevent_get_write_max_() is more likely what you want. */
|
||||
ev_ssize_t
|
||||
bufferevent_rate_limit_group_get_write_limit(
|
||||
struct bufferevent_rate_limit_group *grp)
|
||||
|
@ -910,14 +981,14 @@ bufferevent_decrement_read_limit(struct bufferevent *bev, ev_ssize_t decr)
|
|||
|
||||
new_limit = (bevp->rate_limiting->limit.read_limit -= decr);
|
||||
if (old_limit > 0 && new_limit <= 0) {
|
||||
bufferevent_suspend_read(bev, BEV_SUSPEND_BW);
|
||||
bufferevent_suspend_read_(bev, BEV_SUSPEND_BW);
|
||||
if (event_add(&bevp->rate_limiting->refill_bucket_event,
|
||||
&bevp->rate_limiting->cfg->tick_timeout) < 0)
|
||||
r = -1;
|
||||
} else if (old_limit <= 0 && new_limit > 0) {
|
||||
if (!(bevp->write_suspended & BEV_SUSPEND_BW))
|
||||
event_del(&bevp->rate_limiting->refill_bucket_event);
|
||||
bufferevent_unsuspend_read(bev, BEV_SUSPEND_BW);
|
||||
bufferevent_unsuspend_read_(bev, BEV_SUSPEND_BW);
|
||||
}
|
||||
|
||||
BEV_UNLOCK(bev);
|
||||
|
@ -939,14 +1010,14 @@ bufferevent_decrement_write_limit(struct bufferevent *bev, ev_ssize_t decr)
|
|||
|
||||
new_limit = (bevp->rate_limiting->limit.write_limit -= decr);
|
||||
if (old_limit > 0 && new_limit <= 0) {
|
||||
bufferevent_suspend_write(bev, BEV_SUSPEND_BW);
|
||||
bufferevent_suspend_write_(bev, BEV_SUSPEND_BW);
|
||||
if (event_add(&bevp->rate_limiting->refill_bucket_event,
|
||||
&bevp->rate_limiting->cfg->tick_timeout) < 0)
|
||||
r = -1;
|
||||
} else if (old_limit <= 0 && new_limit > 0) {
|
||||
if (!(bevp->read_suspended & BEV_SUSPEND_BW))
|
||||
event_del(&bevp->rate_limiting->refill_bucket_event);
|
||||
bufferevent_unsuspend_write(bev, BEV_SUSPEND_BW);
|
||||
bufferevent_unsuspend_write_(bev, BEV_SUSPEND_BW);
|
||||
}
|
||||
|
||||
BEV_UNLOCK(bev);
|
||||
|
@ -964,9 +1035,9 @@ bufferevent_rate_limit_group_decrement_read(
|
|||
new_limit = (grp->rate_limit.read_limit -= decr);
|
||||
|
||||
if (old_limit > 0 && new_limit <= 0) {
|
||||
_bev_group_suspend_reading(grp);
|
||||
bev_group_suspend_reading_(grp);
|
||||
} else if (old_limit <= 0 && new_limit > 0) {
|
||||
_bev_group_unsuspend_reading(grp);
|
||||
bev_group_unsuspend_reading_(grp);
|
||||
}
|
||||
|
||||
UNLOCK_GROUP(grp);
|
||||
|
@ -984,9 +1055,9 @@ bufferevent_rate_limit_group_decrement_write(
|
|||
new_limit = (grp->rate_limit.write_limit -= decr);
|
||||
|
||||
if (old_limit > 0 && new_limit <= 0) {
|
||||
_bev_group_suspend_writing(grp);
|
||||
bev_group_suspend_writing_(grp);
|
||||
} else if (old_limit <= 0 && new_limit > 0) {
|
||||
_bev_group_unsuspend_writing(grp);
|
||||
bev_group_unsuspend_writing_(grp);
|
||||
}
|
||||
|
||||
UNLOCK_GROUP(grp);
|
||||
|
@ -1009,3 +1080,13 @@ bufferevent_rate_limit_group_reset_totals(struct bufferevent_rate_limit_group *g
|
|||
{
|
||||
grp->total_read = grp->total_written = 0;
|
||||
}
|
||||
|
||||
int
|
||||
bufferevent_ratelim_init_(struct bufferevent_private *bev)
|
||||
{
|
||||
bev->rate_limiting = NULL;
|
||||
bev->max_single_read = MAX_SINGLE_READ_DEFAULT;
|
||||
bev->max_single_write = MAX_SINGLE_WRITE_DEFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -26,11 +26,12 @@
|
|||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "event2/event-config.h"
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "event2/event-config.h"
|
||||
|
||||
#ifdef _EVENT_HAVE_SYS_TIME_H
|
||||
#ifdef EVENT__HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
|
@ -38,25 +39,25 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef _EVENT_HAVE_STDARG_H
|
||||
#ifdef EVENT__HAVE_STDARG_H
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
#ifdef _EVENT_HAVE_UNISTD_H
|
||||
#ifdef EVENT__HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
#ifdef _EVENT_HAVE_SYS_SOCKET_H
|
||||
#ifdef EVENT__HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef _EVENT_HAVE_NETINET_IN_H
|
||||
#ifdef EVENT__HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef _EVENT_HAVE_NETINET_IN6_H
|
||||
#ifdef EVENT__HAVE_NETINET_IN6_H
|
||||
#include <netinet/in6.h>
|
||||
#endif
|
||||
|
||||
|
@ -70,7 +71,7 @@
|
|||
#include "mm-internal.h"
|
||||
#include "bufferevent-internal.h"
|
||||
#include "util-internal.h"
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include "iocp-internal.h"
|
||||
#endif
|
||||
|
||||
|
@ -78,7 +79,6 @@
|
|||
static int be_socket_enable(struct bufferevent *, short);
|
||||
static int be_socket_disable(struct bufferevent *, short);
|
||||
static void be_socket_destruct(struct bufferevent *);
|
||||
static int be_socket_adj_timeouts(struct bufferevent *);
|
||||
static int be_socket_flush(struct bufferevent *, short, enum bufferevent_flush_mode);
|
||||
static int be_socket_ctrl(struct bufferevent *, enum bufferevent_ctrl_op, union bufferevent_ctrl_data *);
|
||||
|
||||
|
@ -89,14 +89,37 @@ const struct bufferevent_ops bufferevent_ops_socket = {
|
|||
evutil_offsetof(struct bufferevent_private, bev),
|
||||
be_socket_enable,
|
||||
be_socket_disable,
|
||||
NULL, /* unlink */
|
||||
be_socket_destruct,
|
||||
be_socket_adj_timeouts,
|
||||
bufferevent_generic_adj_existing_timeouts_,
|
||||
be_socket_flush,
|
||||
be_socket_ctrl,
|
||||
};
|
||||
|
||||
#define be_socket_add(ev, t) \
|
||||
_bufferevent_add_event((ev), (t))
|
||||
const struct sockaddr*
|
||||
bufferevent_socket_get_conn_address_(struct bufferevent *bev)
|
||||
{
|
||||
struct bufferevent_private *bev_p =
|
||||
EVUTIL_UPCAST(bev, struct bufferevent_private, bev);
|
||||
|
||||
return (struct sockaddr *)&bev_p->conn_address;
|
||||
}
|
||||
static void
|
||||
bufferevent_socket_set_conn_address_fd(struct bufferevent_private *bev_p, int fd)
|
||||
{
|
||||
socklen_t len = sizeof(bev_p->conn_address);
|
||||
|
||||
struct sockaddr *addr = (struct sockaddr *)&bev_p->conn_address;
|
||||
if (addr->sa_family != AF_UNSPEC)
|
||||
getpeername(fd, addr, &len);
|
||||
}
|
||||
static void
|
||||
bufferevent_socket_set_conn_address(struct bufferevent_private *bev_p,
|
||||
struct sockaddr *addr, size_t addrlen)
|
||||
{
|
||||
EVUTIL_ASSERT(addrlen <= sizeof(bev_p->conn_address));
|
||||
memcpy(&bev_p->conn_address, addr, addrlen);
|
||||
}
|
||||
|
||||
static void
|
||||
bufferevent_socket_outbuf_cb(struct evbuffer *buf,
|
||||
|
@ -113,7 +136,7 @@ bufferevent_socket_outbuf_cb(struct evbuffer *buf,
|
|||
!bufev_p->write_suspended) {
|
||||
/* Somebody added data to the buffer, and we would like to
|
||||
* write, and we were not writing. So, start writing. */
|
||||
if (be_socket_add(&bufev->ev_write, &bufev->timeout_write) == -1) {
|
||||
if (bufferevent_add_event_(&bufev->ev_write, &bufev->timeout_write) == -1) {
|
||||
/* Should we log this? */
|
||||
}
|
||||
}
|
||||
|
@ -130,7 +153,7 @@ bufferevent_readcb(evutil_socket_t fd, short event, void *arg)
|
|||
short what = BEV_EVENT_READING;
|
||||
ev_ssize_t howmuch = -1, readmax=-1;
|
||||
|
||||
_bufferevent_incref_and_lock(bufev);
|
||||
bufferevent_incref_and_lock_(bufev);
|
||||
|
||||
if (event == EV_TIMEOUT) {
|
||||
/* Note that we only check for event==EV_TIMEOUT. If
|
||||
|
@ -154,7 +177,7 @@ bufferevent_readcb(evutil_socket_t fd, short event, void *arg)
|
|||
goto done;
|
||||
}
|
||||
}
|
||||
readmax = _bufferevent_get_read_max(bufev_p);
|
||||
readmax = bufferevent_get_read_max_(bufev_p);
|
||||
if (howmuch < 0 || howmuch > readmax) /* The use of -1 for "unlimited"
|
||||
* uglifies this code. XXXX */
|
||||
howmuch = readmax;
|
||||
|
@ -169,6 +192,10 @@ bufferevent_readcb(evutil_socket_t fd, short event, void *arg)
|
|||
int err = evutil_socket_geterror(fd);
|
||||
if (EVUTIL_ERR_RW_RETRIABLE(err))
|
||||
goto reschedule;
|
||||
if (EVUTIL_ERR_CONNECT_REFUSED(err)) {
|
||||
bufev_p->connection_refused = 1;
|
||||
goto done;
|
||||
}
|
||||
/* error case */
|
||||
what |= BEV_EVENT_ERROR;
|
||||
} else if (res == 0) {
|
||||
|
@ -179,11 +206,10 @@ bufferevent_readcb(evutil_socket_t fd, short event, void *arg)
|
|||
if (res <= 0)
|
||||
goto error;
|
||||
|
||||
_bufferevent_decrement_read_buckets(bufev_p, res);
|
||||
bufferevent_decrement_read_buckets_(bufev_p, res);
|
||||
|
||||
/* Invoke the user callback - must always be called last */
|
||||
if (evbuffer_get_length(input) >= bufev->wm_read.low)
|
||||
_bufferevent_run_readcb(bufev);
|
||||
bufferevent_trigger_nolock_(bufev, EV_READ, 0);
|
||||
|
||||
goto done;
|
||||
|
||||
|
@ -192,10 +218,10 @@ bufferevent_readcb(evutil_socket_t fd, short event, void *arg)
|
|||
|
||||
error:
|
||||
bufferevent_disable(bufev, EV_READ);
|
||||
_bufferevent_run_eventcb(bufev, what);
|
||||
bufferevent_run_eventcb_(bufev, what, 0);
|
||||
|
||||
done:
|
||||
_bufferevent_decref_and_unlock(bufev);
|
||||
bufferevent_decref_and_unlock_(bufev);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -209,7 +235,7 @@ bufferevent_writecb(evutil_socket_t fd, short event, void *arg)
|
|||
int connected = 0;
|
||||
ev_ssize_t atmost = -1;
|
||||
|
||||
_bufferevent_incref_and_lock(bufev);
|
||||
bufferevent_incref_and_lock_(bufev);
|
||||
|
||||
if (event == EV_TIMEOUT) {
|
||||
/* Note that we only check for event==EV_TIMEOUT. If
|
||||
|
@ -219,12 +245,12 @@ bufferevent_writecb(evutil_socket_t fd, short event, void *arg)
|
|||
goto error;
|
||||
}
|
||||
if (bufev_p->connecting) {
|
||||
int c = evutil_socket_finished_connecting(fd);
|
||||
int c = evutil_socket_finished_connecting_(fd);
|
||||
/* we need to fake the error if the connection was refused
|
||||
* immediately - usually connection to localhost on BSD */
|
||||
if (bufev_p->connection_refused) {
|
||||
bufev_p->connection_refused = 0;
|
||||
c = -1;
|
||||
bufev_p->connection_refused = 0;
|
||||
c = -1;
|
||||
}
|
||||
|
||||
if (c == 0)
|
||||
|
@ -234,21 +260,22 @@ bufferevent_writecb(evutil_socket_t fd, short event, void *arg)
|
|||
if (c < 0) {
|
||||
event_del(&bufev->ev_write);
|
||||
event_del(&bufev->ev_read);
|
||||
_bufferevent_run_eventcb(bufev, BEV_EVENT_ERROR);
|
||||
bufferevent_run_eventcb_(bufev, BEV_EVENT_ERROR, 0);
|
||||
goto done;
|
||||
} else {
|
||||
connected = 1;
|
||||
#ifdef WIN32
|
||||
bufferevent_socket_set_conn_address_fd(bufev_p, fd);
|
||||
#ifdef _WIN32
|
||||
if (BEV_IS_ASYNC(bufev)) {
|
||||
event_del(&bufev->ev_write);
|
||||
bufferevent_async_set_connected(bufev);
|
||||
_bufferevent_run_eventcb(bufev,
|
||||
BEV_EVENT_CONNECTED);
|
||||
bufferevent_async_set_connected_(bufev);
|
||||
bufferevent_run_eventcb_(bufev,
|
||||
BEV_EVENT_CONNECTED, 0);
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
_bufferevent_run_eventcb(bufev,
|
||||
BEV_EVENT_CONNECTED);
|
||||
bufferevent_run_eventcb_(bufev,
|
||||
BEV_EVENT_CONNECTED, 0);
|
||||
if (!(bufev->enabled & EV_WRITE) ||
|
||||
bufev_p->write_suspended) {
|
||||
event_del(&bufev->ev_write);
|
||||
|
@ -257,7 +284,7 @@ bufferevent_writecb(evutil_socket_t fd, short event, void *arg)
|
|||
}
|
||||
}
|
||||
|
||||
atmost = _bufferevent_get_write_max(bufev_p);
|
||||
atmost = bufferevent_get_write_max_(bufev_p);
|
||||
|
||||
if (bufev_p->write_suspended)
|
||||
goto done;
|
||||
|
@ -281,7 +308,7 @@ bufferevent_writecb(evutil_socket_t fd, short event, void *arg)
|
|||
if (res <= 0)
|
||||
goto error;
|
||||
|
||||
_bufferevent_decrement_write_buckets(bufev_p, res);
|
||||
bufferevent_decrement_write_buckets_(bufev_p, res);
|
||||
}
|
||||
|
||||
if (evbuffer_get_length(bufev->output) == 0) {
|
||||
|
@ -292,9 +319,8 @@ bufferevent_writecb(evutil_socket_t fd, short event, void *arg)
|
|||
* Invoke the user callback if our buffer is drained or below the
|
||||
* low watermark.
|
||||
*/
|
||||
if ((res || !connected) &&
|
||||
evbuffer_get_length(bufev->output) <= bufev->wm_write.low) {
|
||||
_bufferevent_run_writecb(bufev);
|
||||
if (res || !connected) {
|
||||
bufferevent_trigger_nolock_(bufev, EV_WRITE, 0);
|
||||
}
|
||||
|
||||
goto done;
|
||||
|
@ -307,10 +333,10 @@ bufferevent_writecb(evutil_socket_t fd, short event, void *arg)
|
|||
|
||||
error:
|
||||
bufferevent_disable(bufev, EV_WRITE);
|
||||
_bufferevent_run_eventcb(bufev, what);
|
||||
bufferevent_run_eventcb_(bufev, what, 0);
|
||||
|
||||
done:
|
||||
_bufferevent_decref_and_unlock(bufev);
|
||||
bufferevent_decref_and_unlock_(bufev);
|
||||
}
|
||||
|
||||
struct bufferevent *
|
||||
|
@ -320,15 +346,15 @@ bufferevent_socket_new(struct event_base *base, evutil_socket_t fd,
|
|||
struct bufferevent_private *bufev_p;
|
||||
struct bufferevent *bufev;
|
||||
|
||||
#ifdef WIN32
|
||||
if (base && event_base_get_iocp(base))
|
||||
return bufferevent_async_new(base, fd, options);
|
||||
#ifdef _WIN32
|
||||
if (base && event_base_get_iocp_(base))
|
||||
return bufferevent_async_new_(base, fd, options);
|
||||
#endif
|
||||
|
||||
if ((bufev_p = mm_calloc(1, sizeof(struct bufferevent_private)))== NULL)
|
||||
return NULL;
|
||||
|
||||
if (bufferevent_init_common(bufev_p, base, &bufferevent_ops_socket,
|
||||
if (bufferevent_init_common_(bufev_p, base, &bufferevent_ops_socket,
|
||||
options) < 0) {
|
||||
mm_free(bufev_p);
|
||||
return NULL;
|
||||
|
@ -337,9 +363,9 @@ bufferevent_socket_new(struct event_base *base, evutil_socket_t fd,
|
|||
evbuffer_set_flags(bufev->output, EVBUFFER_FLAG_DRAINS_TO_FD);
|
||||
|
||||
event_assign(&bufev->ev_read, bufev->ev_base, fd,
|
||||
EV_READ|EV_PERSIST, bufferevent_readcb, bufev);
|
||||
EV_READ|EV_PERSIST|EV_FINALIZE, bufferevent_readcb, bufev);
|
||||
event_assign(&bufev->ev_write, bufev->ev_base, fd,
|
||||
EV_WRITE|EV_PERSIST, bufferevent_writecb, bufev);
|
||||
EV_WRITE|EV_PERSIST|EV_FINALIZE, bufferevent_writecb, bufev);
|
||||
|
||||
evbuffer_add_cb(bufev->output, bufferevent_socket_outbuf_cb, bufev);
|
||||
|
||||
|
@ -351,7 +377,7 @@ bufferevent_socket_new(struct event_base *base, evutil_socket_t fd,
|
|||
|
||||
int
|
||||
bufferevent_socket_connect(struct bufferevent *bev,
|
||||
struct sockaddr *sa, int socklen)
|
||||
const struct sockaddr *sa, int socklen)
|
||||
{
|
||||
struct bufferevent_private *bufev_p =
|
||||
EVUTIL_UPCAST(bev, struct bufferevent_private, bev);
|
||||
|
@ -361,7 +387,7 @@ bufferevent_socket_connect(struct bufferevent *bev,
|
|||
int result=-1;
|
||||
int ownfd = 0;
|
||||
|
||||
_bufferevent_incref_and_lock(bev);
|
||||
bufferevent_incref_and_lock_(bev);
|
||||
|
||||
if (!bufev_p)
|
||||
goto done;
|
||||
|
@ -370,18 +396,17 @@ bufferevent_socket_connect(struct bufferevent *bev,
|
|||
if (fd < 0) {
|
||||
if (!sa)
|
||||
goto done;
|
||||
fd = socket(sa->sa_family, SOCK_STREAM, 0);
|
||||
fd = evutil_socket_(sa->sa_family,
|
||||
SOCK_STREAM|EVUTIL_SOCK_NONBLOCK, 0);
|
||||
if (fd < 0)
|
||||
goto done;
|
||||
if (evutil_make_socket_nonblocking(fd)<0)
|
||||
goto done;
|
||||
ownfd = 1;
|
||||
}
|
||||
if (sa) {
|
||||
#ifdef WIN32
|
||||
if (bufferevent_async_can_connect(bev)) {
|
||||
#ifdef _WIN32
|
||||
if (bufferevent_async_can_connect_(bev)) {
|
||||
bufferevent_setfd(bev, fd);
|
||||
r = bufferevent_async_connect(bev, fd, sa, socklen);
|
||||
r = bufferevent_async_connect_(bev, fd, sa, socklen);
|
||||
if (r < 0)
|
||||
goto freesock;
|
||||
bufev_p->connecting = 1;
|
||||
|
@ -389,17 +414,17 @@ bufferevent_socket_connect(struct bufferevent *bev,
|
|||
goto done;
|
||||
} else
|
||||
#endif
|
||||
r = evutil_socket_connect(&fd, sa, socklen);
|
||||
r = evutil_socket_connect_(&fd, sa, socklen);
|
||||
if (r < 0)
|
||||
goto freesock;
|
||||
}
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
/* ConnectEx() isn't always around, even when IOCP is enabled.
|
||||
* Here, we borrow the socket object's write handler to fall back
|
||||
* on a non-blocking connect() when ConnectEx() is unavailable. */
|
||||
if (BEV_IS_ASYNC(bev)) {
|
||||
event_assign(&bev->ev_write, bev->ev_base, fd,
|
||||
EV_WRITE|EV_PERSIST, bufferevent_writecb, bev);
|
||||
EV_WRITE|EV_PERSIST|EV_FINALIZE, bufferevent_writecb, bev);
|
||||
}
|
||||
#endif
|
||||
bufferevent_setfd(bev, fd);
|
||||
|
@ -413,24 +438,23 @@ bufferevent_socket_connect(struct bufferevent *bev,
|
|||
/* The connect succeeded already. How very BSD of it. */
|
||||
result = 0;
|
||||
bufev_p->connecting = 1;
|
||||
event_active(&bev->ev_write, EV_WRITE, 1);
|
||||
bufferevent_trigger_nolock_(bev, EV_WRITE, BEV_OPT_DEFER_CALLBACKS);
|
||||
} else {
|
||||
/* The connect failed already. How very BSD of it. */
|
||||
bufev_p->connection_refused = 1;
|
||||
bufev_p->connecting = 1;
|
||||
result = 0;
|
||||
event_active(&bev->ev_write, EV_WRITE, 1);
|
||||
bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR, BEV_OPT_DEFER_CALLBACKS);
|
||||
bufferevent_disable(bev, EV_WRITE|EV_READ);
|
||||
}
|
||||
|
||||
goto done;
|
||||
|
||||
freesock:
|
||||
_bufferevent_run_eventcb(bev, BEV_EVENT_ERROR);
|
||||
bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR, 0);
|
||||
if (ownfd)
|
||||
evutil_closesocket(fd);
|
||||
/* do something about the error? */
|
||||
done:
|
||||
_bufferevent_decref_and_unlock(bev);
|
||||
bufferevent_decref_and_unlock_(bev);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -444,13 +468,20 @@ bufferevent_connect_getaddrinfo_cb(int result, struct evutil_addrinfo *ai,
|
|||
int r;
|
||||
BEV_LOCK(bev);
|
||||
|
||||
bufferevent_unsuspend_write(bev, BEV_SUSPEND_LOOKUP);
|
||||
bufferevent_unsuspend_read(bev, BEV_SUSPEND_LOOKUP);
|
||||
bufferevent_unsuspend_write_(bev, BEV_SUSPEND_LOOKUP);
|
||||
bufferevent_unsuspend_read_(bev, BEV_SUSPEND_LOOKUP);
|
||||
|
||||
bev_p->dns_request = NULL;
|
||||
|
||||
if (result == EVUTIL_EAI_CANCEL) {
|
||||
bev_p->dns_error = result;
|
||||
bufferevent_decref_and_unlock_(bev);
|
||||
return;
|
||||
}
|
||||
if (result != 0) {
|
||||
bev_p->dns_error = result;
|
||||
_bufferevent_run_eventcb(bev, BEV_EVENT_ERROR);
|
||||
_bufferevent_decref_and_unlock(bev);
|
||||
bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR, 0);
|
||||
bufferevent_decref_and_unlock_(bev);
|
||||
if (ai)
|
||||
evutil_freeaddrinfo(ai);
|
||||
return;
|
||||
|
@ -458,9 +489,10 @@ bufferevent_connect_getaddrinfo_cb(int result, struct evutil_addrinfo *ai,
|
|||
|
||||
/* XXX use the other addrinfos? */
|
||||
/* XXX use this return value */
|
||||
bufferevent_socket_set_conn_address(bev_p, ai->ai_addr, (int)ai->ai_addrlen);
|
||||
r = bufferevent_socket_connect(bev, ai->ai_addr, (int)ai->ai_addrlen);
|
||||
(void)r;
|
||||
_bufferevent_decref_and_unlock(bev);
|
||||
bufferevent_decref_and_unlock_(bev);
|
||||
evutil_freeaddrinfo(ai);
|
||||
}
|
||||
|
||||
|
@ -470,7 +502,6 @@ bufferevent_socket_connect_hostname(struct bufferevent *bev,
|
|||
{
|
||||
char portbuf[10];
|
||||
struct evutil_addrinfo hint;
|
||||
int err;
|
||||
struct bufferevent_private *bev_p =
|
||||
EVUTIL_UPCAST(bev, struct bufferevent_private, bev);
|
||||
|
||||
|
@ -479,31 +510,25 @@ bufferevent_socket_connect_hostname(struct bufferevent *bev,
|
|||
if (port < 1 || port > 65535)
|
||||
return -1;
|
||||
|
||||
BEV_LOCK(bev);
|
||||
bev_p->dns_error = 0;
|
||||
BEV_UNLOCK(bev);
|
||||
|
||||
evutil_snprintf(portbuf, sizeof(portbuf), "%d", port);
|
||||
|
||||
memset(&hint, 0, sizeof(hint));
|
||||
hint.ai_family = family;
|
||||
hint.ai_protocol = IPPROTO_TCP;
|
||||
hint.ai_socktype = SOCK_STREAM;
|
||||
|
||||
bufferevent_suspend_write(bev, BEV_SUSPEND_LOOKUP);
|
||||
bufferevent_suspend_read(bev, BEV_SUSPEND_LOOKUP);
|
||||
evutil_snprintf(portbuf, sizeof(portbuf), "%d", port);
|
||||
|
||||
bufferevent_incref(bev);
|
||||
err = evutil_getaddrinfo_async(evdns_base, hostname, portbuf,
|
||||
&hint, bufferevent_connect_getaddrinfo_cb, bev);
|
||||
BEV_LOCK(bev);
|
||||
bev_p->dns_error = 0;
|
||||
|
||||
if (err == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
bufferevent_unsuspend_write(bev, BEV_SUSPEND_LOOKUP);
|
||||
bufferevent_unsuspend_read(bev, BEV_SUSPEND_LOOKUP);
|
||||
return -1;
|
||||
}
|
||||
bufferevent_suspend_write_(bev, BEV_SUSPEND_LOOKUP);
|
||||
bufferevent_suspend_read_(bev, BEV_SUSPEND_LOOKUP);
|
||||
|
||||
bufferevent_incref_(bev);
|
||||
bev_p->dns_request = evutil_getaddrinfo_async_(evdns_base, hostname,
|
||||
portbuf, &hint, bufferevent_connect_getaddrinfo_cb, bev);
|
||||
BEV_UNLOCK(bev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -550,14 +575,12 @@ bufferevent_new(evutil_socket_t fd,
|
|||
static int
|
||||
be_socket_enable(struct bufferevent *bufev, short event)
|
||||
{
|
||||
if (event & EV_READ) {
|
||||
if (be_socket_add(&bufev->ev_read,&bufev->timeout_read) == -1)
|
||||
if (event & EV_READ &&
|
||||
bufferevent_add_event_(&bufev->ev_read, &bufev->timeout_read) == -1)
|
||||
return -1;
|
||||
}
|
||||
if (event & EV_WRITE) {
|
||||
if (be_socket_add(&bufev->ev_write,&bufev->timeout_write) == -1)
|
||||
if (event & EV_WRITE &&
|
||||
bufferevent_add_event_(&bufev->ev_write, &bufev->timeout_write) == -1)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -588,25 +611,10 @@ be_socket_destruct(struct bufferevent *bufev)
|
|||
|
||||
fd = event_get_fd(&bufev->ev_read);
|
||||
|
||||
event_del(&bufev->ev_read);
|
||||
event_del(&bufev->ev_write);
|
||||
|
||||
if ((bufev_p->options & BEV_OPT_CLOSE_ON_FREE) && fd >= 0)
|
||||
EVUTIL_CLOSESOCKET(fd);
|
||||
}
|
||||
|
||||
static int
|
||||
be_socket_adj_timeouts(struct bufferevent *bufev)
|
||||
{
|
||||
int r = 0;
|
||||
if (event_pending(&bufev->ev_read, EV_READ, NULL))
|
||||
if (be_socket_add(&bufev->ev_read, &bufev->timeout_read) < 0)
|
||||
r = -1;
|
||||
if (event_pending(&bufev->ev_write, EV_WRITE, NULL)) {
|
||||
if (be_socket_add(&bufev->ev_write, &bufev->timeout_write) < 0)
|
||||
r = -1;
|
||||
}
|
||||
return r;
|
||||
evutil_getaddrinfo_cancel_async_(bufev_p->dns_request);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -620,20 +628,28 @@ be_socket_flush(struct bufferevent *bev, short iotype,
|
|||
static void
|
||||
be_socket_setfd(struct bufferevent *bufev, evutil_socket_t fd)
|
||||
{
|
||||
struct bufferevent_private *bufev_p =
|
||||
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
|
||||
|
||||
BEV_LOCK(bufev);
|
||||
EVUTIL_ASSERT(bufev->be_ops == &bufferevent_ops_socket);
|
||||
|
||||
event_del(&bufev->ev_read);
|
||||
event_del(&bufev->ev_write);
|
||||
|
||||
evbuffer_unfreeze(bufev->input, 0);
|
||||
evbuffer_unfreeze(bufev->output, 1);
|
||||
|
||||
event_assign(&bufev->ev_read, bufev->ev_base, fd,
|
||||
EV_READ|EV_PERSIST, bufferevent_readcb, bufev);
|
||||
EV_READ|EV_PERSIST|EV_FINALIZE, bufferevent_readcb, bufev);
|
||||
event_assign(&bufev->ev_write, bufev->ev_base, fd,
|
||||
EV_WRITE|EV_PERSIST, bufferevent_writecb, bufev);
|
||||
EV_WRITE|EV_PERSIST|EV_FINALIZE, bufferevent_writecb, bufev);
|
||||
|
||||
if (fd >= 0)
|
||||
bufferevent_enable(bufev, bufev->enabled);
|
||||
|
||||
evutil_getaddrinfo_cancel_async_(bufev_p->dns_request);
|
||||
|
||||
BEV_UNLOCK(bufev);
|
||||
}
|
||||
|
||||
|
@ -642,6 +658,8 @@ int
|
|||
bufferevent_priority_set(struct bufferevent *bufev, int priority)
|
||||
{
|
||||
int r = -1;
|
||||
struct bufferevent_private *bufev_p =
|
||||
EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
|
||||
|
||||
BEV_LOCK(bufev);
|
||||
if (bufev->be_ops != &bufferevent_ops_socket)
|
||||
|
@ -652,6 +670,8 @@ bufferevent_priority_set(struct bufferevent *bufev, int priority)
|
|||
if (event_priority_set(&bufev->ev_write, priority) == -1)
|
||||
goto done;
|
||||
|
||||
event_deferred_cb_set_priority_(&bufev_p->deferred, priority);
|
||||
|
||||
r = 0;
|
||||
done:
|
||||
BEV_UNLOCK(bufev);
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _CHANGELIST_H_
|
||||
#define _CHANGELIST_H_
|
||||
#ifndef CHANGELIST_INTERNAL_H_INCLUDED_
|
||||
#define CHANGELIST_INTERNAL_H_INCLUDED_
|
||||
|
||||
/*
|
||||
A "changelist" is a list of all the fd status changes that should be made
|
||||
|
@ -62,6 +62,7 @@ struct event_change {
|
|||
* and write_change is unused. */
|
||||
ev_uint8_t read_change;
|
||||
ev_uint8_t write_change;
|
||||
ev_uint8_t close_change;
|
||||
};
|
||||
|
||||
/* Flags for read_change and write_change. */
|
||||
|
@ -82,20 +83,20 @@ struct event_change {
|
|||
#define EVENT_CHANGELIST_FDINFO_SIZE sizeof(int)
|
||||
|
||||
/** Set up the data fields in a changelist. */
|
||||
void event_changelist_init(struct event_changelist *changelist);
|
||||
void event_changelist_init_(struct event_changelist *changelist);
|
||||
/** Remove every change in the changelist, and make corresponding changes
|
||||
* in the event maps in the base. This function is generally used right
|
||||
* after making all the changes in the changelist. */
|
||||
void event_changelist_remove_all(struct event_changelist *changelist,
|
||||
void event_changelist_remove_all_(struct event_changelist *changelist,
|
||||
struct event_base *base);
|
||||
/** Free all memory held in a changelist. */
|
||||
void event_changelist_freemem(struct event_changelist *changelist);
|
||||
void event_changelist_freemem_(struct event_changelist *changelist);
|
||||
|
||||
/** Implementation of eventop_add that queues the event in a changelist. */
|
||||
int event_changelist_add(struct event_base *base, evutil_socket_t fd, short old, short events,
|
||||
int event_changelist_add_(struct event_base *base, evutil_socket_t fd, short old, short events,
|
||||
void *p);
|
||||
/** Implementation of eventop_del that queues the event in a changelist. */
|
||||
int event_changelist_del(struct event_base *base, evutil_socket_t fd, short old, short events,
|
||||
int event_changelist_del_(struct event_base *base, evutil_socket_t fd, short old, short events,
|
||||
void *p);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,299 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# TODO:
|
||||
# - inline replace
|
||||
# - clang-format-diff replacement
|
||||
# - uncrustify for patches (not git refs)
|
||||
# - maybe integrate into travis-ci?
|
||||
|
||||
function usage()
|
||||
{
|
||||
cat <<EOL
|
||||
$0 [ OPTS ] [ file-or-gitref [ ... ] ]
|
||||
|
||||
Example:
|
||||
# Chech HEAD git ref
|
||||
$ $0 -r
|
||||
$ $0 -r HEAD
|
||||
|
||||
# Check patch
|
||||
$ git format-patch --stdout -1 | $0 -p
|
||||
$ git show -1 | $0 -p
|
||||
|
||||
# Or via regular files
|
||||
$ git format-patch --stdout -2
|
||||
$ $0 *.patch
|
||||
|
||||
# Over a file
|
||||
$ $0 -d event.c
|
||||
$ $0 -d < event.c
|
||||
|
||||
# And print the whole file not only summary
|
||||
$ $0 -f event.c
|
||||
$ $0 -f < event.c
|
||||
|
||||
OPTS:
|
||||
-p - treat as patch
|
||||
-f - treat as regular file
|
||||
-f - treat as regular file and print diff
|
||||
-r - treat as git revision (default)
|
||||
-C - check using clang-format (default)
|
||||
-U - check with uncrustify
|
||||
-c - config for clang-format/uncrustify
|
||||
-h - print this message
|
||||
EOL
|
||||
}
|
||||
function cfg()
|
||||
{
|
||||
[ -z "${options[cfg]}" ] || {
|
||||
echo "${options[cfg]}"
|
||||
return
|
||||
}
|
||||
|
||||
local dir="$(dirname "${BASH_SOURCE[0]}")"
|
||||
[ "${options[clang]}" -eq 0 ] || {
|
||||
echo "$dir/.clang-format"
|
||||
return
|
||||
}
|
||||
[ "${options[uncrustify]}" -eq 0 ] || {
|
||||
echo "$dir/.uncrustify"
|
||||
return
|
||||
}
|
||||
}
|
||||
function abort()
|
||||
{
|
||||
local msg="$1"
|
||||
shift
|
||||
|
||||
printf "$msg\n" "$@" >&2
|
||||
exit 1
|
||||
}
|
||||
function default_arg()
|
||||
{
|
||||
if [ "${options[ref]}" -eq 1 ]; then
|
||||
echo "HEAD"
|
||||
else
|
||||
[ ! -t 0 ] || abort "<stdin> is a tty"
|
||||
echo "/dev/stdin"
|
||||
fi
|
||||
}
|
||||
function parse_options()
|
||||
{
|
||||
options[patch]=0
|
||||
options[file]=0
|
||||
options[file_diff]=0
|
||||
options[ref]=1
|
||||
options[clang]=1
|
||||
options[uncrustify]=0
|
||||
options[cfg]=
|
||||
|
||||
local OPTARG OPTIND c
|
||||
while getopts "pfrdCUc:h?" c; do
|
||||
case "$c" in
|
||||
p)
|
||||
options[patch]=1
|
||||
options[ref]=0
|
||||
options[file]=0
|
||||
options[file_diff]=0
|
||||
;;
|
||||
f)
|
||||
options[file]=1
|
||||
options[ref]=0
|
||||
options[patch]=0
|
||||
options[file_diff]=0
|
||||
;;
|
||||
r)
|
||||
options[ref]=1
|
||||
options[file]=0
|
||||
options[patch]=0
|
||||
options[file_diff]=0
|
||||
;;
|
||||
d)
|
||||
options[file_diff]=1
|
||||
options[file]=0
|
||||
options[patch]=0
|
||||
options[ref]=0
|
||||
;;
|
||||
C)
|
||||
options[clang]=1
|
||||
options[uncrustify]=0
|
||||
;;
|
||||
U)
|
||||
options[uncrustify]=1
|
||||
options[clang]=0
|
||||
;;
|
||||
c) options[cfg]="$OPTIND" ;;
|
||||
?|h)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
options[cfg]="$(cfg)"
|
||||
|
||||
[ -f "${options[cfg]}" ] || \
|
||||
abort "Config '%s' does not exist" "${options[cfg]}"
|
||||
|
||||
shift $((OPTIND - 1))
|
||||
args=( "$@" )
|
||||
|
||||
if [ ${#args[@]} -eq 0 ]; then
|
||||
# exit on error globally, not only in subshell
|
||||
default_arg > /dev/null
|
||||
args=( "$(default_arg)" )
|
||||
fi
|
||||
|
||||
if [ "${args[0]}" = "/dev/stdin" ]; then
|
||||
TMP_FILE="/tmp/libevent.checkpatch.$RANDOM"
|
||||
cat > "$TMP_FILE"
|
||||
trap "rm '$TMP_FILE'" EXIT
|
||||
|
||||
args[0]="$TMP_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
function diff() { command diff --color=always "$@"; }
|
||||
|
||||
function clang_style()
|
||||
{
|
||||
local c="${options[cfg]}"
|
||||
echo "{ $(sed -e 's/#.*//' -e '/---/d' -e '/\.\.\./d' "$c" | tr $'\n' ,) }"
|
||||
}
|
||||
function clang_format() { clang-format --style="$(clang_style)" "$@"; }
|
||||
function clang_format_diff() { clang-format-diff --style="$(clang_style)" "$@"; }
|
||||
# for non-bare repo will work
|
||||
function clang_format_git()
|
||||
{ git format-patch --stdout "$@" -1 | clang_format_diff; }
|
||||
|
||||
function uncrustify() { command uncrustify -c "${options[cfg]}" "$@"; }
|
||||
function uncrustify_frag() { uncrustify -l C --frag "$@"; }
|
||||
function uncrustify_indent_off() { echo '/* *INDENT-OFF* */'; }
|
||||
function uncrustify_indent_on() { echo '/* *INDENT-ON* */'; }
|
||||
function git_hunk()
|
||||
{
|
||||
local ref=$1 f=$2
|
||||
shift 2
|
||||
git cat-file -p $ref:$f
|
||||
}
|
||||
function uncrustify_git_indent_hunk()
|
||||
{
|
||||
local start=$1 end=$2
|
||||
shift 2
|
||||
|
||||
# Will be beatier with tee(1), but doh bash async substitution
|
||||
{ uncrustify_indent_off; git_hunk "$@" | head -n$((start - 1)); }
|
||||
{ uncrustify_indent_on; git_hunk "$@" | head -n$((end - 1)) | tail -n+$start; }
|
||||
{ uncrustify_indent_off; git_hunk "$@" | tail -n+$((end + 1)); }
|
||||
}
|
||||
function strip()
|
||||
{
|
||||
local start=$1 end=$2
|
||||
shift 2
|
||||
|
||||
# seek indent_{on,off}()
|
||||
let start+=2
|
||||
head -n$end | tail -n+$start
|
||||
}
|
||||
function patch_ranges()
|
||||
{
|
||||
egrep -o '^@@ -[0-9]+(,[0-9]+|) \+[0-9]+(,[0-9]+|) @@' | \
|
||||
cut -d' ' -f3
|
||||
}
|
||||
function git_ranges()
|
||||
{
|
||||
local ref=$1 f=$2
|
||||
shift 2
|
||||
|
||||
git diff -W $ref^..$ref -- $f | patch_ranges
|
||||
}
|
||||
function diff_substitute()
|
||||
{
|
||||
local f="$1"
|
||||
shift
|
||||
|
||||
sed \
|
||||
-e "s#^--- /dev/fd.*\$#--- a/$f#" \
|
||||
-e "s#^+++ /dev/fd.*\$#+++ b/$f#"
|
||||
}
|
||||
function uncrustify_git()
|
||||
{
|
||||
local ref=$1 r f start end length
|
||||
shift
|
||||
|
||||
local files=( $(git diff --name-only $ref^..$ref | egrep "\.(c|h)$") )
|
||||
for f in "${files[@]}"; do
|
||||
local ranges=( $(git_ranges $ref "$f") )
|
||||
for r in "${ranges[@]}"; do
|
||||
[[ ! "$r" =~ ^\+([0-9]+)(,([0-9]+)|)$ ]] && continue
|
||||
start=${BASH_REMATCH[1]}
|
||||
[ -n "${BASH_REMATCH[3]}" ] && \
|
||||
length=${BASH_REMATCH[3]} || \
|
||||
length=1
|
||||
end=$((start + length))
|
||||
echo "Range: $start:$end ($length)" >&2
|
||||
|
||||
diff -u \
|
||||
<(uncrustify_git_indent_hunk $start $end $ref "$f" | strip $start $end) \
|
||||
<(uncrustify_git_indent_hunk $start $end $ref "$f" | uncrustify_frag | strip $start $end) \
|
||||
| diff_substitute "$f"
|
||||
done
|
||||
done
|
||||
}
|
||||
function uncrustify_diff() { abort "Not implemented"; }
|
||||
function uncrustify_file() { uncrustify -f "$@"; }
|
||||
|
||||
function checker()
|
||||
{
|
||||
local c=$1 u=$2
|
||||
shift 2
|
||||
|
||||
[ "${options[clang]}" -eq 0 ] || {
|
||||
$c "$@"
|
||||
return
|
||||
}
|
||||
[ "${options[uncrustify]}" -eq 0 ] || {
|
||||
$u "$@"
|
||||
return
|
||||
}
|
||||
}
|
||||
function check_patch() { checker clang_format_diff uncrustify_diff "$@"; }
|
||||
function check_file() { checker clang_format uncrustify_file "$@"; }
|
||||
function check_ref() { checker clang_format_git uncrustify_git "$@"; }
|
||||
|
||||
function check_arg()
|
||||
{
|
||||
[ "${options[patch]}" -eq 0 ] || {
|
||||
check_patch "$@"
|
||||
return
|
||||
}
|
||||
[ "${options[file]}" -eq 0 ] || {
|
||||
check_file "$@"
|
||||
return
|
||||
}
|
||||
[ "${options[file_diff]}" -eq 0 ] || {
|
||||
diff -u "$@" <(check_file "$@") | diff_substitute "$@"
|
||||
return
|
||||
}
|
||||
[ "${options[ref]}" -eq 0 ] || {
|
||||
check_ref "$@"
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
function main()
|
||||
{
|
||||
local a
|
||||
for a in "${args}"; do
|
||||
check_arg "$a"
|
||||
done
|
||||
}
|
||||
|
||||
declare -A options
|
||||
parse_options "$@"
|
||||
|
||||
main "$@" | less -FRSX
|
|
@ -0,0 +1,13 @@
|
|||
include(CheckCCompilerFlag)
|
||||
|
||||
macro(add_compiler_flags)
|
||||
foreach(flag ${ARGN})
|
||||
string(REGEX REPLACE "[-.+/:= ]" "_" _flag_esc "${flag}")
|
||||
|
||||
check_c_compiler_flag("${flag}" check_c_compiler_flag_${_flag_esc})
|
||||
|
||||
if (check_c_compiler_flag_${_flag_esc})
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}")
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
|
@ -0,0 +1,22 @@
|
|||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,14 @@
|
|||
#include <sys/types.h>
|
||||
|
||||
#define KB ((off_t)1024)
|
||||
#define MB ((off_t)1024 * KB)
|
||||
#define GB ((off_t)1024 * MB)
|
||||
#define TB ((off_t)1024 * GB)
|
||||
int t2[(((64 * GB -1) % 671088649) == 268434537)
|
||||
&& (((TB - (64 * GB -1) + 255) % 1792151290) == 305159546)? 1: -1];
|
||||
|
||||
int main()
|
||||
{
|
||||
;
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
# - Check if _FILE_OFFSET_BITS macro needed for large files
|
||||
# CHECK_FILE_OFFSET_BITS ()
|
||||
#
|
||||
# The following variables may be set before calling this macro to
|
||||
# modify the way the check is run:
|
||||
#
|
||||
# CMAKE_REQUIRED_FLAGS = string of compile command line flags
|
||||
# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
|
||||
# CMAKE_REQUIRED_INCLUDES = list of include directories
|
||||
# Copyright (c) 2009, Michihiro NAKAJIMA
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
#INCLUDE(CheckCSourceCompiles)
|
||||
|
||||
GET_FILENAME_COMPONENT(_selfdir_CheckFileOffsetBits
|
||||
"${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
|
||||
MACRO (CHECK_FILE_OFFSET_BITS)
|
||||
IF(NOT DEFINED _FILE_OFFSET_BITS)
|
||||
MESSAGE(STATUS "Cheking _FILE_OFFSET_BITS for large files")
|
||||
TRY_COMPILE(__WITHOUT_FILE_OFFSET_BITS_64
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${_selfdir_CheckFileOffsetBits}/CheckFileOffsetBits.c
|
||||
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS})
|
||||
IF(NOT __WITHOUT_FILE_OFFSET_BITS_64)
|
||||
TRY_COMPILE(__WITH_FILE_OFFSET_BITS_64
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${_selfdir_CheckFileOffsetBits}/CheckFileOffsetBits.c
|
||||
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} -D_FILE_OFFSET_BITS=64)
|
||||
ENDIF(NOT __WITHOUT_FILE_OFFSET_BITS_64)
|
||||
|
||||
IF(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64)
|
||||
SET(_FILE_OFFSET_BITS 64 CACHE INTERNAL "_FILE_OFFSET_BITS macro needed for large files")
|
||||
MESSAGE(STATUS "Cheking _FILE_OFFSET_BITS for large files - needed")
|
||||
ELSE(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64)
|
||||
SET(_FILE_OFFSET_BITS "" CACHE INTERNAL "_FILE_OFFSET_BITS macro needed for large files")
|
||||
MESSAGE(STATUS "Cheking _FILE_OFFSET_BITS for large files - not needed")
|
||||
ENDIF(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64)
|
||||
ENDIF(NOT DEFINED _FILE_OFFSET_BITS)
|
||||
|
||||
ENDMACRO (CHECK_FILE_OFFSET_BITS)
|
|
@ -0,0 +1,30 @@
|
|||
#ifdef CHECK_FUNCTION_EXISTS
|
||||
|
||||
#ifndef _WIN32
|
||||
char CHECK_FUNCTION_EXISTS();
|
||||
#endif
|
||||
|
||||
#ifdef __CLASSIC_C__
|
||||
int main(){
|
||||
int ac;
|
||||
char*av[];
|
||||
#else
|
||||
int main(int ac, char*av[]){
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
void * p = &CHECK_FUNCTION_EXISTS;
|
||||
#else
|
||||
CHECK_FUNCTION_EXISTS();
|
||||
#endif
|
||||
if(ac > 1000)
|
||||
{
|
||||
return *av[0];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* CHECK_FUNCTION_EXISTS */
|
||||
|
||||
# error "CHECK_FUNCTION_EXISTS has to specify the function"
|
||||
|
||||
#endif /* CHECK_FUNCTION_EXISTS */
|
|
@ -0,0 +1,69 @@
|
|||
# - Check if a C function can be linked
|
||||
# CHECK_FUNCTION_EXISTS(<function> <variable>)
|
||||
#
|
||||
# Check that the <function> is provided by libraries on the system and
|
||||
# store the result in a <variable>. This does not verify that any
|
||||
# system header file declares the function, only that it can be found
|
||||
# at link time (considure using CheckSymbolExists).
|
||||
#
|
||||
# The following variables may be set before calling this macro to
|
||||
# modify the way the check is run:
|
||||
#
|
||||
# CMAKE_REQUIRED_FLAGS = string of compile command line flags
|
||||
# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
|
||||
# CMAKE_REQUIRED_INCLUDES = list of include directories
|
||||
# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2002-2011 Kitware, Inc.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
MACRO(CHECK_FUNCTION_EXISTS_EX FUNCTION VARIABLE)
|
||||
IF(${VARIABLE} MATCHES "^${VARIABLE}$")
|
||||
SET(MACRO_CHECK_FUNCTION_DEFINITIONS
|
||||
"-DCHECK_FUNCTION_EXISTS=${FUNCTION} ${CMAKE_REQUIRED_FLAGS}")
|
||||
MESSAGE(STATUS "Looking for ${FUNCTION}")
|
||||
IF(CMAKE_REQUIRED_LIBRARIES)
|
||||
SET(CHECK_FUNCTION_EXISTS_ADD_LIBRARIES
|
||||
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
|
||||
ELSE(CMAKE_REQUIRED_LIBRARIES)
|
||||
SET(CHECK_FUNCTION_EXISTS_ADD_LIBRARIES)
|
||||
ENDIF(CMAKE_REQUIRED_LIBRARIES)
|
||||
IF(CMAKE_REQUIRED_INCLUDES)
|
||||
SET(CHECK_FUNCTION_EXISTS_ADD_INCLUDES
|
||||
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
|
||||
ELSE(CMAKE_REQUIRED_INCLUDES)
|
||||
SET(CHECK_FUNCTION_EXISTS_ADD_INCLUDES)
|
||||
ENDIF(CMAKE_REQUIRED_INCLUDES)
|
||||
TRY_COMPILE(${VARIABLE}
|
||||
${CMAKE_BINARY_DIR}
|
||||
${PROJECT_SOURCE_DIR}/cmake/CheckFunctionExistsEx.c
|
||||
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
|
||||
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
|
||||
"${CHECK_FUNCTION_EXISTS_ADD_LIBRARIES}"
|
||||
"${CHECK_FUNCTION_EXISTS_ADD_INCLUDES}"
|
||||
OUTPUT_VARIABLE OUTPUT)
|
||||
IF(${VARIABLE})
|
||||
SET(${VARIABLE} 1 CACHE INTERNAL "Have function ${FUNCTION}")
|
||||
MESSAGE(STATUS "Looking for ${FUNCTION} - found")
|
||||
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
|
||||
"Determining if the function ${FUNCTION} exists passed with the following output:\n"
|
||||
"${OUTPUT}\n\n")
|
||||
ELSE(${VARIABLE})
|
||||
MESSAGE(STATUS "Looking for ${FUNCTION} - not found")
|
||||
SET(${VARIABLE} "" CACHE INTERNAL "Have function ${FUNCTION}")
|
||||
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
|
||||
"Determining if the function ${FUNCTION} exists failed with the following output:\n"
|
||||
"${OUTPUT}\n\n")
|
||||
ENDIF(${VARIABLE})
|
||||
ENDIF()
|
||||
ENDMACRO(CHECK_FUNCTION_EXISTS_EX)
|
|
@ -0,0 +1,14 @@
|
|||
include(CheckCSourceCompiles)
|
||||
|
||||
macro(check_function_keywords _wordlist)
|
||||
set(${_result} "")
|
||||
foreach(flag ${_wordlist})
|
||||
string(REGEX REPLACE "[-+/ ()]" "_" flagname "${flag}")
|
||||
string(TOUPPER "${flagname}" flagname)
|
||||
set(have_flag "HAVE_${flagname}")
|
||||
check_c_source_compiles("${flag} void func(); void func() { } int main() { func(); return 0; }" ${have_flag})
|
||||
if(${have_flag} AND NOT ${_result})
|
||||
set(${_result} "${flag}")
|
||||
endif(${have_flag} AND NOT ${_result})
|
||||
endforeach(flag)
|
||||
endmacro(check_function_keywords)
|
29
ipc/chromium/src/third_party/libevent/cmake/CheckPrototypeDefinition.c.in
поставляемый
Normal file
29
ipc/chromium/src/third_party/libevent/cmake/CheckPrototypeDefinition.c.in
поставляемый
Normal file
|
@ -0,0 +1,29 @@
|
|||
@CHECK_PROTOTYPE_DEFINITION_HEADER@
|
||||
|
||||
static void cmakeRequireSymbol(int dummy, ...) {
|
||||
(void) dummy;
|
||||
}
|
||||
|
||||
static void checkSymbol(void) {
|
||||
#ifndef @CHECK_PROTOTYPE_DEFINITION_SYMBOL@
|
||||
cmakeRequireSymbol(0, &@CHECK_PROTOTYPE_DEFINITION_SYMBOL@);
|
||||
#endif
|
||||
}
|
||||
|
||||
@CHECK_PROTOTYPE_DEFINITION_PROTO@ {
|
||||
return @CHECK_PROTOTYPE_DEFINITION_RETURN@;
|
||||
}
|
||||
|
||||
#ifdef __CLASSIC_C__
|
||||
int main() {
|
||||
int ac;
|
||||
char*av[];
|
||||
#else
|
||||
int main(int ac, char *av[]) {
|
||||
#endif
|
||||
checkSymbol();
|
||||
if (ac > 1000) {
|
||||
return *av[0];
|
||||
}
|
||||
return 0;
|
||||
}
|
82
ipc/chromium/src/third_party/libevent/cmake/CheckPrototypeDefinition.cmake
поставляемый
Normal file
82
ipc/chromium/src/third_party/libevent/cmake/CheckPrototypeDefinition.cmake
поставляемый
Normal file
|
@ -0,0 +1,82 @@
|
|||
# - Check if the protoype we expect is correct.
|
||||
# check_prototype_definition(FUNCTION PROTOTYPE RETURN HEADER VARIABLE)
|
||||
#
|
||||
# FUNCTION - The name of the function (used to check if prototype exists)
|
||||
# PROTOTYPE- The prototype to check.
|
||||
# RETURN - The return value of the function.
|
||||
# HEADER - The header files required.
|
||||
# VARIABLE - The variable to store the result.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# check_prototype_definition(getpwent_r
|
||||
# "struct passwd *getpwent_r(struct passwd *src, char *buf, int buflen)"
|
||||
# "NULL"
|
||||
# "unistd.h;pwd.h"
|
||||
# SOLARIS_GETPWENT_R)
|
||||
#
|
||||
# The following variables may be set before calling this macro to
|
||||
# modify the way the check is run:
|
||||
#
|
||||
# CMAKE_REQUIRED_FLAGS = string of compile command line flags
|
||||
# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
|
||||
# CMAKE_REQUIRED_INCLUDES = list of include directories
|
||||
# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
|
||||
|
||||
|
||||
function(CHECK_PROTOTYPE_DEFINITION _FUNCTION _PROTOTYPE _RETURN _HEADER _VARIABLE)
|
||||
if (${_VARIABLE} MATCHES "^${_VARIABLE}$")
|
||||
set(CHECK_PROTOTYPE_DEFINITION_CONTENT "/* */\n")
|
||||
|
||||
set(CHECK_PROTOTYPE_DEFINITION_FLAGS ${CMAKE_REQUIRED_FLAGS})
|
||||
if (CMAKE_REQUIRED_LIBRARIES)
|
||||
set(CHECK_PROTOTYPE_DEFINITION_LIBS
|
||||
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
|
||||
else(CMAKE_REQUIRED_LIBRARIES)
|
||||
set(CHECK_PROTOTYPE_DEFINITION_LIBS)
|
||||
endif(CMAKE_REQUIRED_LIBRARIES)
|
||||
if (CMAKE_REQUIRED_INCLUDES)
|
||||
set(CMAKE_SYMBOL_EXISTS_INCLUDES
|
||||
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
|
||||
else(CMAKE_REQUIRED_INCLUDES)
|
||||
set(CMAKE_SYMBOL_EXISTS_INCLUDES)
|
||||
endif(CMAKE_REQUIRED_INCLUDES)
|
||||
|
||||
foreach(_FILE ${_HEADER})
|
||||
set(CHECK_PROTOTYPE_DEFINITION_HEADER
|
||||
"${CHECK_PROTOTYPE_DEFINITION_HEADER}#include <${_FILE}>\n")
|
||||
endforeach(_FILE)
|
||||
|
||||
set(CHECK_PROTOTYPE_DEFINITION_SYMBOL ${_FUNCTION})
|
||||
set(CHECK_PROTOTYPE_DEFINITION_PROTO ${_PROTOTYPE})
|
||||
set(CHECK_PROTOTYPE_DEFINITION_RETURN ${_RETURN})
|
||||
|
||||
configure_file("${PROJECT_SOURCE_DIR}/cmake/CheckPrototypeDefinition.c.in"
|
||||
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckPrototypeDefinition.c" @ONLY)
|
||||
|
||||
file(READ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckPrototypeDefinition.c _SOURCE)
|
||||
|
||||
try_compile(${_VARIABLE}
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckPrototypeDefinition.c
|
||||
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
|
||||
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CHECK_PROTOTYPE_DEFINITION_FLAGS}
|
||||
"${CHECK_PROTOTYPE_DEFINITION_LIBS}"
|
||||
"${CMAKE_SYMBOL_EXISTS_INCLUDES}"
|
||||
OUTPUT_VARIABLE OUTPUT)
|
||||
|
||||
if (${_VARIABLE})
|
||||
set(${_VARIABLE} 1 CACHE INTERNAL "Have correct prototype for ${_FUNCTION}")
|
||||
message(STATUS "Checking prototype ${_FUNCTION} for ${_VARIABLE} - True")
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
|
||||
"Determining if the prototype ${_FUNCTION} exists for ${_VARIABLE} passed with the following output:\n"
|
||||
"${OUTPUT}\n\n")
|
||||
else (${_VARIABLE})
|
||||
message(STATUS "Checking prototype ${_FUNCTION} for ${_VARIABLE} - False")
|
||||
set(${_VARIABLE} 0 CACHE INTERNAL "Have correct prototype for ${_FUNCTION}")
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
|
||||
"Determining if the prototype ${_FUNCTION} exists for ${_VARIABLE} failed with the following output:\n"
|
||||
"${OUTPUT}\n\n${_SOURCE}\n\n")
|
||||
endif (${_VARIABLE})
|
||||
endif()
|
||||
endfunction(CHECK_PROTOTYPE_DEFINITION)
|
18
ipc/chromium/src/third_party/libevent/cmake/CheckWaitpidSupportWNOWAIT.cmake
поставляемый
Normal file
18
ipc/chromium/src/third_party/libevent/cmake/CheckWaitpidSupportWNOWAIT.cmake
поставляемый
Normal file
|
@ -0,0 +1,18 @@
|
|||
include(CheckCSourceRuns)
|
||||
|
||||
check_c_source_runs(
|
||||
"
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
pid_t pid;
|
||||
int status;
|
||||
if ((pid = fork()) == 0) _exit(0);
|
||||
_exit(waitpid(pid, &status, WNOWAIT) == -1);
|
||||
}"
|
||||
EVENT__HAVE_WAITPID_WITH_WNOWAIT)
|
|
@ -0,0 +1,52 @@
|
|||
include(CheckCSourceRuns)
|
||||
|
||||
check_c_source_runs(
|
||||
"
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/event.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int kq;
|
||||
int n;
|
||||
int fd[2];
|
||||
struct kevent ev;
|
||||
struct timespec ts;
|
||||
char buf[8000];
|
||||
|
||||
if (pipe(fd) == -1)
|
||||
exit(1);
|
||||
if (fcntl(fd[1], F_SETFL, O_NONBLOCK) == -1)
|
||||
exit(1);
|
||||
|
||||
while ((n = write(fd[1], buf, sizeof(buf))) == sizeof(buf))
|
||||
;
|
||||
|
||||
if ((kq = kqueue()) == -1)
|
||||
exit(1);
|
||||
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
ev.ident = fd[1];
|
||||
ev.filter = EVFILT_WRITE;
|
||||
ev.flags = EV_ADD | EV_ENABLE;
|
||||
n = kevent(kq, &ev, 1, NULL, 0, NULL);
|
||||
if (n == -1)
|
||||
exit(1);
|
||||
|
||||
read(fd[0], buf, sizeof(buf));
|
||||
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 0;
|
||||
n = kevent(kq, NULL, 0, &ev, 1, &ts);
|
||||
if (n == -1 || n == 0)
|
||||
exit(1);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
" EVENT__HAVE_WORKING_KQUEUE)
|
|
@ -0,0 +1,165 @@
|
|||
#
|
||||
# Boost Software License - Version 1.0 - August 17th, 2003
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person or organization
|
||||
# obtaining a copy of the software and accompanying documentation covered by
|
||||
# this license (the "Software") to use, reproduce, display, distribute,
|
||||
# execute, and transmit the Software, and to prepare derivative works of the
|
||||
# Software, and to permit third-parties to whom the Software is furnished to
|
||||
# do so, all subject to the following:
|
||||
#
|
||||
# The copyright notices in the Software and this entire statement, including
|
||||
# the above license grant, this restriction and the following disclaimer,
|
||||
# must be included in all copies of the Software, in whole or in part, and
|
||||
# all derivative works of the Software, unless such copies or derivative
|
||||
# works are solely in the form of machine-executable object code generated by
|
||||
# a source language processor.
|
||||
#
|
||||
# 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
# SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
# FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# 2012-01-31, Lars Bilke
|
||||
# - Enable Code Coverage
|
||||
#
|
||||
# 2013-09-17, Joakim Söderberg
|
||||
# - Added support for Clang.
|
||||
# - Some additional usage instructions.
|
||||
#
|
||||
# 2016-11-02, Azat Khuzhin
|
||||
# - Adopt for C compiler only (libevent)
|
||||
#
|
||||
# USAGE:
|
||||
# 1. Copy this file into your cmake modules path.
|
||||
#
|
||||
# 2. Add the following line to your CMakeLists.txt:
|
||||
# INCLUDE(CodeCoverage)
|
||||
#
|
||||
# 3. Set compiler flags to turn off optimization and enable coverage:
|
||||
# SET(CMAKE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
|
||||
# SET(CMAKE_C_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
|
||||
#
|
||||
# 3. Use the function SETUP_TARGET_FOR_COVERAGE to create a custom make target
|
||||
# which runs your test executable and produces a lcov code coverage report:
|
||||
# Example:
|
||||
# SETUP_TARGET_FOR_COVERAGE(
|
||||
# my_coverage_target # Name for custom target.
|
||||
# test_driver # Name of the test driver executable that runs the tests.
|
||||
# # NOTE! This should always have a ZERO as exit code
|
||||
# # otherwise the coverage generation will not complete.
|
||||
# coverage # Name of output directory.
|
||||
# )
|
||||
#
|
||||
# 4. Build a Debug build:
|
||||
# cmake -DCMAKE_BUILD_TYPE=Debug ..
|
||||
# make
|
||||
# make my_coverage_target
|
||||
#
|
||||
#
|
||||
|
||||
# Check prereqs
|
||||
FIND_PROGRAM( GCOV_PATH gcov )
|
||||
FIND_PROGRAM( LCOV_PATH lcov )
|
||||
FIND_PROGRAM( GENHTML_PATH genhtml )
|
||||
FIND_PROGRAM( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/tests)
|
||||
|
||||
IF(NOT GCOV_PATH)
|
||||
MESSAGE(FATAL_ERROR "gcov not found! Aborting...")
|
||||
ENDIF() # NOT GCOV_PATH
|
||||
|
||||
IF(NOT CMAKE_COMPILER_IS_GNUCC)
|
||||
# Clang version 3.0.0 and greater now supports gcov as well.
|
||||
MESSAGE(WARNING "Compiler is not GNU gcc! Clang Version 3.0.0 and greater supports gcov as well, but older versions don't.")
|
||||
|
||||
IF(NOT "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
|
||||
MESSAGE(FATAL_ERROR "Compiler is not GNU gcc! Aborting...")
|
||||
ENDIF()
|
||||
ENDIF() # NOT CMAKE_COMPILER_IS_GNUCC
|
||||
|
||||
IF ( NOT CMAKE_BUILD_TYPE STREQUAL "Debug" )
|
||||
MESSAGE( WARNING "Code coverage results with an optimized (non-Debug) build may be misleading" )
|
||||
ENDIF() # NOT CMAKE_BUILD_TYPE STREQUAL "Debug"
|
||||
|
||||
|
||||
# Param _targetname The name of new the custom make target
|
||||
# Param _testrunner The name of the target which runs the tests.
|
||||
# MUST return ZERO always, even on errors.
|
||||
# If not, no coverage report will be created!
|
||||
# Param _outputname lcov output is generated as _outputname.info
|
||||
# HTML report is generated in _outputname/index.html
|
||||
# Optional fourth parameter is passed as arguments to _testrunner
|
||||
# Pass them in list form, e.g.: "-j;2" for -j 2
|
||||
FUNCTION(SETUP_TARGET_FOR_COVERAGE _targetname _testrunner _outputname)
|
||||
|
||||
IF(NOT LCOV_PATH)
|
||||
MESSAGE(FATAL_ERROR "lcov not found! Aborting...")
|
||||
ENDIF() # NOT LCOV_PATH
|
||||
|
||||
IF(NOT GENHTML_PATH)
|
||||
MESSAGE(FATAL_ERROR "genhtml not found! Aborting...")
|
||||
ENDIF() # NOT GENHTML_PATH
|
||||
|
||||
# Setup target
|
||||
ADD_CUSTOM_TARGET(${_targetname}
|
||||
|
||||
# Cleanup lcov
|
||||
${LCOV_PATH} --directory . --zerocounters
|
||||
|
||||
# Run tests
|
||||
COMMAND ${_testrunner} ${ARGV3}
|
||||
|
||||
# Capturing lcov counters and generating report
|
||||
COMMAND ${LCOV_PATH} --directory . --capture --output-file ${_outputname}.info
|
||||
COMMAND ${LCOV_PATH} --remove ${_outputname}.info 'tests/*' '/usr/*' --output-file ${_outputname}.info.cleaned
|
||||
COMMAND ${GENHTML_PATH} -o ${_outputname} ${_outputname}.info.cleaned
|
||||
COMMAND ${CMAKE_COMMAND} -E remove ${_outputname}.info ${_outputname}.info.cleaned
|
||||
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report."
|
||||
)
|
||||
|
||||
# Show info where to find the report
|
||||
ADD_CUSTOM_COMMAND(TARGET ${_targetname} POST_BUILD
|
||||
COMMAND ;
|
||||
COMMENT "Open ./${_outputname}/index.html in your browser to view the coverage report."
|
||||
)
|
||||
|
||||
ENDFUNCTION() # SETUP_TARGET_FOR_COVERAGE
|
||||
|
||||
# Param _targetname The name of new the custom make target
|
||||
# Param _testrunner The name of the target which runs the tests
|
||||
# Param _outputname cobertura output is generated as _outputname.xml
|
||||
# Optional fourth parameter is passed as arguments to _testrunner
|
||||
# Pass them in list form, e.g.: "-j;2" for -j 2
|
||||
FUNCTION(SETUP_TARGET_FOR_COVERAGE_COBERTURA _targetname _testrunner _outputname)
|
||||
|
||||
IF(NOT PYTHON_EXECUTABLE)
|
||||
MESSAGE(FATAL_ERROR "Python not found! Aborting...")
|
||||
ENDIF() # NOT PYTHON_EXECUTABLE
|
||||
|
||||
IF(NOT GCOVR_PATH)
|
||||
MESSAGE(FATAL_ERROR "gcovr not found! Aborting...")
|
||||
ENDIF() # NOT GCOVR_PATH
|
||||
|
||||
ADD_CUSTOM_TARGET(${_targetname}
|
||||
|
||||
# Run tests
|
||||
${_testrunner} ${ARGV3}
|
||||
|
||||
# Running gcovr
|
||||
COMMAND ${GCOVR_PATH} -x -r ${CMAKE_SOURCE_DIR} -e '${CMAKE_SOURCE_DIR}/tests/' -o ${_outputname}.xml
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMENT "Running gcovr to produce Cobertura code coverage report."
|
||||
)
|
||||
|
||||
# Show info where to find the report
|
||||
ADD_CUSTOM_COMMAND(TARGET ${_targetname} POST_BUILD
|
||||
COMMAND ;
|
||||
COMMENT "Cobertura code coverage report saved in ${_outputname}.xml."
|
||||
)
|
||||
|
||||
ENDFUNCTION() # SETUP_TARGET_FOR_COVERAGE_COBERTURA
|
|
@ -0,0 +1,57 @@
|
|||
CMake - Cross Platform Makefile Generator
|
||||
Copyright 2000-2013 Kitware, Inc.
|
||||
Copyright 2000-2011 Insight Software Consortium
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the names of Kitware, Inc., the Insight Software Consortium,
|
||||
nor the names of their contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
The above copyright and license notice applies to distributions of
|
||||
CMake in source and binary form. Some source files contain additional
|
||||
notices of original copyright by their contributors; see each source
|
||||
for details. Third-party software packages supplied with CMake under
|
||||
compatible licenses provide their own copyright notices documented in
|
||||
corresponding subdirectories.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
CMake was initially developed by Kitware with the following sponsorship:
|
||||
|
||||
* National Library of Medicine at the National Institutes of Health
|
||||
as part of the Insight Segmentation and Registration Toolkit (ITK).
|
||||
|
||||
* US National Labs (Los Alamos, Livermore, Sandia) ASC Parallel
|
||||
Visualization Initiative.
|
||||
|
||||
* National Alliance for Medical Image Computing (NAMIC) is funded by the
|
||||
National Institutes of Health through the NIH Roadmap for Medical Research,
|
||||
Grant U54 EB005149.
|
||||
|
||||
* Kitware, Inc.
|
|
@ -0,0 +1,45 @@
|
|||
# The module defines the following variables:
|
||||
# GIT_EXECUTABLE - path to git command line client
|
||||
# GIT_FOUND - true if the command line client was found
|
||||
# Example usage:
|
||||
# find_package(Git)
|
||||
# if(GIT_FOUND)
|
||||
# message("git found: ${GIT_EXECUTABLE}")
|
||||
# endif()
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2010 Kitware, Inc.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distributed this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
# Look for 'git' or 'eg' (easy git)
|
||||
set(git_names git eg)
|
||||
|
||||
# Prefer .cmd variants on Windows unless running in a Makefile
|
||||
# in the MSYS shell.
|
||||
if(WIN32)
|
||||
if(NOT CMAKE_GENERATOR MATCHES "MSYS")
|
||||
set(git_names git.cmd git eg.cmd eg)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_program(GIT_EXECUTABLE
|
||||
NAMES ${git_names}
|
||||
DOC "git command line client")
|
||||
|
||||
mark_as_advanced(GIT_EXECUTABLE)
|
||||
|
||||
# Handle the QUIETLY and REQUIRED arguments and set GIT_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Git DEFAULT_MSG GIT_EXECUTABLE)
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# - Config file for the Libevent package
|
||||
# It defines the following variables
|
||||
# LIBEVENT_INCLUDE_DIRS - include directories for FooBar
|
||||
# LIBEVENT_LIBRARIES - libraries to link against
|
||||
|
||||
# Get the path of the current file.
|
||||
get_filename_component(LIBEVENT_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
|
||||
# Set the include directories.
|
||||
set(LIBEVENT_INCLUDE_DIRS "@EVENT_INSTALL_INCLUDE_DIR@")
|
||||
|
||||
# Include the project Targets file, this contains definitions for IMPORTED targets.
|
||||
include(${LIBEVENT_CMAKE_DIR}/LibeventTargets.cmake)
|
||||
|
||||
# IMPORTED targets from LibeventTargets.cmake
|
||||
set(LIBEVENT_LIBRARIES event event_core event_extra)
|
||||
|
17
ipc/chromium/src/third_party/libevent/cmake/LibeventConfigBuildTree.cmake.in
поставляемый
Normal file
17
ipc/chromium/src/third_party/libevent/cmake/LibeventConfigBuildTree.cmake.in
поставляемый
Normal file
|
@ -0,0 +1,17 @@
|
|||
# - Config file for the Libevent package
|
||||
# It defines the following variables
|
||||
# LIBEVENT_INCLUDE_DIRS - include directories for FooBar
|
||||
# LIBEVENT_LIBRARIES - libraries to link against
|
||||
|
||||
# Get the path of the current file.
|
||||
get_filename_component(LIBEVENT_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
|
||||
# Set the include directories.
|
||||
set(LIBEVENT_INCLUDE_DIRS "@EVENT__INCLUDE_DIRS@")
|
||||
|
||||
# Include the project Targets file, this contains definitions for IMPORTED targets.
|
||||
include(${LIBEVENT_CMAKE_DIR}/LibeventTargets.cmake)
|
||||
|
||||
# IMPORTED targets from LibeventTargets.cmake
|
||||
set(LIBEVENT_LIBRARIES event event_core event_extra)
|
||||
|
11
ipc/chromium/src/third_party/libevent/cmake/LibeventConfigVersion.cmake.in
поставляемый
Normal file
11
ipc/chromium/src/third_party/libevent/cmake/LibeventConfigVersion.cmake.in
поставляемый
Normal file
|
@ -0,0 +1,11 @@
|
|||
set(PACKAGE_VERSION "@EVENT_PACKAGE_VERSION@")
|
||||
|
||||
# Check whether the requested PACKAGE_FIND_VERSION is compatible
|
||||
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
|
||||
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||
else()
|
||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||
if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
|
||||
set(PACKAGE_VERSION_EXACT TRUE)
|
||||
endif()
|
||||
endif()
|
|
@ -0,0 +1,53 @@
|
|||
# This module defines the following variables utilizing
|
||||
# git to determine the parent tag. And if found the macro
|
||||
# will attempt to parse them in the github tag fomat
|
||||
#
|
||||
# Usful for auto-versionin in ou CMakeLists
|
||||
#
|
||||
# EVENT_GIT___VERSION_FOUND - Version variables foud
|
||||
# EVENT_GIT___VERSION_MAJOR - Major version.
|
||||
# EVENT_GIT___VERSION_MINOR - Minor version
|
||||
# EVENT_GIT___VERSION_STAGE - Stage version
|
||||
#
|
||||
# Example usage:
|
||||
#
|
||||
# event_fuzzy_version_from_git()
|
||||
# if (EVENT_GIT___VERSION_FOUND)
|
||||
# message("Libvent major=${EVENT_GIT___VERSION_MAJOR}")
|
||||
# message(" minor=${EVENT_GIT___VERSION_MINOR}")
|
||||
# message(" patch=${EVENT_GIT___VERSION_PATCH}")
|
||||
# message(" stage=${EVENT_GIT___VERSION_STAGE}")
|
||||
# endif()
|
||||
|
||||
include(FindGit)
|
||||
|
||||
macro(event_fuzzy_version_from_git)
|
||||
set(EVENT_GIT___VERSION_FOUND FALSE)
|
||||
|
||||
# set our defaults.
|
||||
set(EVENT_GIT___VERSION_MAJOR 2)
|
||||
set(EVENT_GIT___VERSION_MINOR 1)
|
||||
set(EVENT_GIT___VERSION_PATCH 8)
|
||||
set(EVENT_GIT___VERSION_STAGE "beta")
|
||||
|
||||
find_package(Git)
|
||||
|
||||
if (GIT_FOUND)
|
||||
execute_process(
|
||||
COMMAND
|
||||
${GIT_EXECUTABLE} describe --abbrev=0
|
||||
WORKING_DIRECTORY
|
||||
${PROJECT_SOURCE_DIR}
|
||||
RESULT_VARIABLE
|
||||
GITRET
|
||||
OUTPUT_VARIABLE
|
||||
GITVERSION)
|
||||
|
||||
if (GITRET EQUAL 0)
|
||||
string(REGEX REPLACE "^release-([0-9]+)\\.([0-9]+)\\.([0-9]+)-(.*)" "\\1" EVENT_GIT___VERSION_MAJOR ${GITVERSION})
|
||||
string(REGEX REPLACE "^release-([0-9]+)\\.([0-9]+)\\.([0-9]+)-(.*)" "\\2" EVENT_GIT___VERSION_MINOR ${GITVERSION})
|
||||
string(REGEX REPLACE "^release-([0-9]+)\\.([0-9]+)\\.([0-9]+)-(.*)" "\\3" EVENT_GIT___VERSION_PATCH ${GITVERSION})
|
||||
string(REGEX REPLACE "^release-([0-9]+)\\.([0-9]+)\\.([0-9]+)-([aA-zZ]+)" "\\4" EVENT_GIT___VERSION_STAGE ${GITVERSION})
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
|
@ -32,8 +32,8 @@
|
|||
* @(#)queue.h 8.5 (Berkeley) 8/20/94
|
||||
*/
|
||||
|
||||
#ifndef _SYS_QUEUE_H_
|
||||
#define _SYS_QUEUE_H_
|
||||
#ifndef SYS_QUEUE_H__
|
||||
#define SYS_QUEUE_H__
|
||||
|
||||
/*
|
||||
* This file defines five types of data structures: singly-linked lists,
|
||||
|
@ -93,7 +93,7 @@ struct name { \
|
|||
#define SLIST_HEAD_INITIALIZER(head) \
|
||||
{ NULL }
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
#define SLIST_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *sle_next; /* next element */ \
|
||||
|
@ -485,4 +485,4 @@ struct { \
|
|||
(elm2)->field.cqe_prev->field.cqe_next = (elm2); \
|
||||
} while (0)
|
||||
|
||||
#endif /* !_SYS_QUEUE_H_ */
|
||||
#endif /* !SYS_QUEUE_H__ */
|
||||
|
|
|
@ -1,342 +0,0 @@
|
|||
#! /bin/sh
|
||||
# Wrapper for compilers which do not understand '-c -o'.
|
||||
|
||||
scriptversion=2012-03-05.13; # UTC
|
||||
|
||||
# Copyright (C) 1999-2012 Free Software Foundation, Inc.
|
||||
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||
#
|
||||
# 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 2, 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
nl='
|
||||
'
|
||||
|
||||
# We need space, tab and new line, in precisely that order. Quoting is
|
||||
# there to prevent tools from complaining about whitespace usage.
|
||||
IFS=" "" $nl"
|
||||
|
||||
file_conv=
|
||||
|
||||
# func_file_conv build_file lazy
|
||||
# Convert a $build file to $host form and store it in $file
|
||||
# Currently only supports Windows hosts. If the determined conversion
|
||||
# type is listed in (the comma separated) LAZY, no conversion will
|
||||
# take place.
|
||||
func_file_conv ()
|
||||
{
|
||||
file=$1
|
||||
case $file in
|
||||
/ | /[!/]*) # absolute file, and not a UNC file
|
||||
if test -z "$file_conv"; then
|
||||
# lazily determine how to convert abs files
|
||||
case `uname -s` in
|
||||
MINGW*)
|
||||
file_conv=mingw
|
||||
;;
|
||||
CYGWIN*)
|
||||
file_conv=cygwin
|
||||
;;
|
||||
*)
|
||||
file_conv=wine
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
case $file_conv/,$2, in
|
||||
*,$file_conv,*)
|
||||
;;
|
||||
mingw/*)
|
||||
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
|
||||
;;
|
||||
cygwin/*)
|
||||
file=`cygpath -m "$file" || echo "$file"`
|
||||
;;
|
||||
wine/*)
|
||||
file=`winepath -w "$file" || echo "$file"`
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# func_cl_dashL linkdir
|
||||
# Make cl look for libraries in LINKDIR
|
||||
func_cl_dashL ()
|
||||
{
|
||||
func_file_conv "$1"
|
||||
if test -z "$lib_path"; then
|
||||
lib_path=$file
|
||||
else
|
||||
lib_path="$lib_path;$file"
|
||||
fi
|
||||
linker_opts="$linker_opts -LIBPATH:$file"
|
||||
}
|
||||
|
||||
# func_cl_dashl library
|
||||
# Do a library search-path lookup for cl
|
||||
func_cl_dashl ()
|
||||
{
|
||||
lib=$1
|
||||
found=no
|
||||
save_IFS=$IFS
|
||||
IFS=';'
|
||||
for dir in $lib_path $LIB
|
||||
do
|
||||
IFS=$save_IFS
|
||||
if $shared && test -f "$dir/$lib.dll.lib"; then
|
||||
found=yes
|
||||
lib=$dir/$lib.dll.lib
|
||||
break
|
||||
fi
|
||||
if test -f "$dir/$lib.lib"; then
|
||||
found=yes
|
||||
lib=$dir/$lib.lib
|
||||
break
|
||||
fi
|
||||
done
|
||||
IFS=$save_IFS
|
||||
|
||||
if test "$found" != yes; then
|
||||
lib=$lib.lib
|
||||
fi
|
||||
}
|
||||
|
||||
# func_cl_wrapper cl arg...
|
||||
# Adjust compile command to suit cl
|
||||
func_cl_wrapper ()
|
||||
{
|
||||
# Assume a capable shell
|
||||
lib_path=
|
||||
shared=:
|
||||
linker_opts=
|
||||
for arg
|
||||
do
|
||||
if test -n "$eat"; then
|
||||
eat=
|
||||
else
|
||||
case $1 in
|
||||
-o)
|
||||
# configure might choose to run compile as 'compile cc -o foo foo.c'.
|
||||
eat=1
|
||||
case $2 in
|
||||
*.o | *.[oO][bB][jJ])
|
||||
func_file_conv "$2"
|
||||
set x "$@" -Fo"$file"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
func_file_conv "$2"
|
||||
set x "$@" -Fe"$file"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
-I)
|
||||
eat=1
|
||||
func_file_conv "$2" mingw
|
||||
set x "$@" -I"$file"
|
||||
shift
|
||||
;;
|
||||
-I*)
|
||||
func_file_conv "${1#-I}" mingw
|
||||
set x "$@" -I"$file"
|
||||
shift
|
||||
;;
|
||||
-l)
|
||||
eat=1
|
||||
func_cl_dashl "$2"
|
||||
set x "$@" "$lib"
|
||||
shift
|
||||
;;
|
||||
-l*)
|
||||
func_cl_dashl "${1#-l}"
|
||||
set x "$@" "$lib"
|
||||
shift
|
||||
;;
|
||||
-L)
|
||||
eat=1
|
||||
func_cl_dashL "$2"
|
||||
;;
|
||||
-L*)
|
||||
func_cl_dashL "${1#-L}"
|
||||
;;
|
||||
-static)
|
||||
shared=false
|
||||
;;
|
||||
-Wl,*)
|
||||
arg=${1#-Wl,}
|
||||
save_ifs="$IFS"; IFS=','
|
||||
for flag in $arg; do
|
||||
IFS="$save_ifs"
|
||||
linker_opts="$linker_opts $flag"
|
||||
done
|
||||
IFS="$save_ifs"
|
||||
;;
|
||||
-Xlinker)
|
||||
eat=1
|
||||
linker_opts="$linker_opts $2"
|
||||
;;
|
||||
-*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
|
||||
func_file_conv "$1"
|
||||
set x "$@" -Tp"$file"
|
||||
shift
|
||||
;;
|
||||
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
|
||||
func_file_conv "$1" mingw
|
||||
set x "$@" "$file"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
done
|
||||
if test -n "$linker_opts"; then
|
||||
linker_opts="-link$linker_opts"
|
||||
fi
|
||||
exec "$@" $linker_opts
|
||||
exit 1
|
||||
}
|
||||
|
||||
eat=
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try '$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: compile [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Wrapper for compilers which do not understand '-c -o'.
|
||||
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
|
||||
arguments, and rename the output as expected.
|
||||
|
||||
If you are trying to build a whole package this is not the
|
||||
right script to run: please start by reading the file 'INSTALL'.
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "compile $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
|
||||
func_cl_wrapper "$@" # Doesn't return...
|
||||
;;
|
||||
esac
|
||||
|
||||
ofile=
|
||||
cfile=
|
||||
|
||||
for arg
|
||||
do
|
||||
if test -n "$eat"; then
|
||||
eat=
|
||||
else
|
||||
case $1 in
|
||||
-o)
|
||||
# configure might choose to run compile as 'compile cc -o foo foo.c'.
|
||||
# So we strip '-o arg' only if arg is an object.
|
||||
eat=1
|
||||
case $2 in
|
||||
*.o | *.obj)
|
||||
ofile=$2
|
||||
;;
|
||||
*)
|
||||
set x "$@" -o "$2"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*.c)
|
||||
cfile=$1
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
if test -z "$ofile" || test -z "$cfile"; then
|
||||
# If no '-o' option was seen then we might have been invoked from a
|
||||
# pattern rule where we don't need one. That is ok -- this is a
|
||||
# normal compilation that the losing compiler can handle. If no
|
||||
# '.c' file was seen then we are probably linking. That is also
|
||||
# ok.
|
||||
exec "$@"
|
||||
fi
|
||||
|
||||
# Name of file we expect compiler to create.
|
||||
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
|
||||
|
||||
# Create the lock directory.
|
||||
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
|
||||
# that we are using for the .o file. Also, base the name on the expected
|
||||
# object file name, since that is what matters with a parallel build.
|
||||
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
|
||||
while true; do
|
||||
if mkdir "$lockdir" >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
# FIXME: race condition here if user kills between mkdir and trap.
|
||||
trap "rmdir '$lockdir'; exit 1" 1 2 15
|
||||
|
||||
# Run the compile.
|
||||
"$@"
|
||||
ret=$?
|
||||
|
||||
if test -f "$cofile"; then
|
||||
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
|
||||
elif test -f "${cofile}bj"; then
|
||||
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
|
||||
fi
|
||||
|
||||
rmdir "$lockdir"
|
||||
exit $ret
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,442 +0,0 @@
|
|||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define if libevent should build without support for a debug mode */
|
||||
#undef DISABLE_DEBUG_MODE
|
||||
|
||||
/* Define if libevent should not allow replacing the mm functions */
|
||||
#undef DISABLE_MM_REPLACEMENT
|
||||
|
||||
/* Define if libevent should not be compiled with thread support */
|
||||
#undef DISABLE_THREAD_SUPPORT
|
||||
|
||||
/* Define to 1 if you have the `arc4random' function. */
|
||||
#undef HAVE_ARC4RANDOM
|
||||
|
||||
/* Define to 1 if you have the `arc4random_buf' function. */
|
||||
#undef HAVE_ARC4RANDOM_BUF
|
||||
|
||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
#undef HAVE_ARPA_INET_H
|
||||
|
||||
/* Define to 1 if you have the `clock_gettime' function. */
|
||||
#undef HAVE_CLOCK_GETTIME
|
||||
|
||||
/* Define to 1 if you have the declaration of `CTL_KERN', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_CTL_KERN
|
||||
|
||||
/* Define to 1 if you have the declaration of `KERN_ARND', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_KERN_ARND
|
||||
|
||||
/* Define to 1 if you have the declaration of `KERN_RANDOM', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_KERN_RANDOM
|
||||
|
||||
/* Define to 1 if you have the declaration of `RANDOM_UUID', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_RANDOM_UUID
|
||||
|
||||
/* Define if /dev/poll is available */
|
||||
#undef HAVE_DEVPOLL
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define if your system supports the epoll system calls */
|
||||
#undef HAVE_EPOLL
|
||||
|
||||
/* Define to 1 if you have the `epoll_ctl' function. */
|
||||
#undef HAVE_EPOLL_CTL
|
||||
|
||||
/* Define to 1 if you have the `eventfd' function. */
|
||||
#undef HAVE_EVENTFD
|
||||
|
||||
/* Define if your system supports event ports */
|
||||
#undef HAVE_EVENT_PORTS
|
||||
|
||||
/* Define to 1 if you have the `fcntl' function. */
|
||||
#undef HAVE_FCNTL
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#undef HAVE_FCNTL_H
|
||||
|
||||
/* Define to 1 if the system has the type `fd_mask'. */
|
||||
#undef HAVE_FD_MASK
|
||||
|
||||
/* Do we have getaddrinfo()? */
|
||||
#undef HAVE_GETADDRINFO
|
||||
|
||||
/* Define to 1 if you have the `getegid' function. */
|
||||
#undef HAVE_GETEGID
|
||||
|
||||
/* Define to 1 if you have the `geteuid' function. */
|
||||
#undef HAVE_GETEUID
|
||||
|
||||
/* Define this if you have any gethostbyname_r() */
|
||||
#undef HAVE_GETHOSTBYNAME_R
|
||||
|
||||
/* Define this if gethostbyname_r takes 3 arguments */
|
||||
#undef HAVE_GETHOSTBYNAME_R_3_ARG
|
||||
|
||||
/* Define this if gethostbyname_r takes 5 arguments */
|
||||
#undef HAVE_GETHOSTBYNAME_R_5_ARG
|
||||
|
||||
/* Define this if gethostbyname_r takes 6 arguments */
|
||||
#undef HAVE_GETHOSTBYNAME_R_6_ARG
|
||||
|
||||
/* Define to 1 if you have the `getnameinfo' function. */
|
||||
#undef HAVE_GETNAMEINFO
|
||||
|
||||
/* Define to 1 if you have the `getprotobynumber' function. */
|
||||
#undef HAVE_GETPROTOBYNUMBER
|
||||
|
||||
/* Define to 1 if you have the `getservbyname' function. */
|
||||
#undef HAVE_GETSERVBYNAME
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
#undef HAVE_GETTIMEOFDAY
|
||||
|
||||
/* Define to 1 if you have the `inet_aton' function. */
|
||||
#undef HAVE_INET_ATON
|
||||
|
||||
/* Define to 1 if you have the `inet_ntop' function. */
|
||||
#undef HAVE_INET_NTOP
|
||||
|
||||
/* Define to 1 if you have the `inet_pton' function. */
|
||||
#undef HAVE_INET_PTON
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the `issetugid' function. */
|
||||
#undef HAVE_ISSETUGID
|
||||
|
||||
/* Define to 1 if you have the `kqueue' function. */
|
||||
#undef HAVE_KQUEUE
|
||||
|
||||
/* Define if the system has zlib */
|
||||
#undef HAVE_LIBZ
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the `mmap' function. */
|
||||
#undef HAVE_MMAP
|
||||
|
||||
/* Define to 1 if you have the <netdb.h> header file. */
|
||||
#undef HAVE_NETDB_H
|
||||
|
||||
/* Define to 1 if you have the <netinet/in6.h> header file. */
|
||||
#undef HAVE_NETINET_IN6_H
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#undef HAVE_NETINET_IN_H
|
||||
|
||||
/* Define if the system has openssl */
|
||||
#undef HAVE_OPENSSL
|
||||
|
||||
/* Define to 1 if you have the <openssl/bio.h> header file. */
|
||||
#undef HAVE_OPENSSL_BIO_H
|
||||
|
||||
/* Define to 1 if you have the `pipe' function. */
|
||||
#undef HAVE_PIPE
|
||||
|
||||
/* Define to 1 if you have the `poll' function. */
|
||||
#undef HAVE_POLL
|
||||
|
||||
/* Define to 1 if you have the <poll.h> header file. */
|
||||
#undef HAVE_POLL_H
|
||||
|
||||
/* Define to 1 if you have the `port_create' function. */
|
||||
#undef HAVE_PORT_CREATE
|
||||
|
||||
/* Define to 1 if you have the <port.h> header file. */
|
||||
#undef HAVE_PORT_H
|
||||
|
||||
/* Define if you have POSIX threads libraries and header files. */
|
||||
#undef HAVE_PTHREAD
|
||||
|
||||
/* Define if we have pthreads on this system */
|
||||
#undef HAVE_PTHREADS
|
||||
|
||||
/* Define to 1 if you have the `putenv' function. */
|
||||
#undef HAVE_PUTENV
|
||||
|
||||
/* Define to 1 if the system has the type `sa_family_t'. */
|
||||
#undef HAVE_SA_FAMILY_T
|
||||
|
||||
/* Define to 1 if you have the `select' function. */
|
||||
#undef HAVE_SELECT
|
||||
|
||||
/* Define to 1 if you have the `sendfile' function. */
|
||||
#undef HAVE_SENDFILE
|
||||
|
||||
/* Define to 1 if you have the `setenv' function. */
|
||||
#undef HAVE_SETENV
|
||||
|
||||
/* Define if F_SETFD is defined in <fcntl.h> */
|
||||
#undef HAVE_SETFD
|
||||
|
||||
/* Define to 1 if you have the `sigaction' function. */
|
||||
#undef HAVE_SIGACTION
|
||||
|
||||
/* Define to 1 if you have the `signal' function. */
|
||||
#undef HAVE_SIGNAL
|
||||
|
||||
/* Define to 1 if you have the `splice' function. */
|
||||
#undef HAVE_SPLICE
|
||||
|
||||
/* Define to 1 if you have the <stdarg.h> header file. */
|
||||
#undef HAVE_STDARG_H
|
||||
|
||||
/* Define to 1 if you have the <stddef.h> header file. */
|
||||
#undef HAVE_STDDEF_H
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the `strlcpy' function. */
|
||||
#undef HAVE_STRLCPY
|
||||
|
||||
/* Define to 1 if you have the `strsep' function. */
|
||||
#undef HAVE_STRSEP
|
||||
|
||||
/* Define to 1 if you have the `strtok_r' function. */
|
||||
#undef HAVE_STRTOK_R
|
||||
|
||||
/* Define to 1 if you have the `strtoll' function. */
|
||||
#undef HAVE_STRTOLL
|
||||
|
||||
/* Define to 1 if the system has the type `struct addrinfo'. */
|
||||
#undef HAVE_STRUCT_ADDRINFO
|
||||
|
||||
/* Define to 1 if the system has the type `struct in6_addr'. */
|
||||
#undef HAVE_STRUCT_IN6_ADDR
|
||||
|
||||
/* Define to 1 if `s6_addr16' is a member of `struct in6_addr'. */
|
||||
#undef HAVE_STRUCT_IN6_ADDR_S6_ADDR16
|
||||
|
||||
/* Define to 1 if `s6_addr32' is a member of `struct in6_addr'. */
|
||||
#undef HAVE_STRUCT_IN6_ADDR_S6_ADDR32
|
||||
|
||||
/* Define to 1 if the system has the type `struct sockaddr_in6'. */
|
||||
#undef HAVE_STRUCT_SOCKADDR_IN6
|
||||
|
||||
/* Define to 1 if `sin6_len' is a member of `struct sockaddr_in6'. */
|
||||
#undef HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
|
||||
|
||||
/* Define to 1 if `sin_len' is a member of `struct sockaddr_in'. */
|
||||
#undef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
|
||||
|
||||
/* Define to 1 if the system has the type `struct sockaddr_storage'. */
|
||||
#undef HAVE_STRUCT_SOCKADDR_STORAGE
|
||||
|
||||
/* Define to 1 if `ss_family' is a member of `struct sockaddr_storage'. */
|
||||
#undef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
|
||||
|
||||
/* Define to 1 if `__ss_family' is a member of `struct sockaddr_storage'. */
|
||||
#undef HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY
|
||||
|
||||
/* Define to 1 if you have the `sysctl' function. */
|
||||
#undef HAVE_SYSCTL
|
||||
|
||||
/* Define to 1 if you have the <sys/devpoll.h> header file. */
|
||||
#undef HAVE_SYS_DEVPOLL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/epoll.h> header file. */
|
||||
#undef HAVE_SYS_EPOLL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/eventfd.h> header file. */
|
||||
#undef HAVE_SYS_EVENTFD_H
|
||||
|
||||
/* Define to 1 if you have the <sys/event.h> header file. */
|
||||
#undef HAVE_SYS_EVENT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||
#undef HAVE_SYS_IOCTL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||
#undef HAVE_SYS_MMAN_H
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
/* Define to 1 if you have the <sys/queue.h> header file. */
|
||||
#undef HAVE_SYS_QUEUE_H
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
#undef HAVE_SYS_SELECT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/sendfile.h> header file. */
|
||||
#undef HAVE_SYS_SENDFILE_H
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#undef HAVE_SYS_SOCKET_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/sysctl.h> header file. */
|
||||
#undef HAVE_SYS_SYSCTL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#undef HAVE_SYS_TIME_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <sys/uio.h> header file. */
|
||||
#undef HAVE_SYS_UIO_H
|
||||
|
||||
/* Define to 1 if you have the <sys/wait.h> header file. */
|
||||
#undef HAVE_SYS_WAIT_H
|
||||
|
||||
/* Define if TAILQ_FOREACH is defined in <sys/queue.h> */
|
||||
#undef HAVE_TAILQFOREACH
|
||||
|
||||
/* Define if timeradd is defined in <sys/time.h> */
|
||||
#undef HAVE_TIMERADD
|
||||
|
||||
/* Define if timerclear is defined in <sys/time.h> */
|
||||
#undef HAVE_TIMERCLEAR
|
||||
|
||||
/* Define if timercmp is defined in <sys/time.h> */
|
||||
#undef HAVE_TIMERCMP
|
||||
|
||||
/* Define if timerisset is defined in <sys/time.h> */
|
||||
#undef HAVE_TIMERISSET
|
||||
|
||||
/* Define to 1 if the system has the type `uint16_t'. */
|
||||
#undef HAVE_UINT16_T
|
||||
|
||||
/* Define to 1 if the system has the type `uint32_t'. */
|
||||
#undef HAVE_UINT32_T
|
||||
|
||||
/* Define to 1 if the system has the type `uint64_t'. */
|
||||
#undef HAVE_UINT64_T
|
||||
|
||||
/* Define to 1 if the system has the type `uint8_t'. */
|
||||
#undef HAVE_UINT8_T
|
||||
|
||||
/* Define to 1 if the system has the type `uintptr_t'. */
|
||||
#undef HAVE_UINTPTR_T
|
||||
|
||||
/* Define to 1 if you have the `umask' function. */
|
||||
#undef HAVE_UMASK
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if you have the `unsetenv' function. */
|
||||
#undef HAVE_UNSETENV
|
||||
|
||||
/* Define to 1 if you have the `vasprintf' function. */
|
||||
#undef HAVE_VASPRINTF
|
||||
|
||||
/* Define if kqueue works correctly with pipes */
|
||||
#undef HAVE_WORKING_KQUEUE
|
||||
|
||||
/* Define to 1 if you have the <zlib.h> header file. */
|
||||
#undef HAVE_ZLIB_H
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#undef LT_OBJDIR
|
||||
|
||||
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
|
||||
#undef NO_MINUS_C_MINUS_O
|
||||
|
||||
/* Numeric representation of the version */
|
||||
#undef NUMERIC_VERSION
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Define to necessary symbol if this constant uses a non-standard name on
|
||||
your system. */
|
||||
#undef PTHREAD_CREATE_JOINABLE
|
||||
|
||||
/* The size of `int', as computed by sizeof. */
|
||||
#undef SIZEOF_INT
|
||||
|
||||
/* The size of `long', as computed by sizeof. */
|
||||
#undef SIZEOF_LONG
|
||||
|
||||
/* The size of `long long', as computed by sizeof. */
|
||||
#undef SIZEOF_LONG_LONG
|
||||
|
||||
/* The size of `off_t', as computed by sizeof. */
|
||||
#undef SIZEOF_OFF_T
|
||||
|
||||
/* The size of `pthread_t', as computed by sizeof. */
|
||||
#undef SIZEOF_PTHREAD_T
|
||||
|
||||
/* The size of `short', as computed by sizeof. */
|
||||
#undef SIZEOF_SHORT
|
||||
|
||||
/* The size of `size_t', as computed by sizeof. */
|
||||
#undef SIZEOF_SIZE_T
|
||||
|
||||
/* The size of `void *', as computed by sizeof. */
|
||||
#undef SIZEOF_VOID_P
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#undef TIME_WITH_SYS_TIME
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Define to appropriate substitue if compiler doesnt have __func__ */
|
||||
#undef __func__
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
#undef const
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
#undef inline
|
||||
#endif
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#undef pid_t
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
#undef size_t
|
||||
|
||||
/* Define to unsigned int if you dont have it */
|
||||
#undef socklen_t
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#undef ssize_t
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,4 +1,3 @@
|
|||
dnl configure.in for libevent
|
||||
dnl Copyright 2000-2007 Niels Provos
|
||||
dnl Copyright 2007-2012 Niels Provos and Nick Mathewson
|
||||
dnl
|
||||
|
@ -6,34 +5,44 @@ dnl See LICENSE for copying information.
|
|||
dnl
|
||||
dnl Original version Dug Song <dugsong@monkey.org>
|
||||
|
||||
AC_INIT(libevent,2.1.8-stable)
|
||||
AC_PREREQ(2.59)
|
||||
AC_INIT(event.c)
|
||||
AC_CONFIG_SRCDIR(event.c)
|
||||
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
AM_INIT_AUTOMAKE(libevent,2.0.22-stable)
|
||||
AC_CONFIG_HEADERS(config.h)
|
||||
AC_DEFINE(NUMERIC_VERSION, 0x02001600, [Numeric representation of the version])
|
||||
AM_INIT_AUTOMAKE
|
||||
dnl AM_SILENT_RULES req. automake 1.11. [no] defaults V=1
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
AC_CONFIG_HEADERS(config.h evconfig-private.h:evconfig-private.h.in)
|
||||
AC_DEFINE(NUMERIC_VERSION, 0x02010800, [Numeric representation of the version])
|
||||
|
||||
dnl Initialize prefix.
|
||||
if test "$prefix" = "NONE"; then
|
||||
prefix="/usr/local"
|
||||
fi
|
||||
|
||||
dnl Try and get a full POSIX environment on obscure systems
|
||||
ifdef([AC_USE_SYSTEM_EXTENSIONS], [
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
], [
|
||||
AC_AIX
|
||||
AC_GNU_SOURCE
|
||||
AC_MINIX
|
||||
])
|
||||
|
||||
AC_CANONICAL_BUILD
|
||||
AC_CANONICAL_HOST
|
||||
dnl the 'build' machine is where we run configure and compile
|
||||
dnl the 'host' machine is where the resulting stuff runs.
|
||||
|
||||
case "$host_os" in
|
||||
|
||||
osf5*)
|
||||
CFLAGS="$CFLAGS -D_OSF_SOURCE"
|
||||
;;
|
||||
esac
|
||||
#case "$host_os" in
|
||||
#
|
||||
# osf5*)
|
||||
# CFLAGS="$CFLAGS -D_OSF_SOURCE"
|
||||
# ;;
|
||||
#esac
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AM_PROG_CC_C_O
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
|
@ -65,16 +74,26 @@ if test "$GCC" = "yes" ; then
|
|||
fi
|
||||
|
||||
# OS X Lion started deprecating the system openssl. Let's just disable
|
||||
# all deprecation warnings on OS X.
|
||||
case "$host_os" in
|
||||
|
||||
darwin*)
|
||||
CFLAGS="$CFLAGS -Wno-deprecated-declarations"
|
||||
;;
|
||||
esac
|
||||
# all deprecation warnings on OS X; but do so only for gcc...
|
||||
if test "$GCC" = "yes" ; then
|
||||
case "$host_os" in
|
||||
darwin*)
|
||||
CFLAGS="$CFLAGS -Wno-deprecated-declarations"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(gcc-warnings,
|
||||
AS_HELP_STRING(--enable-gcc-warnings, enable verbose warnings with GCC))
|
||||
AS_HELP_STRING(--disable-gcc-warnings, disable verbose warnings with GCC))
|
||||
|
||||
AC_ARG_ENABLE(gcc-hardening,
|
||||
AS_HELP_STRING(--enable-gcc-hardening, enable compiler security checks),
|
||||
[if test x$enableval = xyes; then
|
||||
CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=2 -fstack-protector-all"
|
||||
CFLAGS="$CFLAGS -fwrapv -fPIE -Wstack-protector"
|
||||
CFLAGS="$CFLAGS --param ssp-buffer-size=1"
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE(thread-support,
|
||||
AS_HELP_STRING(--disable-thread-support, disable support for threading),
|
||||
[], [enable_thread_support=yes])
|
||||
|
@ -93,34 +112,47 @@ AC_ARG_ENABLE([libevent-install],
|
|||
AC_ARG_ENABLE([libevent-regress],
|
||||
AS_HELP_STRING([--disable-libevent-regress, skip regress in make check]),
|
||||
[], [enable_libevent_regress=yes])
|
||||
AC_ARG_ENABLE([samples],
|
||||
AS_HELP_STRING([--disable-samples, skip building of sample programs]),
|
||||
[], [enable_samples=yes])
|
||||
AC_ARG_ENABLE([function-sections],
|
||||
AS_HELP_STRING([--enable-function-sections, make static library allow smaller binaries with --gc-sections]),
|
||||
[], [enable_function_sections=no])
|
||||
AC_ARG_ENABLE([verbose-debug],
|
||||
AS_HELP_STRING([--enable-verbose-debug, verbose debug logging]),
|
||||
[], [enable_verbose_debug=no])
|
||||
AC_ARG_ENABLE([clock-gettime],
|
||||
AS_HELP_STRING(--disable-clock-gettime, do not use clock_gettime even if it is available),
|
||||
[], [enable_clock_gettime=yes])
|
||||
|
||||
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
dnl Uncomment "AC_DISABLE_SHARED" to make shared librraries not get
|
||||
dnl Uncomment "AC_DISABLE_SHARED" to make shared libraries not get
|
||||
dnl built by default. You can also turn shared libs on and off from
|
||||
dnl the command line with --enable-shared and --disable-shared.
|
||||
dnl AC_DISABLE_SHARED
|
||||
AC_SUBST(LIBTOOL_DEPS)
|
||||
|
||||
AM_CONDITIONAL([BUILD_SAMPLES], [test "$enable_samples" = "yes"])
|
||||
AM_CONDITIONAL([BUILD_REGRESS], [test "$enable_libevent_regress" = "yes"])
|
||||
|
||||
dnl Checks for libraries.
|
||||
AC_SEARCH_LIBS([inet_ntoa], [nsl])
|
||||
AC_SEARCH_LIBS([socket], [socket])
|
||||
AC_SEARCH_LIBS([inet_aton], [resolv])
|
||||
AC_SEARCH_LIBS([clock_gettime], [rt])
|
||||
if test "x$enable_clock_gettime" = "xyes"; then
|
||||
AC_SEARCH_LIBS([clock_gettime], [rt])
|
||||
AC_CHECK_FUNCS([clock_gettime])
|
||||
fi
|
||||
AC_SEARCH_LIBS([sendfile], [sendfile])
|
||||
|
||||
dnl - check if the macro WIN32 is defined on this compiler.
|
||||
dnl - (this is how we check for a windows version of GCC)
|
||||
dnl - check if the macro _WIN32 is defined on this compiler.
|
||||
dnl - (this is how we check for a windows compiler)
|
||||
AC_MSG_CHECKING(for WIN32)
|
||||
AC_TRY_COMPILE(,
|
||||
[
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
die horribly
|
||||
#endif
|
||||
],
|
||||
|
@ -171,27 +203,44 @@ AC_SUBST(EV_LIB_WS32)
|
|||
AC_SUBST(EV_LIB_GDI)
|
||||
AC_SUBST(OPENSSL_LIBADD)
|
||||
|
||||
AC_CHECK_HEADERS([openssl/bio.h])
|
||||
AC_SYS_LARGEFILE
|
||||
|
||||
if test "$enable_openssl" = "yes"; then
|
||||
save_LIBS="$LIBS"
|
||||
LIBS=""
|
||||
OPENSSL_LIBS=""
|
||||
have_openssl=no
|
||||
AC_SEARCH_LIBS([SSL_new], [ssl],
|
||||
[have_openssl=yes
|
||||
OPENSSL_LIBS="$LIBS -lcrypto $EV_LIB_GDI $EV_LIB_WS32 $OPENSSL_LIBADD"
|
||||
AC_DEFINE(HAVE_OPENSSL, 1, [Define if the system has openssl])],
|
||||
[have_openssl=no],
|
||||
[-lcrypto $EV_LIB_GDI $EV_LIB_WS32 $OPENSSL_LIBADD])
|
||||
LIBS="$save_LIBS"
|
||||
AC_SUBST(OPENSSL_LIBS)
|
||||
fi
|
||||
LIBEVENT_OPENSSL
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS([fcntl.h stdarg.h inttypes.h stdint.h stddef.h poll.h unistd.h sys/epoll.h sys/time.h sys/queue.h sys/event.h sys/param.h sys/ioctl.h sys/select.h sys/devpoll.h port.h netinet/in.h netinet/in6.h sys/socket.h sys/uio.h arpa/inet.h sys/eventfd.h sys/mman.h sys/sendfile.h sys/wait.h netdb.h])
|
||||
AC_CHECK_HEADERS([sys/stat.h])
|
||||
AC_CHECK_HEADERS([ \
|
||||
arpa/inet.h \
|
||||
fcntl.h \
|
||||
ifaddrs.h \
|
||||
mach/mach_time.h \
|
||||
netdb.h \
|
||||
netinet/in.h \
|
||||
netinet/in6.h \
|
||||
netinet/tcp.h \
|
||||
poll.h \
|
||||
port.h \
|
||||
stdarg.h \
|
||||
stddef.h \
|
||||
sys/devpoll.h \
|
||||
sys/epoll.h \
|
||||
sys/event.h \
|
||||
sys/eventfd.h \
|
||||
sys/ioctl.h \
|
||||
sys/mman.h \
|
||||
sys/param.h \
|
||||
sys/queue.h \
|
||||
sys/resource.h \
|
||||
sys/select.h \
|
||||
sys/sendfile.h \
|
||||
sys/socket.h \
|
||||
sys/stat.h \
|
||||
sys/time.h \
|
||||
sys/timerfd.h \
|
||||
sys/uio.h \
|
||||
sys/wait.h \
|
||||
errno.h \
|
||||
])
|
||||
|
||||
AC_CHECK_HEADERS(sys/sysctl.h, [], [], [
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
|
@ -289,9 +338,47 @@ AC_C_INLINE
|
|||
AC_HEADER_TIME
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_CHECK_FUNCS([gettimeofday vasprintf fcntl clock_gettime strtok_r strsep])
|
||||
AC_CHECK_FUNCS([getnameinfo strlcpy inet_ntop inet_pton signal sigaction strtoll inet_aton pipe eventfd sendfile mmap splice arc4random arc4random_buf issetugid geteuid getegid getprotobynumber setenv unsetenv putenv sysctl])
|
||||
AC_CHECK_FUNCS([umask])
|
||||
AC_CHECK_FUNCS([ \
|
||||
accept4 \
|
||||
arc4random \
|
||||
arc4random_buf \
|
||||
eventfd \
|
||||
epoll_create1 \
|
||||
fcntl \
|
||||
getegid \
|
||||
geteuid \
|
||||
getifaddrs \
|
||||
getnameinfo \
|
||||
getprotobynumber \
|
||||
gettimeofday \
|
||||
inet_ntop \
|
||||
inet_pton \
|
||||
issetugid \
|
||||
mach_absolute_time \
|
||||
mmap \
|
||||
nanosleep \
|
||||
pipe \
|
||||
pipe2 \
|
||||
putenv \
|
||||
sendfile \
|
||||
setenv \
|
||||
setrlimit \
|
||||
sigaction \
|
||||
signal \
|
||||
splice \
|
||||
strlcpy \
|
||||
strsep \
|
||||
strtok_r \
|
||||
strtoll \
|
||||
sysctl \
|
||||
timerfd_create \
|
||||
umask \
|
||||
unsetenv \
|
||||
usleep \
|
||||
vasprintf \
|
||||
getservbyname \
|
||||
])
|
||||
AM_CONDITIONAL(STRLCPY_IMPL, [test x"$ac_cv_func_strlcpy" = xno])
|
||||
|
||||
AC_CACHE_CHECK(
|
||||
[for getaddrinfo],
|
||||
|
@ -315,7 +402,6 @@ if test "$libevent_cv_getaddrinfo" = "yes" ; then
|
|||
AC_DEFINE([HAVE_GETADDRINFO], [1], [Do we have getaddrinfo()?])
|
||||
else
|
||||
|
||||
AC_CHECK_FUNCS([getservbyname])
|
||||
# Check for gethostbyname_r in all its glorious incompatible versions.
|
||||
# (This is cut-and-pasted from Tor, which based its logic on
|
||||
# Python's configure.in.)
|
||||
|
@ -374,8 +460,6 @@ AC_CHECK_FUNC(gethostbyname_r, [
|
|||
|
||||
fi
|
||||
|
||||
AC_CHECK_SIZEOF(long)
|
||||
|
||||
AC_MSG_CHECKING(for F_SETFD in fcntl.h)
|
||||
AC_EGREP_CPP(yes,
|
||||
[
|
||||
|
@ -515,6 +599,26 @@ main(int argc, char **argv)
|
|||
fi
|
||||
AM_CONDITIONAL(EPOLL_BACKEND, [test "x$haveepoll" = "xyes"])
|
||||
|
||||
AC_MSG_CHECKING(waitpid support WNOWAIT)
|
||||
AC_TRY_RUN(
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
pid_t pid;
|
||||
int status;
|
||||
if ((pid = fork()) == 0) _exit(0);
|
||||
_exit(waitpid(pid, &status, WNOWAIT) == -1);
|
||||
}, [AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_WAITPID_WITH_WNOWAIT, 1,
|
||||
[Define if waitpid() supports WNOWAIT])
|
||||
], AC_MSG_RESULT(no), AC_MSG_RESULT(no))
|
||||
|
||||
|
||||
haveeventports=no
|
||||
AC_CHECK_FUNCS(port_create, [haveeventports=yes], )
|
||||
if test "x$haveeventports" = "xyes" ; then
|
||||
|
@ -575,7 +679,7 @@ AC_CHECK_TYPES([struct in6_addr, struct sockaddr_in6, sa_family_t, struct addrin
|
|||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#define WIN32_WINNT 0x400
|
||||
#define _WIN32_WINNT 0x400
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
@ -598,7 +702,7 @@ AC_CHECK_MEMBERS([struct in6_addr.s6_addr32, struct in6_addr.s6_addr16, struct s
|
|||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#define WIN32_WINNT 0x400
|
||||
#define _WIN32_WINNT 0x400
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
@ -611,6 +715,14 @@ AC_CHECK_MEMBERS([struct in6_addr.s6_addr32, struct in6_addr.s6_addr16, struct s
|
|||
#endif
|
||||
])
|
||||
|
||||
AC_CHECK_TYPES([struct so_linger],
|
||||
[#define HAVE_SO_LINGER], ,
|
||||
[
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING([for socklen_t])
|
||||
AC_TRY_COMPILE([
|
||||
#include <sys/types.h>
|
||||
|
@ -651,6 +763,7 @@ if test x$bwin32 != xtrue && test "$enable_thread_support" != "no"; then
|
|||
#include <pthread.h> ]
|
||||
)
|
||||
fi
|
||||
AM_CONDITIONAL(THREADS, [test "$enable_thread_support" != "no"])
|
||||
AM_CONDITIONAL(PTHREADS, [test "$have_pthreads" != "no" && test "$enable_thread_support" != "no"])
|
||||
|
||||
# check if we should compile locking into the library
|
||||
|
@ -671,12 +784,21 @@ if test x$enable_debug_mode = xno; then
|
|||
[Define if libevent should build without support for a debug mode])
|
||||
fi
|
||||
|
||||
# check if we should enable verbose debugging
|
||||
if test x$enable_verbose_debug = xyes; then
|
||||
CFLAGS="$CFLAGS -DUSE_DEBUG"
|
||||
fi
|
||||
|
||||
# check if we have and should use openssl
|
||||
AM_CONDITIONAL(OPENSSL, [test "$enable_openssl" != "no" && test "$have_openssl" = "yes"])
|
||||
if test "x$enable_openssl" = "xyes"; then
|
||||
AC_SEARCH_LIBS([ERR_remove_thread_state], [crypto eay32],
|
||||
[AC_DEFINE(HAVE_ERR_REMOVE_THREAD_STATE, 1, [Define to 1 if you have ERR_remove_thread_stat().])])
|
||||
fi
|
||||
|
||||
# Add some more warnings which we use in development but not in the
|
||||
# released versions. (Some relevant gcc versions can't handle these.)
|
||||
if test x$enable_gcc_warnings = xyes && test "$GCC" = "yes"; then
|
||||
if test x$enable_gcc_warnings != xno && test "$GCC" = "yes"; then
|
||||
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [
|
||||
#if !defined(__GNUC__) || (__GNUC__ < 4)
|
||||
|
@ -698,7 +820,11 @@ if test x$enable_gcc_warnings = xyes && test "$GCC" = "yes"; then
|
|||
#error
|
||||
#endif])], have_clang=yes, have_clang=no)
|
||||
|
||||
CFLAGS="$CFLAGS -W -Wfloat-equal -Wundef -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wwrite-strings -Wredundant-decls -Wchar-subscripts -Wcomment -Wformat -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wnested-externs -Wbad-function-cast -Wswitch-enum -Werror"
|
||||
CFLAGS="$CFLAGS -W -Wfloat-equal -Wundef -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wwrite-strings -Wredundant-decls -Wchar-subscripts -Wcomment -Wformat -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wnested-externs -Wbad-function-cast -Wswitch"
|
||||
if test x$enable_gcc_warnings = xyes; then
|
||||
CFLAGS="$CFLAGS -Werror"
|
||||
fi
|
||||
|
||||
CFLAGS="$CFLAGS -Wno-unused-parameter -Wstrict-aliasing"
|
||||
|
||||
if test x$have_gcc4 = xyes ; then
|
||||
|
@ -817,5 +943,5 @@ AC_SUBST([LIBEVENT_GC_SECTIONS])
|
|||
|
||||
AM_CONDITIONAL([INSTALL_LIBEVENT], [test "$enable_libevent_install" = "yes"])
|
||||
|
||||
AC_CONFIG_FILES( [libevent.pc libevent_openssl.pc libevent_pthreads.pc] )
|
||||
AC_OUTPUT(Makefile include/Makefile test/Makefile sample/Makefile)
|
||||
AC_CONFIG_FILES( [libevent.pc libevent_openssl.pc libevent_pthreads.pc libevent_core.pc libevent_extra.pc] )
|
||||
AC_OUTPUT(Makefile)
|
||||
|
|
|
@ -23,78 +23,48 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _DEFER_INTERNAL_H_
|
||||
#define _DEFER_INTERNAL_H_
|
||||
#ifndef DEFER_INTERNAL_H_INCLUDED_
|
||||
#define DEFER_INTERNAL_H_INCLUDED_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "event2/event-config.h"
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#include <sys/queue.h>
|
||||
|
||||
struct deferred_cb;
|
||||
|
||||
typedef void (*deferred_cb_fn)(struct deferred_cb *, void *);
|
||||
|
||||
/** A deferred_cb is a callback that can be scheduled to run as part of
|
||||
* an event_base's event_loop, rather than running immediately. */
|
||||
struct deferred_cb {
|
||||
/** Links to the adjacent active (pending) deferred_cb objects. */
|
||||
TAILQ_ENTRY (deferred_cb) cb_next;
|
||||
/** True iff this deferred_cb is pending in an event_base. */
|
||||
unsigned queued : 1;
|
||||
/** The function to execute when the callback runs. */
|
||||
deferred_cb_fn cb;
|
||||
/** The function's second argument. */
|
||||
void *arg;
|
||||
};
|
||||
|
||||
/** A deferred_cb_queue is a list of deferred_cb that we can add to and run. */
|
||||
struct deferred_cb_queue {
|
||||
/** Lock used to protect the queue. */
|
||||
void *lock;
|
||||
|
||||
/** How many entries are in the queue? */
|
||||
int active_count;
|
||||
|
||||
/** Function called when adding to the queue from another thread. */
|
||||
void (*notify_fn)(struct deferred_cb_queue *, void *);
|
||||
void *notify_arg;
|
||||
|
||||
/** Deferred callback management: a list of deferred callbacks to
|
||||
* run active the active events. */
|
||||
TAILQ_HEAD (deferred_cb_list, deferred_cb) deferred_cb_list;
|
||||
};
|
||||
struct event_callback;
|
||||
typedef void (*deferred_cb_fn)(struct event_callback *, void *);
|
||||
|
||||
/**
|
||||
Initialize an empty, non-pending deferred_cb.
|
||||
Initialize an empty, non-pending event_callback.
|
||||
|
||||
@param deferred The deferred_cb structure to initialize.
|
||||
@param cb The function to run when the deferred_cb executes.
|
||||
@param deferred The struct event_callback structure to initialize.
|
||||
@param priority The priority that the callback should run at.
|
||||
@param cb The function to run when the struct event_callback executes.
|
||||
@param arg The function's second argument.
|
||||
*/
|
||||
void event_deferred_cb_init(struct deferred_cb *, deferred_cb_fn, void *);
|
||||
void event_deferred_cb_init_(struct event_callback *, ev_uint8_t, deferred_cb_fn, void *);
|
||||
/**
|
||||
Cancel a deferred_cb if it is currently scheduled in an event_base.
|
||||
Change the priority of a non-pending event_callback.
|
||||
*/
|
||||
void event_deferred_cb_cancel(struct deferred_cb_queue *, struct deferred_cb *);
|
||||
void event_deferred_cb_set_priority_(struct event_callback *, ev_uint8_t);
|
||||
/**
|
||||
Activate a deferred_cb if it is not currently scheduled in an event_base.
|
||||
Cancel a struct event_callback if it is currently scheduled in an event_base.
|
||||
*/
|
||||
void event_deferred_cb_schedule(struct deferred_cb_queue *, struct deferred_cb *);
|
||||
void event_deferred_cb_cancel_(struct event_base *, struct event_callback *);
|
||||
/**
|
||||
Activate a struct event_callback if it is not currently scheduled in an event_base.
|
||||
|
||||
#define LOCK_DEFERRED_QUEUE(q) \
|
||||
EVLOCK_LOCK((q)->lock, 0)
|
||||
#define UNLOCK_DEFERRED_QUEUE(q) \
|
||||
EVLOCK_UNLOCK((q)->lock, 0)
|
||||
Return true if it was not previously scheduled.
|
||||
*/
|
||||
int event_deferred_cb_schedule_(struct event_base *, struct event_callback *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
void event_deferred_cb_queue_init(struct deferred_cb_queue *);
|
||||
struct deferred_cb_queue *event_base_get_deferred_cb_queue(struct event_base *);
|
||||
|
||||
#endif /* _EVENT_INTERNAL_H_ */
|
||||
#endif /* EVENT_INTERNAL_H_INCLUDED_ */
|
||||
|
||||
|
|
|
@ -1,707 +0,0 @@
|
|||
#! /bin/sh
|
||||
# depcomp - compile a program generating dependencies as side-effects
|
||||
|
||||
scriptversion=2012-03-27.16; # UTC
|
||||
|
||||
# Copyright (C) 1999-2012 Free Software Foundation, Inc.
|
||||
|
||||
# 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 2, 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try '$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Run PROGRAMS ARGS to compile a file, generating dependencies
|
||||
as side-effects.
|
||||
|
||||
Environment variables:
|
||||
depmode Dependency tracking mode.
|
||||
source Source file read by 'PROGRAMS ARGS'.
|
||||
object Object file output by 'PROGRAMS ARGS'.
|
||||
DEPDIR directory where to store dependencies.
|
||||
depfile Dependency file to output.
|
||||
tmpdepfile Temporary file to use when outputting dependencies.
|
||||
libtool Whether libtool is used (yes/no).
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "depcomp $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
|
||||
# A tabulation character.
|
||||
tab=' '
|
||||
# A newline character.
|
||||
nl='
|
||||
'
|
||||
|
||||
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
|
||||
echo "depcomp: Variables source, object and depmode must be set" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
|
||||
depfile=${depfile-`echo "$object" |
|
||||
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
|
||||
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
|
||||
|
||||
rm -f "$tmpdepfile"
|
||||
|
||||
# Some modes work just like other modes, but use different flags. We
|
||||
# parameterize here, but still list the modes in the big case below,
|
||||
# to make depend.m4 easier to write. Note that we *cannot* use a case
|
||||
# here, because this file can only contain one case statement.
|
||||
if test "$depmode" = hp; then
|
||||
# HP compiler uses -M and no extra arg.
|
||||
gccflag=-M
|
||||
depmode=gcc
|
||||
fi
|
||||
|
||||
if test "$depmode" = dashXmstdout; then
|
||||
# This is just like dashmstdout with a different argument.
|
||||
dashmflag=-xM
|
||||
depmode=dashmstdout
|
||||
fi
|
||||
|
||||
cygpath_u="cygpath -u -f -"
|
||||
if test "$depmode" = msvcmsys; then
|
||||
# This is just like msvisualcpp but w/o cygpath translation.
|
||||
# Just convert the backslash-escaped backslashes to single forward
|
||||
# slashes to satisfy depend.m4
|
||||
cygpath_u='sed s,\\\\,/,g'
|
||||
depmode=msvisualcpp
|
||||
fi
|
||||
|
||||
if test "$depmode" = msvc7msys; then
|
||||
# This is just like msvc7 but w/o cygpath translation.
|
||||
# Just convert the backslash-escaped backslashes to single forward
|
||||
# slashes to satisfy depend.m4
|
||||
cygpath_u='sed s,\\\\,/,g'
|
||||
depmode=msvc7
|
||||
fi
|
||||
|
||||
if test "$depmode" = xlc; then
|
||||
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency informations.
|
||||
gccflag=-qmakedep=gcc,-MF
|
||||
depmode=gcc
|
||||
fi
|
||||
|
||||
case "$depmode" in
|
||||
gcc3)
|
||||
## gcc 3 implements dependency tracking that does exactly what
|
||||
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
|
||||
## it if -MD -MP comes after the -MF stuff. Hmm.
|
||||
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
|
||||
## the command line argument order; so add the flags where they
|
||||
## appear in depend2.am. Note that the slowdown incurred here
|
||||
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
|
||||
*) set fnord "$@" "$arg" ;;
|
||||
esac
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
done
|
||||
"$@"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
mv "$tmpdepfile" "$depfile"
|
||||
;;
|
||||
|
||||
gcc)
|
||||
## There are various ways to get dependency output from gcc. Here's
|
||||
## why we pick this rather obscure method:
|
||||
## - Don't want to use -MD because we'd like the dependencies to end
|
||||
## up in a subdir. Having to rename by hand is ugly.
|
||||
## (We might end up doing this anyway to support other compilers.)
|
||||
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
|
||||
## -MM, not -M (despite what the docs say).
|
||||
## - Using -M directly means running the compiler twice (even worse
|
||||
## than renaming).
|
||||
if test -z "$gccflag"; then
|
||||
gccflag=-MD,
|
||||
fi
|
||||
"$@" -Wp,"$gccflag$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
|
||||
## The second -e expression handles DOS-style file names with drive letters.
|
||||
sed -e 's/^[^:]*: / /' \
|
||||
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
|
||||
## This next piece of magic avoids the "deleted header file" problem.
|
||||
## The problem is that when a header file which appears in a .P file
|
||||
## is deleted, the dependency causes make to die (because there is
|
||||
## typically no way to rebuild the header). We avoid this by adding
|
||||
## dummy dependencies for each header file. Too bad gcc doesn't do
|
||||
## this for us directly.
|
||||
tr ' ' "$nl" < "$tmpdepfile" |
|
||||
## Some versions of gcc put a space before the ':'. On the theory
|
||||
## that the space means something, we add a space to the output as
|
||||
## well. hp depmode also adds that space, but also prefixes the VPATH
|
||||
## to the object. Take care to not repeat it in the output.
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
|
||||
| sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
hp)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
sgi)
|
||||
if test "$libtool" = yes; then
|
||||
"$@" "-Wp,-MDupdate,$tmpdepfile"
|
||||
else
|
||||
"$@" -MDupdate "$tmpdepfile"
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
|
||||
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
|
||||
echo "$object : \\" > "$depfile"
|
||||
|
||||
# Clip off the initial element (the dependent). Don't try to be
|
||||
# clever and replace this with sed code, as IRIX sed won't handle
|
||||
# lines with more than a fixed number of characters (4096 in
|
||||
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
|
||||
# the IRIX cc adds comments like '#:fec' to the end of the
|
||||
# dependency line.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
|
||||
tr "$nl" ' ' >> "$depfile"
|
||||
echo >> "$depfile"
|
||||
|
||||
# The second pass generates a dummy entry for each header file.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
|
||||
>> "$depfile"
|
||||
else
|
||||
# The sourcefile does not contain any dependencies, so just
|
||||
# store a dummy comment line, to avoid errors with the Makefile
|
||||
# "include basename.Plo" scheme.
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
xlc)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
aix)
|
||||
# The C for AIX Compiler uses -M and outputs the dependencies
|
||||
# in a .u file. In older versions, this file always lives in the
|
||||
# current directory. Also, the AIX compiler puts '$object:' at the
|
||||
# start of each line; $object doesn't have directory information.
|
||||
# Version 6 uses the directory in both cases.
|
||||
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||
test "x$dir" = "x$object" && dir=
|
||||
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.u
|
||||
tmpdepfile2=$base.u
|
||||
tmpdepfile3=$dir.libs/$base.u
|
||||
"$@" -Wc,-M
|
||||
else
|
||||
tmpdepfile1=$dir$base.u
|
||||
tmpdepfile2=$dir$base.u
|
||||
tmpdepfile3=$dir$base.u
|
||||
"$@" -M
|
||||
fi
|
||||
stat=$?
|
||||
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
# Each line is of the form 'foo.o: dependent.h'.
|
||||
# Do two passes, one to just change these to
|
||||
# '$object: dependent.h' and one to simply 'dependent.h:'.
|
||||
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
|
||||
sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
# The sourcefile does not contain any dependencies, so just
|
||||
# store a dummy comment line, to avoid errors with the Makefile
|
||||
# "include basename.Plo" scheme.
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
icc)
|
||||
# Intel's C compiler anf tcc (Tiny C Compiler) understand '-MD -MF file'.
|
||||
# However on
|
||||
# $CC -MD -MF foo.d -c -o sub/foo.o sub/foo.c
|
||||
# ICC 7.0 will fill foo.d with something like
|
||||
# foo.o: sub/foo.c
|
||||
# foo.o: sub/foo.h
|
||||
# which is wrong. We want
|
||||
# sub/foo.o: sub/foo.c
|
||||
# sub/foo.o: sub/foo.h
|
||||
# sub/foo.c:
|
||||
# sub/foo.h:
|
||||
# ICC 7.1 will output
|
||||
# foo.o: sub/foo.c sub/foo.h
|
||||
# and will wrap long lines using '\':
|
||||
# foo.o: sub/foo.c ... \
|
||||
# sub/foo.h ... \
|
||||
# ...
|
||||
# tcc 0.9.26 (FIXME still under development at the moment of writing)
|
||||
# will emit a similar output, but also prepend the continuation lines
|
||||
# with horizontal tabulation characters.
|
||||
"$@" -MD -MF "$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
# Each line is of the form 'foo.o: dependent.h',
|
||||
# or 'foo.o: dep1.h dep2.h \', or ' dep3.h dep4.h \'.
|
||||
# Do two passes, one to just change these to
|
||||
# '$object: dependent.h' and one to simply 'dependent.h:'.
|
||||
sed -e "s/^[ $tab][ $tab]*/ /" -e "s,^[^:]*:,$object :," \
|
||||
< "$tmpdepfile" > "$depfile"
|
||||
sed '
|
||||
s/[ '"$tab"'][ '"$tab"']*/ /g
|
||||
s/^ *//
|
||||
s/ *\\*$//
|
||||
s/^[^:]*: *//
|
||||
/^$/d
|
||||
/:$/d
|
||||
s/$/ :/
|
||||
' < "$tmpdepfile" >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
hp2)
|
||||
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
|
||||
# compilers, which have integrated preprocessors. The correct option
|
||||
# to use with these is +Maked; it writes dependencies to a file named
|
||||
# 'foo.d', which lands next to the object file, wherever that
|
||||
# happens to be.
|
||||
# Much of this is similar to the tru64 case; see comments there.
|
||||
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||
test "x$dir" = "x$object" && dir=
|
||||
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir.libs/$base.d
|
||||
"$@" -Wc,+Maked
|
||||
else
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
"$@" +Maked
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
|
||||
# Add 'dependent.h:' lines.
|
||||
sed -ne '2,${
|
||||
s/^ *//
|
||||
s/ \\*$//
|
||||
s/$/:/
|
||||
p
|
||||
}' "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile" "$tmpdepfile2"
|
||||
;;
|
||||
|
||||
tru64)
|
||||
# The Tru64 compiler uses -MD to generate dependencies as a side
|
||||
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
|
||||
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
|
||||
# dependencies in 'foo.d' instead, so we check for that too.
|
||||
# Subdirectories are respected.
|
||||
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||
test "x$dir" = "x$object" && dir=
|
||||
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
|
||||
|
||||
if test "$libtool" = yes; then
|
||||
# With Tru64 cc, shared objects can also be used to make a
|
||||
# static library. This mechanism is used in libtool 1.4 series to
|
||||
# handle both shared and static libraries in a single compilation.
|
||||
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
|
||||
#
|
||||
# With libtool 1.5 this exception was removed, and libtool now
|
||||
# generates 2 separate objects for the 2 libraries. These two
|
||||
# compilations output dependencies in $dir.libs/$base.o.d and
|
||||
# in $dir$base.o.d. We have to check for both files, because
|
||||
# one of the two compilations can be disabled. We should prefer
|
||||
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
|
||||
# automatically cleaned when .libs/ is deleted, while ignoring
|
||||
# the former would cause a distcleancheck panic.
|
||||
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
|
||||
tmpdepfile2=$dir$base.o.d # libtool 1.5
|
||||
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
|
||||
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
|
||||
"$@" -Wc,-MD
|
||||
else
|
||||
tmpdepfile1=$dir$base.o.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
tmpdepfile3=$dir$base.d
|
||||
tmpdepfile4=$dir$base.d
|
||||
"$@" -MD
|
||||
fi
|
||||
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
|
||||
sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvc7)
|
||||
if test "$libtool" = yes; then
|
||||
showIncludes=-Wc,-showIncludes
|
||||
else
|
||||
showIncludes=-showIncludes
|
||||
fi
|
||||
"$@" $showIncludes > "$tmpdepfile"
|
||||
stat=$?
|
||||
grep -v '^Note: including file: ' "$tmpdepfile"
|
||||
if test "$stat" = 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
# The first sed program below extracts the file names and escapes
|
||||
# backslashes for cygpath. The second sed program outputs the file
|
||||
# name when reading, but also accumulates all include files in the
|
||||
# hold buffer in order to output them again at the end. This only
|
||||
# works with sed implementations that can handle large buffers.
|
||||
sed < "$tmpdepfile" -n '
|
||||
/^Note: including file: *\(.*\)/ {
|
||||
s//\1/
|
||||
s/\\/\\\\/g
|
||||
p
|
||||
}' | $cygpath_u | sort -u | sed -n '
|
||||
s/ /\\ /g
|
||||
s/\(.*\)/'"$tab"'\1 \\/p
|
||||
s/.\(.*\) \\/\1:/
|
||||
H
|
||||
$ {
|
||||
s/.*/'"$tab"'/
|
||||
G
|
||||
p
|
||||
}' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvc7msys)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
#nosideeffect)
|
||||
# This comment above is used by automake to tell side-effect
|
||||
# dependency tracking mechanisms from slower ones.
|
||||
|
||||
dashmstdout)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout, regardless of -o.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove '-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
test -z "$dashmflag" && dashmflag=-M
|
||||
# Require at least two characters before searching for ':'
|
||||
# in the target name. This is to cope with DOS-style filenames:
|
||||
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
|
||||
"$@" $dashmflag |
|
||||
sed 's:^['"$tab"' ]*[^:'"$tab"' ][^:][^:]*\:['"$tab"' ]*:'"$object"'\: :' > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
cat < "$tmpdepfile" > "$depfile"
|
||||
tr ' ' "$nl" < "$tmpdepfile" | \
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
dashXmstdout)
|
||||
# This case only exists to satisfy depend.m4. It is never actually
|
||||
# run, as this mode is specially recognized in the preamble.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
makedepend)
|
||||
"$@" || exit $?
|
||||
# Remove any Libtool call
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
# X makedepend
|
||||
shift
|
||||
cleared=no eat=no
|
||||
for arg
|
||||
do
|
||||
case $cleared in
|
||||
no)
|
||||
set ""; shift
|
||||
cleared=yes ;;
|
||||
esac
|
||||
if test $eat = yes; then
|
||||
eat=no
|
||||
continue
|
||||
fi
|
||||
case "$arg" in
|
||||
-D*|-I*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
# Strip any option that makedepend may not understand. Remove
|
||||
# the object too, otherwise makedepend will parse it as a source file.
|
||||
-arch)
|
||||
eat=yes ;;
|
||||
-*|$object)
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
esac
|
||||
done
|
||||
obj_suffix=`echo "$object" | sed 's/^.*\././'`
|
||||
touch "$tmpdepfile"
|
||||
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
|
||||
rm -f "$depfile"
|
||||
# makedepend may prepend the VPATH from the source file name to the object.
|
||||
# No need to regex-escape $object, excess matching of '.' is harmless.
|
||||
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
|
||||
sed '1,2d' "$tmpdepfile" | tr ' ' "$nl" | \
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile" "$tmpdepfile".bak
|
||||
;;
|
||||
|
||||
cpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove '-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
"$@" -E |
|
||||
sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
|
||||
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
|
||||
sed '$ s: \\$::' > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
cat < "$tmpdepfile" >> "$depfile"
|
||||
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvisualcpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case "$arg" in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
|
||||
set fnord "$@"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
"$@" -E 2>/dev/null |
|
||||
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
|
||||
echo "$tab" >> "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvcmsys)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
none)
|
||||
exec "$@"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unknown depmode $depmode" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
|
@ -25,10 +25,13 @@
|
|||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "event2/event-config.h"
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#ifdef EVENT__HAVE_DEVPOLL
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/resource.h>
|
||||
#ifdef _EVENT_HAVE_SYS_TIME_H
|
||||
#ifdef EVENT__HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include <sys/queue.h>
|
||||
|
@ -129,7 +132,7 @@ devpoll_init(struct event_base *base)
|
|||
nfiles = rl.rlim_cur;
|
||||
|
||||
/* Initialize the kernel queue */
|
||||
if ((dpfd = evutil_open_closeonexec("/dev/poll", O_RDWR, 0)) == -1) {
|
||||
if ((dpfd = evutil_open_closeonexec_("/dev/poll", O_RDWR, 0)) == -1) {
|
||||
event_warn("open: /dev/poll");
|
||||
mm_free(devpollop);
|
||||
return (NULL);
|
||||
|
@ -156,7 +159,7 @@ devpoll_init(struct event_base *base)
|
|||
return (NULL);
|
||||
}
|
||||
|
||||
evsig_init(base);
|
||||
evsig_init_(base);
|
||||
|
||||
return (devpollop);
|
||||
}
|
||||
|
@ -214,7 +217,7 @@ devpoll_dispatch(struct event_base *base, struct timeval *tv)
|
|||
continue;
|
||||
|
||||
/* XXX(niels): not sure if this works for devpoll */
|
||||
evmap_io_active(base, events[i].fd, which);
|
||||
evmap_io_active_(base, events[i].fd, which);
|
||||
}
|
||||
|
||||
return (0);
|
||||
|
@ -293,7 +296,7 @@ devpoll_dealloc(struct event_base *base)
|
|||
{
|
||||
struct devpollop *devpollop = base->evbase;
|
||||
|
||||
evsig_dealloc(base);
|
||||
evsig_dealloc_(base);
|
||||
if (devpollop->events)
|
||||
mm_free(devpollop->events);
|
||||
if (devpollop->changes)
|
||||
|
@ -304,3 +307,5 @@ devpoll_dealloc(struct event_base *base)
|
|||
memset(devpollop, 0, sizeof(struct devpollop));
|
||||
mm_free(devpollop);
|
||||
}
|
||||
|
||||
#endif /* EVENT__HAVE_DEVPOLL */
|
||||
|
|
|
@ -25,11 +25,14 @@
|
|||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "event2/event-config.h"
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#ifdef EVENT__HAVE_EPOLL
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/resource.h>
|
||||
#ifdef _EVENT_HAVE_SYS_TIME_H
|
||||
#ifdef EVENT__HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include <sys/queue.h>
|
||||
|
@ -41,9 +44,12 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#ifdef _EVENT_HAVE_FCNTL_H
|
||||
#ifdef EVENT__HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#ifdef EVENT__HAVE_SYS_TIMERFD_H
|
||||
#include <sys/timerfd.h>
|
||||
#endif
|
||||
|
||||
#include "event-internal.h"
|
||||
#include "evsignal-internal.h"
|
||||
|
@ -52,11 +58,38 @@
|
|||
#include "log-internal.h"
|
||||
#include "evmap-internal.h"
|
||||
#include "changelist-internal.h"
|
||||
#include "time-internal.h"
|
||||
|
||||
/* Since Linux 2.6.17, epoll is able to report about peer half-closed connection
|
||||
using special EPOLLRDHUP flag on a read event.
|
||||
*/
|
||||
#if !defined(EPOLLRDHUP)
|
||||
#define EPOLLRDHUP 0
|
||||
#define EARLY_CLOSE_IF_HAVE_RDHUP 0
|
||||
#else
|
||||
#define EARLY_CLOSE_IF_HAVE_RDHUP EV_FEATURE_EARLY_CLOSE
|
||||
#endif
|
||||
|
||||
#include "epolltable-internal.h"
|
||||
|
||||
#if defined(EVENT__HAVE_SYS_TIMERFD_H) && \
|
||||
defined(EVENT__HAVE_TIMERFD_CREATE) && \
|
||||
defined(HAVE_POSIX_MONOTONIC) && defined(TFD_NONBLOCK) && \
|
||||
defined(TFD_CLOEXEC)
|
||||
/* Note that we only use timerfd if TFD_NONBLOCK and TFD_CLOEXEC are available
|
||||
and working. This means that we can't support it on 2.6.25 (where timerfd
|
||||
was introduced) or 2.6.26, since 2.6.27 introduced those flags.
|
||||
*/
|
||||
#define USING_TIMERFD
|
||||
#endif
|
||||
|
||||
struct epollop {
|
||||
struct epoll_event *events;
|
||||
int nevents;
|
||||
int epfd;
|
||||
#ifdef USING_TIMERFD
|
||||
int timerfd;
|
||||
#endif
|
||||
};
|
||||
|
||||
static void *epoll_init(struct event_base *);
|
||||
|
@ -66,12 +99,12 @@ static void epoll_dealloc(struct event_base *);
|
|||
static const struct eventop epollops_changelist = {
|
||||
"epoll (with changelist)",
|
||||
epoll_init,
|
||||
event_changelist_add,
|
||||
event_changelist_del,
|
||||
event_changelist_add_,
|
||||
event_changelist_del_,
|
||||
epoll_dispatch,
|
||||
epoll_dealloc,
|
||||
1, /* need reinit */
|
||||
EV_FEATURE_ET|EV_FEATURE_O1,
|
||||
EV_FEATURE_ET|EV_FEATURE_O1| EARLY_CLOSE_IF_HAVE_RDHUP,
|
||||
EVENT_CHANGELIST_FDINFO_SIZE
|
||||
};
|
||||
|
||||
|
@ -89,7 +122,7 @@ const struct eventop epollops = {
|
|||
epoll_dispatch,
|
||||
epoll_dealloc,
|
||||
1, /* need reinit */
|
||||
EV_FEATURE_ET|EV_FEATURE_O1,
|
||||
EV_FEATURE_ET|EV_FEATURE_O1|EV_FEATURE_EARLY_CLOSE,
|
||||
0
|
||||
};
|
||||
|
||||
|
@ -107,19 +140,24 @@ const struct eventop epollops = {
|
|||
static void *
|
||||
epoll_init(struct event_base *base)
|
||||
{
|
||||
int epfd;
|
||||
int epfd = -1;
|
||||
struct epollop *epollop;
|
||||
|
||||
/* Initialize the kernel queue. (The size field is ignored since
|
||||
* 2.6.8.) */
|
||||
if ((epfd = epoll_create(32000)) == -1) {
|
||||
if (errno != ENOSYS)
|
||||
event_warn("epoll_create");
|
||||
return (NULL);
|
||||
#ifdef EVENT__HAVE_EPOLL_CREATE1
|
||||
/* First, try the shiny new epoll_create1 interface, if we have it. */
|
||||
epfd = epoll_create1(EPOLL_CLOEXEC);
|
||||
#endif
|
||||
if (epfd == -1) {
|
||||
/* Initialize the kernel queue using the old interface. (The
|
||||
size field is ignored since 2.6.8.) */
|
||||
if ((epfd = epoll_create(32000)) == -1) {
|
||||
if (errno != ENOSYS)
|
||||
event_warn("epoll_create");
|
||||
return (NULL);
|
||||
}
|
||||
evutil_make_socket_closeonexec(epfd);
|
||||
}
|
||||
|
||||
evutil_make_socket_closeonexec(epfd);
|
||||
|
||||
if (!(epollop = mm_calloc(1, sizeof(struct epollop)))) {
|
||||
close(epfd);
|
||||
return (NULL);
|
||||
|
@ -138,10 +176,48 @@ epoll_init(struct event_base *base)
|
|||
|
||||
if ((base->flags & EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST) != 0 ||
|
||||
((base->flags & EVENT_BASE_FLAG_IGNORE_ENV) == 0 &&
|
||||
evutil_getenv("EVENT_EPOLL_USE_CHANGELIST") != NULL))
|
||||
base->evsel = &epollops_changelist;
|
||||
evutil_getenv_("EVENT_EPOLL_USE_CHANGELIST") != NULL)) {
|
||||
|
||||
evsig_init(base);
|
||||
base->evsel = &epollops_changelist;
|
||||
}
|
||||
|
||||
#ifdef USING_TIMERFD
|
||||
/*
|
||||
The epoll interface ordinarily gives us one-millisecond precision,
|
||||
so on Linux it makes perfect sense to use the CLOCK_MONOTONIC_COARSE
|
||||
timer. But when the user has set the new PRECISE_TIMER flag for an
|
||||
event_base, we can try to use timerfd to give them finer granularity.
|
||||
*/
|
||||
if ((base->flags & EVENT_BASE_FLAG_PRECISE_TIMER) &&
|
||||
base->monotonic_timer.monotonic_clock == CLOCK_MONOTONIC) {
|
||||
int fd;
|
||||
fd = epollop->timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC);
|
||||
if (epollop->timerfd >= 0) {
|
||||
struct epoll_event epev;
|
||||
memset(&epev, 0, sizeof(epev));
|
||||
epev.data.fd = epollop->timerfd;
|
||||
epev.events = EPOLLIN;
|
||||
if (epoll_ctl(epollop->epfd, EPOLL_CTL_ADD, fd, &epev) < 0) {
|
||||
event_warn("epoll_ctl(timerfd)");
|
||||
close(fd);
|
||||
epollop->timerfd = -1;
|
||||
}
|
||||
} else {
|
||||
if (errno != EINVAL && errno != ENOSYS) {
|
||||
/* These errors probably mean that we were
|
||||
* compiled with timerfd/TFD_* support, but
|
||||
* we're running on a kernel that lacks those.
|
||||
*/
|
||||
event_warn("timerfd_create");
|
||||
}
|
||||
epollop->timerfd = -1;
|
||||
}
|
||||
} else {
|
||||
epollop->timerfd = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
evsig_init_(base);
|
||||
|
||||
return (epollop);
|
||||
}
|
||||
|
@ -170,6 +246,23 @@ epoll_op_to_string(int op)
|
|||
"???";
|
||||
}
|
||||
|
||||
#define PRINT_CHANGES(op, events, ch, status) \
|
||||
"Epoll %s(%d) on fd %d " status ". " \
|
||||
"Old events were %d; " \
|
||||
"read change was %d (%s); " \
|
||||
"write change was %d (%s); " \
|
||||
"close change was %d (%s)", \
|
||||
epoll_op_to_string(op), \
|
||||
events, \
|
||||
ch->fd, \
|
||||
ch->old_events, \
|
||||
ch->read_change, \
|
||||
change_to_string(ch->read_change), \
|
||||
ch->write_change, \
|
||||
change_to_string(ch->write_change), \
|
||||
ch->close_change, \
|
||||
change_to_string(ch->close_change)
|
||||
|
||||
static int
|
||||
epoll_apply_one_change(struct event_base *base,
|
||||
struct epollop *epollop,
|
||||
|
@ -177,156 +270,86 @@ epoll_apply_one_change(struct event_base *base,
|
|||
{
|
||||
struct epoll_event epev;
|
||||
int op, events = 0;
|
||||
int idx;
|
||||
|
||||
if (1) {
|
||||
/* The logic here is a little tricky. If we had no events set
|
||||
on the fd before, we need to set op="ADD" and set
|
||||
events=the events we want to add. If we had any events set
|
||||
on the fd before, and we want any events to remain on the
|
||||
fd, we need to say op="MOD" and set events=the events we
|
||||
want to remain. But if we want to delete the last event,
|
||||
we say op="DEL" and set events=the remaining events. What
|
||||
fun!
|
||||
*/
|
||||
idx = EPOLL_OP_TABLE_INDEX(ch);
|
||||
op = epoll_op_table[idx].op;
|
||||
events = epoll_op_table[idx].events;
|
||||
|
||||
/* TODO: Turn this into a switch or a table lookup. */
|
||||
|
||||
if ((ch->read_change & EV_CHANGE_ADD) ||
|
||||
(ch->write_change & EV_CHANGE_ADD)) {
|
||||
/* If we are adding anything at all, we'll want to do
|
||||
* either an ADD or a MOD. */
|
||||
events = 0;
|
||||
op = EPOLL_CTL_ADD;
|
||||
if (ch->read_change & EV_CHANGE_ADD) {
|
||||
events |= EPOLLIN;
|
||||
} else if (ch->read_change & EV_CHANGE_DEL) {
|
||||
;
|
||||
} else if (ch->old_events & EV_READ) {
|
||||
events |= EPOLLIN;
|
||||
}
|
||||
if (ch->write_change & EV_CHANGE_ADD) {
|
||||
events |= EPOLLOUT;
|
||||
} else if (ch->write_change & EV_CHANGE_DEL) {
|
||||
;
|
||||
} else if (ch->old_events & EV_WRITE) {
|
||||
events |= EPOLLOUT;
|
||||
}
|
||||
if ((ch->read_change|ch->write_change) & EV_ET)
|
||||
events |= EPOLLET;
|
||||
|
||||
if (ch->old_events) {
|
||||
/* If MOD fails, we retry as an ADD, and if
|
||||
* ADD fails we will retry as a MOD. So the
|
||||
* only hard part here is to guess which one
|
||||
* will work. As a heuristic, we'll try
|
||||
* MOD first if we think there were old
|
||||
* events and ADD if we think there were none.
|
||||
*
|
||||
* We can be wrong about the MOD if the file
|
||||
* has in fact been closed and re-opened.
|
||||
*
|
||||
* We can be wrong about the ADD if the
|
||||
* the fd has been re-created with a dup()
|
||||
* of the same file that it was before.
|
||||
*/
|
||||
op = EPOLL_CTL_MOD;
|
||||
}
|
||||
} else if ((ch->read_change & EV_CHANGE_DEL) ||
|
||||
(ch->write_change & EV_CHANGE_DEL)) {
|
||||
/* If we're deleting anything, we'll want to do a MOD
|
||||
* or a DEL. */
|
||||
op = EPOLL_CTL_DEL;
|
||||
|
||||
if (ch->read_change & EV_CHANGE_DEL) {
|
||||
if (ch->write_change & EV_CHANGE_DEL) {
|
||||
events = EPOLLIN|EPOLLOUT;
|
||||
} else if (ch->old_events & EV_WRITE) {
|
||||
events = EPOLLOUT;
|
||||
op = EPOLL_CTL_MOD;
|
||||
} else {
|
||||
events = EPOLLIN;
|
||||
}
|
||||
} else if (ch->write_change & EV_CHANGE_DEL) {
|
||||
if (ch->old_events & EV_READ) {
|
||||
events = EPOLLIN;
|
||||
op = EPOLL_CTL_MOD;
|
||||
} else {
|
||||
events = EPOLLOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!events)
|
||||
return 0;
|
||||
|
||||
memset(&epev, 0, sizeof(epev));
|
||||
epev.data.fd = ch->fd;
|
||||
epev.events = events;
|
||||
if (epoll_ctl(epollop->epfd, op, ch->fd, &epev) == -1) {
|
||||
if (op == EPOLL_CTL_MOD && errno == ENOENT) {
|
||||
/* If a MOD operation fails with ENOENT, the
|
||||
* fd was probably closed and re-opened. We
|
||||
* should retry the operation as an ADD.
|
||||
*/
|
||||
if (epoll_ctl(epollop->epfd, EPOLL_CTL_ADD, ch->fd, &epev) == -1) {
|
||||
event_warn("Epoll MOD(%d) on %d retried as ADD; that failed too",
|
||||
(int)epev.events, ch->fd);
|
||||
return -1;
|
||||
} else {
|
||||
event_debug(("Epoll MOD(%d) on %d retried as ADD; succeeded.",
|
||||
(int)epev.events,
|
||||
ch->fd));
|
||||
}
|
||||
} else if (op == EPOLL_CTL_ADD && errno == EEXIST) {
|
||||
/* If an ADD operation fails with EEXIST,
|
||||
* either the operation was redundant (as with a
|
||||
* precautionary add), or we ran into a fun
|
||||
* kernel bug where using dup*() to duplicate the
|
||||
* same file into the same fd gives you the same epitem
|
||||
* rather than a fresh one. For the second case,
|
||||
* we must retry with MOD. */
|
||||
if (epoll_ctl(epollop->epfd, EPOLL_CTL_MOD, ch->fd, &epev) == -1) {
|
||||
event_warn("Epoll ADD(%d) on %d retried as MOD; that failed too",
|
||||
(int)epev.events, ch->fd);
|
||||
return -1;
|
||||
} else {
|
||||
event_debug(("Epoll ADD(%d) on %d retried as MOD; succeeded.",
|
||||
(int)epev.events,
|
||||
ch->fd));
|
||||
}
|
||||
} else if (op == EPOLL_CTL_DEL &&
|
||||
(errno == ENOENT || errno == EBADF ||
|
||||
errno == EPERM)) {
|
||||
/* If a delete fails with one of these errors,
|
||||
* that's fine too: we closed the fd before we
|
||||
* got around to calling epoll_dispatch. */
|
||||
event_debug(("Epoll DEL(%d) on fd %d gave %s: DEL was unnecessary.",
|
||||
(int)epev.events,
|
||||
ch->fd,
|
||||
strerror(errno)));
|
||||
} else {
|
||||
event_warn("Epoll %s(%d) on fd %d failed. Old events were %d; read change was %d (%s); write change was %d (%s)",
|
||||
epoll_op_to_string(op),
|
||||
(int)epev.events,
|
||||
ch->fd,
|
||||
ch->old_events,
|
||||
ch->read_change,
|
||||
change_to_string(ch->read_change),
|
||||
ch->write_change,
|
||||
change_to_string(ch->write_change));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
event_debug(("Epoll %s(%d) on fd %d okay. [old events were %d; read change was %d; write change was %d]",
|
||||
epoll_op_to_string(op),
|
||||
(int)epev.events,
|
||||
(int)ch->fd,
|
||||
ch->old_events,
|
||||
ch->read_change,
|
||||
ch->write_change));
|
||||
}
|
||||
if (!events) {
|
||||
EVUTIL_ASSERT(op == 0);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
|
||||
if ((ch->read_change|ch->write_change) & EV_CHANGE_ET)
|
||||
events |= EPOLLET;
|
||||
|
||||
memset(&epev, 0, sizeof(epev));
|
||||
epev.data.fd = ch->fd;
|
||||
epev.events = events;
|
||||
if (epoll_ctl(epollop->epfd, op, ch->fd, &epev) == 0) {
|
||||
event_debug((PRINT_CHANGES(op, epev.events, ch, "okay")));
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
case EPOLL_CTL_MOD:
|
||||
if (errno == ENOENT) {
|
||||
/* If a MOD operation fails with ENOENT, the
|
||||
* fd was probably closed and re-opened. We
|
||||
* should retry the operation as an ADD.
|
||||
*/
|
||||
if (epoll_ctl(epollop->epfd, EPOLL_CTL_ADD, ch->fd, &epev) == -1) {
|
||||
event_warn("Epoll MOD(%d) on %d retried as ADD; that failed too",
|
||||
(int)epev.events, ch->fd);
|
||||
return -1;
|
||||
} else {
|
||||
event_debug(("Epoll MOD(%d) on %d retried as ADD; succeeded.",
|
||||
(int)epev.events,
|
||||
ch->fd));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EPOLL_CTL_ADD:
|
||||
if (errno == EEXIST) {
|
||||
/* If an ADD operation fails with EEXIST,
|
||||
* either the operation was redundant (as with a
|
||||
* precautionary add), or we ran into a fun
|
||||
* kernel bug where using dup*() to duplicate the
|
||||
* same file into the same fd gives you the same epitem
|
||||
* rather than a fresh one. For the second case,
|
||||
* we must retry with MOD. */
|
||||
if (epoll_ctl(epollop->epfd, EPOLL_CTL_MOD, ch->fd, &epev) == -1) {
|
||||
event_warn("Epoll ADD(%d) on %d retried as MOD; that failed too",
|
||||
(int)epev.events, ch->fd);
|
||||
return -1;
|
||||
} else {
|
||||
event_debug(("Epoll ADD(%d) on %d retried as MOD; succeeded.",
|
||||
(int)epev.events,
|
||||
ch->fd));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EPOLL_CTL_DEL:
|
||||
if (errno == ENOENT || errno == EBADF || errno == EPERM) {
|
||||
/* If a delete fails with one of these errors,
|
||||
* that's fine too: we closed the fd before we
|
||||
* got around to calling epoll_dispatch. */
|
||||
event_debug(("Epoll DEL(%d) on fd %d gave %s: DEL was unnecessary.",
|
||||
(int)epev.events,
|
||||
ch->fd,
|
||||
strerror(errno)));
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
event_warn(PRINT_CHANGES(op, epev.events, ch, "failed"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -355,13 +378,16 @@ epoll_nochangelist_add(struct event_base *base, evutil_socket_t fd,
|
|||
struct event_change ch;
|
||||
ch.fd = fd;
|
||||
ch.old_events = old;
|
||||
ch.read_change = ch.write_change = 0;
|
||||
ch.read_change = ch.write_change = ch.close_change = 0;
|
||||
if (events & EV_WRITE)
|
||||
ch.write_change = EV_CHANGE_ADD |
|
||||
(events & EV_ET);
|
||||
if (events & EV_READ)
|
||||
ch.read_change = EV_CHANGE_ADD |
|
||||
(events & EV_ET);
|
||||
if (events & EV_CLOSED)
|
||||
ch.close_change = EV_CHANGE_ADD |
|
||||
(events & EV_ET);
|
||||
|
||||
return epoll_apply_one_change(base, base->evbase, &ch);
|
||||
}
|
||||
|
@ -373,11 +399,13 @@ epoll_nochangelist_del(struct event_base *base, evutil_socket_t fd,
|
|||
struct event_change ch;
|
||||
ch.fd = fd;
|
||||
ch.old_events = old;
|
||||
ch.read_change = ch.write_change = 0;
|
||||
ch.read_change = ch.write_change = ch.close_change = 0;
|
||||
if (events & EV_WRITE)
|
||||
ch.write_change = EV_CHANGE_DEL;
|
||||
if (events & EV_READ)
|
||||
ch.read_change = EV_CHANGE_DEL;
|
||||
if (events & EV_CLOSED)
|
||||
ch.close_change = EV_CHANGE_DEL;
|
||||
|
||||
return epoll_apply_one_change(base, base->evbase, &ch);
|
||||
}
|
||||
|
@ -390,8 +418,35 @@ epoll_dispatch(struct event_base *base, struct timeval *tv)
|
|||
int i, res;
|
||||
long timeout = -1;
|
||||
|
||||
#ifdef USING_TIMERFD
|
||||
if (epollop->timerfd >= 0) {
|
||||
struct itimerspec is;
|
||||
is.it_interval.tv_sec = 0;
|
||||
is.it_interval.tv_nsec = 0;
|
||||
if (tv == NULL) {
|
||||
/* No timeout; disarm the timer. */
|
||||
is.it_value.tv_sec = 0;
|
||||
is.it_value.tv_nsec = 0;
|
||||
} else {
|
||||
if (tv->tv_sec == 0 && tv->tv_usec == 0) {
|
||||
/* we need to exit immediately; timerfd can't
|
||||
* do that. */
|
||||
timeout = 0;
|
||||
}
|
||||
is.it_value.tv_sec = tv->tv_sec;
|
||||
is.it_value.tv_nsec = tv->tv_usec * 1000;
|
||||
}
|
||||
/* TODO: we could avoid unnecessary syscalls here by only
|
||||
calling timerfd_settime when the top timeout changes, or
|
||||
when we're called with a different timeval.
|
||||
*/
|
||||
if (timerfd_settime(epollop->timerfd, 0, &is, NULL) < 0) {
|
||||
event_warn("timerfd_settime");
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (tv != NULL) {
|
||||
timeout = evutil_tv_to_msec(tv);
|
||||
timeout = evutil_tv_to_msec_(tv);
|
||||
if (timeout < 0 || timeout > MAX_EPOLL_TIMEOUT_MSEC) {
|
||||
/* Linux kernels can wait forever if the timeout is
|
||||
* too big; see comment on MAX_EPOLL_TIMEOUT_MSEC. */
|
||||
|
@ -400,7 +455,7 @@ epoll_dispatch(struct event_base *base, struct timeval *tv)
|
|||
}
|
||||
|
||||
epoll_apply_changes(base);
|
||||
event_changelist_remove_all(&base->changelist, base);
|
||||
event_changelist_remove_all_(&base->changelist, base);
|
||||
|
||||
EVBASE_RELEASE_LOCK(base, th_base_lock);
|
||||
|
||||
|
@ -423,6 +478,10 @@ epoll_dispatch(struct event_base *base, struct timeval *tv)
|
|||
for (i = 0; i < res; i++) {
|
||||
int what = events[i].events;
|
||||
short ev = 0;
|
||||
#ifdef USING_TIMERFD
|
||||
if (events[i].data.fd == epollop->timerfd)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
if (what & (EPOLLHUP|EPOLLERR)) {
|
||||
ev = EV_READ | EV_WRITE;
|
||||
|
@ -431,12 +490,14 @@ epoll_dispatch(struct event_base *base, struct timeval *tv)
|
|||
ev |= EV_READ;
|
||||
if (what & EPOLLOUT)
|
||||
ev |= EV_WRITE;
|
||||
if (what & EPOLLRDHUP)
|
||||
ev |= EV_CLOSED;
|
||||
}
|
||||
|
||||
if (!ev)
|
||||
continue;
|
||||
|
||||
evmap_io_active(base, events[i].data.fd, ev | EV_ET);
|
||||
evmap_io_active_(base, events[i].data.fd, ev | EV_ET);
|
||||
}
|
||||
|
||||
if (res == epollop->nevents && epollop->nevents < MAX_NEVENT) {
|
||||
|
@ -462,12 +523,18 @@ epoll_dealloc(struct event_base *base)
|
|||
{
|
||||
struct epollop *epollop = base->evbase;
|
||||
|
||||
evsig_dealloc(base);
|
||||
evsig_dealloc_(base);
|
||||
if (epollop->events)
|
||||
mm_free(epollop->events);
|
||||
if (epollop->epfd >= 0)
|
||||
close(epollop->epfd);
|
||||
#ifdef USING_TIMERFD
|
||||
if (epollop->timerfd >= 0)
|
||||
close(epollop->timerfd);
|
||||
#endif
|
||||
|
||||
memset(epollop, 0, sizeof(struct epollop));
|
||||
mm_free(epollop);
|
||||
}
|
||||
|
||||
#endif /* EVENT__HAVE_EPOLL */
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "evconfig-private.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -24,15 +24,17 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _EVBUFFER_INTERNAL_H_
|
||||
#define _EVBUFFER_INTERNAL_H_
|
||||
#ifndef EVBUFFER_INTERNAL_H_INCLUDED_
|
||||
#define EVBUFFER_INTERNAL_H_INCLUDED_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "event2/event-config.h"
|
||||
#include "evconfig-private.h"
|
||||
#include "event2/util.h"
|
||||
#include "event2/event_struct.h"
|
||||
#include "util-internal.h"
|
||||
#include "defer-internal.h"
|
||||
|
||||
|
@ -41,7 +43,7 @@ extern "C" {
|
|||
* arguments. */
|
||||
#define EVBUFFER_CB_NODEFER 2
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
#include <sys/queue.h>
|
||||
|
@ -49,7 +51,7 @@ extern "C" {
|
|||
/* Minimum allocation for a chain. We define this so that we're burning no
|
||||
* more than 5% of each allocation on overhead. It would be nice to lose even
|
||||
* less space, though. */
|
||||
#if _EVENT_SIZEOF_VOID_P < 8
|
||||
#if EVENT__SIZEOF_VOID_P < 8
|
||||
#define MIN_BUFFER_SIZE 512
|
||||
#else
|
||||
#define MIN_BUFFER_SIZE 1024
|
||||
|
@ -59,7 +61,7 @@ extern "C" {
|
|||
* when bytes are added to or removed from the evbuffer. */
|
||||
struct evbuffer_cb_entry {
|
||||
/** Structures to implement a doubly-linked queue of callbacks */
|
||||
TAILQ_ENTRY(evbuffer_cb_entry) next;
|
||||
LIST_ENTRY(evbuffer_cb_entry) next;
|
||||
/** The callback function to invoke when this callback is called.
|
||||
If EVBUFFER_CB_OBSOLETE is set in flags, the cb_obsolete field is
|
||||
valid; otherwise, cb_func is valid. */
|
||||
|
@ -106,7 +108,7 @@ struct evbuffer {
|
|||
* tried to invoke callbacks. */
|
||||
size_t n_del_for_cb;
|
||||
|
||||
#ifndef _EVENT_DISABLE_THREAD_SUPPORT
|
||||
#ifndef EVENT__DISABLE_THREAD_SUPPORT
|
||||
/** A lock used to mediate access to this buffer. */
|
||||
void *lock;
|
||||
#endif
|
||||
|
@ -125,7 +127,7 @@ struct evbuffer {
|
|||
* overflows when we have mutually recursive callbacks, and for
|
||||
* serializing callbacks in a single thread. */
|
||||
unsigned deferred_cbs : 1;
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
/** True iff this buffer is set up for overlapped IO. */
|
||||
unsigned is_overlapped : 1;
|
||||
#endif
|
||||
|
@ -133,7 +135,7 @@ struct evbuffer {
|
|||
ev_uint32_t flags;
|
||||
|
||||
/** Used to implement deferred callbacks. */
|
||||
struct deferred_cb_queue *cb_queue;
|
||||
struct event_base *cb_queue;
|
||||
|
||||
/** A reference count on this evbuffer. When the reference count
|
||||
* reaches 0, the buffer is destroyed. Manipulated with
|
||||
|
@ -141,24 +143,24 @@ struct evbuffer {
|
|||
* evbuffer_free. */
|
||||
int refcnt;
|
||||
|
||||
/** A deferred_cb handle to make all of this buffer's callbacks
|
||||
/** A struct event_callback handle to make all of this buffer's callbacks
|
||||
* invoked from the event loop. */
|
||||
struct deferred_cb deferred;
|
||||
struct event_callback deferred;
|
||||
|
||||
/** A doubly-linked-list of callback functions */
|
||||
TAILQ_HEAD(evbuffer_cb_queue, evbuffer_cb_entry) callbacks;
|
||||
LIST_HEAD(evbuffer_cb_queue, evbuffer_cb_entry) callbacks;
|
||||
|
||||
/** The parent bufferevent object this evbuffer belongs to.
|
||||
* NULL if the evbuffer stands alone. */
|
||||
struct bufferevent *parent;
|
||||
};
|
||||
|
||||
#if _EVENT_SIZEOF_OFF_T < _EVENT_SIZEOF_SIZE_T
|
||||
#if EVENT__SIZEOF_OFF_T < EVENT__SIZEOF_SIZE_T
|
||||
typedef ev_ssize_t ev_misalign_t;
|
||||
#define EVBUFFER_CHAIN_MAX ((size_t)EV_SSIZE_MAX)
|
||||
#else
|
||||
typedef ev_off_t ev_misalign_t;
|
||||
#if _EVENT_SIZEOF_OFF_T > _EVENT_SIZEOF_SIZE_T
|
||||
#if EVENT__SIZEOF_OFF_T > EVENT__SIZEOF_SIZE_T
|
||||
#define EVBUFFER_CHAIN_MAX EV_SIZE_MAX
|
||||
#else
|
||||
#define EVBUFFER_CHAIN_MAX ((size_t)EV_SSIZE_MAX)
|
||||
|
@ -184,8 +186,8 @@ struct evbuffer_chain {
|
|||
|
||||
/** Set if special handling is required for this chain */
|
||||
unsigned flags;
|
||||
#define EVBUFFER_MMAP 0x0001 /**< memory in buffer is mmaped */
|
||||
#define EVBUFFER_SENDFILE 0x0002 /**< a chain used for sendfile */
|
||||
#define EVBUFFER_FILESEGMENT 0x0001 /**< A chain used for a file segment */
|
||||
#define EVBUFFER_SENDFILE 0x0002 /**< a chain used with sendfile */
|
||||
#define EVBUFFER_REFERENCE 0x0004 /**< a chain with a mem reference */
|
||||
#define EVBUFFER_IMMUTABLE 0x0008 /**< read-only chain */
|
||||
/** a chain that mustn't be reallocated or freed, or have its contents
|
||||
|
@ -196,6 +198,11 @@ struct evbuffer_chain {
|
|||
/** a chain that should be freed, but can't be freed until it is
|
||||
* un-pinned. */
|
||||
#define EVBUFFER_DANGLING 0x0040
|
||||
/** a chain that is a referenced copy of another chain */
|
||||
#define EVBUFFER_MULTICAST 0x0080
|
||||
|
||||
/** number of references to this chain */
|
||||
int refcnt;
|
||||
|
||||
/** Usually points to the read-write memory belonging to this
|
||||
* buffer allocated as part of the evbuffer_chain allocation.
|
||||
|
@ -206,21 +213,67 @@ struct evbuffer_chain {
|
|||
unsigned char *buffer;
|
||||
};
|
||||
|
||||
/* this is currently used by both mmap and sendfile */
|
||||
/* TODO(niels): something strange needs to happen for Windows here, I am not
|
||||
* sure what that is, but it needs to get looked into.
|
||||
*/
|
||||
struct evbuffer_chain_fd {
|
||||
int fd; /**< the fd associated with this chain */
|
||||
};
|
||||
|
||||
/** callback for a reference buffer; lets us know what to do with it when
|
||||
* we're done with it. */
|
||||
/** callback for a reference chain; lets us know what to do with it when
|
||||
* we're done with it. Lives at the end of an evbuffer_chain with the
|
||||
* EVBUFFER_REFERENCE flag set */
|
||||
struct evbuffer_chain_reference {
|
||||
evbuffer_ref_cleanup_cb cleanupfn;
|
||||
void *extra;
|
||||
};
|
||||
|
||||
/** File segment for a file-segment chain. Lives at the end of an
|
||||
* evbuffer_chain with the EVBUFFER_FILESEGMENT flag set. */
|
||||
struct evbuffer_chain_file_segment {
|
||||
struct evbuffer_file_segment *segment;
|
||||
#ifdef _WIN32
|
||||
/** If we're using CreateFileMapping, this is the handle to the view. */
|
||||
HANDLE view_handle;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Declared in event2/buffer.h; defined here. */
|
||||
struct evbuffer_file_segment {
|
||||
void *lock; /**< lock prevent concurrent access to refcnt */
|
||||
int refcnt; /**< Reference count for this file segment */
|
||||
unsigned flags; /**< combination of EVBUF_FS_* flags */
|
||||
|
||||
/** What kind of file segment is this? */
|
||||
unsigned can_sendfile : 1;
|
||||
unsigned is_mapping : 1;
|
||||
|
||||
/** The fd that we read the data from. */
|
||||
int fd;
|
||||
/** If we're using mmap, this is the raw mapped memory. */
|
||||
void *mapping;
|
||||
#ifdef _WIN32
|
||||
/** If we're using CreateFileMapping, this is the mapping */
|
||||
HANDLE mapping_handle;
|
||||
#endif
|
||||
/** If we're using mmap or IO, this is the content of the file
|
||||
* segment. */
|
||||
char *contents;
|
||||
/** Position of this segment within the file. */
|
||||
ev_off_t file_offset;
|
||||
/** If we're using mmap, this is the offset within 'mapping' where
|
||||
* this data segment begins. */
|
||||
ev_off_t mmap_offset;
|
||||
/** The length of this segment. */
|
||||
ev_off_t length;
|
||||
/** Cleanup callback function */
|
||||
evbuffer_file_segment_cleanup_cb cleanup_cb;
|
||||
/** Argument to be pass to cleanup callback function */
|
||||
void *cleanup_cb_arg;
|
||||
};
|
||||
|
||||
/** Information about the multicast parent of a chain. Lives at the
|
||||
* end of an evbuffer_chain with the EVBUFFER_MULTICAST flag set. */
|
||||
struct evbuffer_multicast_parent {
|
||||
/** source buffer the multicast parent belongs to */
|
||||
struct evbuffer *source;
|
||||
/** multicast parent for this chain */
|
||||
struct evbuffer_chain *parent;
|
||||
};
|
||||
|
||||
#define EVBUFFER_CHAIN_SIZE sizeof(struct evbuffer_chain)
|
||||
/** Return a pointer to extra data allocated along with an evbuffer. */
|
||||
#define EVBUFFER_CHAIN_EXTRA(t, c) (t *)((struct evbuffer_chain *)(c) + 1)
|
||||
|
@ -247,21 +300,21 @@ struct evbuffer_chain_reference {
|
|||
} while (0)
|
||||
|
||||
/** Increase the reference count of buf by one. */
|
||||
void _evbuffer_incref(struct evbuffer *buf);
|
||||
void evbuffer_incref_(struct evbuffer *buf);
|
||||
/** Increase the reference count of buf by one and acquire the lock. */
|
||||
void _evbuffer_incref_and_lock(struct evbuffer *buf);
|
||||
void evbuffer_incref_and_lock_(struct evbuffer *buf);
|
||||
/** Pin a single buffer chain using a given flag. A pinned chunk may not be
|
||||
* moved or freed until it is unpinned. */
|
||||
void _evbuffer_chain_pin(struct evbuffer_chain *chain, unsigned flag);
|
||||
void evbuffer_chain_pin_(struct evbuffer_chain *chain, unsigned flag);
|
||||
/** Unpin a single buffer chain using a given flag. */
|
||||
void _evbuffer_chain_unpin(struct evbuffer_chain *chain, unsigned flag);
|
||||
void evbuffer_chain_unpin_(struct evbuffer_chain *chain, unsigned flag);
|
||||
/** As evbuffer_free, but requires that we hold a lock on the buffer, and
|
||||
* releases the lock before freeing it and the buffer. */
|
||||
void _evbuffer_decref_and_unlock(struct evbuffer *buffer);
|
||||
void evbuffer_decref_and_unlock_(struct evbuffer *buffer);
|
||||
|
||||
/** As evbuffer_expand, but does not guarantee that the newly allocated memory
|
||||
* is contiguous. Instead, it may be split across two or more chunks. */
|
||||
int _evbuffer_expand_fast(struct evbuffer *, size_t, int);
|
||||
int evbuffer_expand_fast_(struct evbuffer *, size_t, int);
|
||||
|
||||
/** Helper: prepares for a readv/WSARecv call by expanding the buffer to
|
||||
* hold enough memory to read 'howmuch' bytes in possibly noncontiguous memory.
|
||||
|
@ -269,7 +322,7 @@ int _evbuffer_expand_fast(struct evbuffer *, size_t, int);
|
|||
* extent, and *chainp to point to the first chain that we'll try to read into.
|
||||
* Returns the number of vecs used.
|
||||
*/
|
||||
int _evbuffer_read_setup_vecs(struct evbuffer *buf, ev_ssize_t howmuch,
|
||||
int evbuffer_read_setup_vecs_(struct evbuffer *buf, ev_ssize_t howmuch,
|
||||
struct evbuffer_iovec *vecs, int n_vecs, struct evbuffer_chain ***chainp,
|
||||
int exact);
|
||||
|
||||
|
@ -282,12 +335,17 @@ int _evbuffer_read_setup_vecs(struct evbuffer *buf, ev_ssize_t howmuch,
|
|||
* See note in buffer_iocp's launch_write function */
|
||||
|
||||
/** Set the parent bufferevent object for buf to bev */
|
||||
void evbuffer_set_parent(struct evbuffer *buf, struct bufferevent *bev);
|
||||
void evbuffer_set_parent_(struct evbuffer *buf, struct bufferevent *bev);
|
||||
|
||||
void evbuffer_invoke_callbacks(struct evbuffer *buf);
|
||||
void evbuffer_invoke_callbacks_(struct evbuffer *buf);
|
||||
|
||||
|
||||
int evbuffer_get_callbacks_(struct evbuffer *buffer,
|
||||
struct event_callback **cbs,
|
||||
int max_cbs);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _EVBUFFER_INTERNAL_H_ */
|
||||
#endif /* EVBUFFER_INTERNAL_H_INCLUDED_ */
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/* evconfig-private.h. Generated from evconfig-private.h.in by configure. */
|
||||
/* evconfig-private.h template - see "Configuration Header Templates" */
|
||||
/* in AC manual. Kevin Bowling <kevin.bowling@kev009.com */
|
||||
#ifndef EVCONFIG_PRIVATE_H_INCLUDED_
|
||||
#define EVCONFIG_PRIVATE_H_INCLUDED_
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# define _ALL_SOURCE 1
|
||||
#endif
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
/* Enable threading extensions on Solaris. */
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# define _POSIX_PTHREAD_SEMANTICS 1
|
||||
#endif
|
||||
/* Enable extensions on HP NonStop. */
|
||||
#ifndef _TANDEM_SOURCE
|
||||
# define _TANDEM_SOURCE 1
|
||||
#endif
|
||||
/* Enable general extensions on Solaris. */
|
||||
#ifndef __EXTENSIONS__
|
||||
# define __EXTENSIONS__ 1
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
/* #undef _FILE_OFFSET_BITS */
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
/* #undef _LARGE_FILES */
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
#ifndef _MINIX
|
||||
/* #undef _MINIX */
|
||||
#endif
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
#ifndef _POSIX_1_SOURCE
|
||||
/* #undef _POSIX_1_SOURCE */
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
#ifndef _POSIX_SOURCE
|
||||
/* #undef _POSIX_SOURCE */
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
#ifndef EVCONFIG_PRIVATE_H_INCLUDED_
|
||||
#define EVCONFIG_PRIVATE_H_INCLUDED_
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
#cmakedefine _ALL_SOURCE
|
||||
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#cmakedefine _GNU_SOURCE 1
|
||||
|
||||
/* Enable threading extensions on Solaris. */
|
||||
#cmakedefine _POSIX_PTHREAD_SEMANTICS 1
|
||||
|
||||
/* Enable extensions on HP NonStop. */
|
||||
#cmakedefine _TANDEM_SOURCE 1
|
||||
|
||||
/* Enable general extensions on Solaris. */
|
||||
#cmakedefine __EXTENSIONS__
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#cmakedefine _FILE_OFFSET_BITS 1
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
#cmakedefine _LARGE_FILES 1
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
#cmakedefine _MINIX 1
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
#cmakedefine _POSIX_1_SOURCE 1
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
#cmakedefine _POSIX_SOURCE 1
|
||||
|
||||
#endif
|
|
@ -0,0 +1,48 @@
|
|||
/* evconfig-private.h template - see "Configuration Header Templates" */
|
||||
/* in AC manual. Kevin Bowling <kevin.bowling@kev009.com */
|
||||
#ifndef EVCONFIG_PRIVATE_H_INCLUDED_
|
||||
#define EVCONFIG_PRIVATE_H_INCLUDED_
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# undef _ALL_SOURCE
|
||||
#endif
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# undef _GNU_SOURCE
|
||||
#endif
|
||||
/* Enable threading extensions on Solaris. */
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# undef _POSIX_PTHREAD_SEMANTICS
|
||||
#endif
|
||||
/* Enable extensions on HP NonStop. */
|
||||
#ifndef _TANDEM_SOURCE
|
||||
# undef _TANDEM_SOURCE
|
||||
#endif
|
||||
/* Enable general extensions on Solaris. */
|
||||
#ifndef __EXTENSIONS__
|
||||
# undef __EXTENSIONS__
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#undef _FILE_OFFSET_BITS
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
#undef _LARGE_FILES
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
#ifndef _MINIX
|
||||
#undef _MINIX
|
||||
#endif
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
#ifndef _POSIX_1_SOURCE
|
||||
#undef _POSIX_1_SOURCE
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
#ifndef _POSIX_SOURCE
|
||||
#undef _POSIX_SOURCE
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,322 @@
|
|||
.\"
|
||||
.\" Copyright (c) 2006 Niels Provos <provos@citi.umich.edu>
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\"
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. The name of the author may not be used to endorse or promote products
|
||||
.\" derived from this software without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
.\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd October 7, 2006
|
||||
.Dt EVDNS 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm evdns_init
|
||||
.Nm evdns_shutdown
|
||||
.Nm evdns_err_to_string
|
||||
.Nm evdns_nameserver_add
|
||||
.Nm evdns_count_nameservers
|
||||
.Nm evdns_clear_nameservers_and_suspend
|
||||
.Nm evdns_resume
|
||||
.Nm evdns_nameserver_ip_add
|
||||
.Nm evdns_resolve_ipv4
|
||||
.Nm evdns_resolve_reverse
|
||||
.Nm evdns_resolv_conf_parse
|
||||
.Nm evdns_config_windows_nameservers
|
||||
.Nm evdns_search_clear
|
||||
.Nm evdns_search_add
|
||||
.Nm evdns_search_ndots_set
|
||||
.Nm evdns_set_log_fn
|
||||
.Nd asynchronous functions for DNS resolution.
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <sys/time.h>
|
||||
.Fd #include <event.h>
|
||||
.Fd #include <evdns.h>
|
||||
.Ft int
|
||||
.Fn evdns_init
|
||||
.Ft void
|
||||
.Fn evdns_shutdown "int fail_requests"
|
||||
.Ft "const char *"
|
||||
.Fn evdns_err_to_string "int err"
|
||||
.Ft int
|
||||
.Fn evdns_nameserver_add "unsigned long int address"
|
||||
.Ft int
|
||||
.Fn evdns_count_nameservers
|
||||
.Ft int
|
||||
.Fn evdns_clear_nameservers_and_suspend
|
||||
.Ft int
|
||||
.Fn evdns_resume
|
||||
.Ft int
|
||||
.Fn evdns_nameserver_ip_add(const char *ip_as_string);
|
||||
.Ft int
|
||||
.Fn evdns_resolve_ipv4 "const char *name" "int flags" "evdns_callback_type callback" "void *ptr"
|
||||
.Ft int
|
||||
.Fn evdns_resolve_reverse "struct in_addr *in" "int flags" "evdns_callback_type callback" "void *ptr"
|
||||
.Ft int
|
||||
.Fn evdns_resolv_conf_parse "int flags" "const char *"
|
||||
.Ft void
|
||||
.Fn evdns_search_clear
|
||||
.Ft void
|
||||
.Fn evdns_search_add "const char *domain"
|
||||
.Ft void
|
||||
.Fn evdns_search_ndots_set "const int ndots"
|
||||
.Ft void
|
||||
.Fn evdns_set_log_fn "evdns_debug_log_fn_type fn"
|
||||
.Ft int
|
||||
.Fn evdns_config_windows_nameservers
|
||||
.Sh DESCRIPTION
|
||||
Welcome, gentle reader
|
||||
.Pp
|
||||
Async DNS lookups are really a whole lot harder than they should be,
|
||||
mostly stemming from the fact that the libc resolver has never been
|
||||
very good at them. Before you use this library you should see if libc
|
||||
can do the job for you with the modern async call getaddrinfo_a
|
||||
(see http://www.imperialviolet.org/page25.html#e498). Otherwise,
|
||||
please continue.
|
||||
.Pp
|
||||
This code is based on libevent and you must call event_init before
|
||||
any of the APIs in this file. You must also seed the OpenSSL random
|
||||
source if you are using OpenSSL for ids (see below).
|
||||
.Pp
|
||||
This library is designed to be included and shipped with your source
|
||||
code. You statically link with it. You should also test for the
|
||||
existence of strtok_r and define HAVE_STRTOK_R if you have it.
|
||||
.Pp
|
||||
The DNS protocol requires a good source of id numbers and these
|
||||
numbers should be unpredictable for spoofing reasons. There are
|
||||
three methods for generating them here and you must define exactly
|
||||
one of them. In increasing order of preference:
|
||||
.Pp
|
||||
.Bl -tag -width "DNS_USE_GETTIMEOFDAY_FOR_ID" -compact -offset indent
|
||||
.It DNS_USE_GETTIMEOFDAY_FOR_ID
|
||||
Using the bottom 16 bits of the usec result from gettimeofday. This
|
||||
is a pretty poor solution but should work anywhere.
|
||||
.It DNS_USE_CPU_CLOCK_FOR_ID
|
||||
Using the bottom 16 bits of the nsec result from the CPU's time
|
||||
counter. This is better, but may not work everywhere. Requires
|
||||
POSIX realtime support and you'll need to link against -lrt on
|
||||
glibc systems at least.
|
||||
.It DNS_USE_OPENSSL_FOR_ID
|
||||
Uses the OpenSSL RAND_bytes call to generate the data. You must
|
||||
have seeded the pool before making any calls to this library.
|
||||
.El
|
||||
.Pp
|
||||
The library keeps track of the state of nameservers and will avoid
|
||||
them when they go down. Otherwise it will round robin between them.
|
||||
.Pp
|
||||
Quick start guide:
|
||||
#include "evdns.h"
|
||||
void callback(int result, char type, int count, int ttl,
|
||||
void *addresses, void *arg);
|
||||
evdns_resolv_conf_parse(DNS_OPTIONS_ALL, "/etc/resolv.conf");
|
||||
evdns_resolve("www.hostname.com", 0, callback, NULL);
|
||||
.Pp
|
||||
When the lookup is complete the callback function is called. The
|
||||
first argument will be one of the DNS_ERR_* defines in evdns.h.
|
||||
Hopefully it will be DNS_ERR_NONE, in which case type will be
|
||||
DNS_IPv4_A, count will be the number of IP addresses, ttl is the time
|
||||
which the data can be cached for (in seconds), addresses will point
|
||||
to an array of uint32_t's and arg will be whatever you passed to
|
||||
evdns_resolve.
|
||||
.Pp
|
||||
Searching:
|
||||
.Pp
|
||||
In order for this library to be a good replacement for glibc's resolver it
|
||||
supports searching. This involves setting a list of default domains, in
|
||||
which names will be queried for. The number of dots in the query name
|
||||
determines the order in which this list is used.
|
||||
.Pp
|
||||
Searching appears to be a single lookup from the point of view of the API,
|
||||
although many DNS queries may be generated from a single call to
|
||||
evdns_resolve. Searching can also drastically slow down the resolution
|
||||
of names.
|
||||
.Pp
|
||||
To disable searching:
|
||||
.Bl -enum -compact -offset indent
|
||||
.It
|
||||
Never set it up. If you never call
|
||||
.Fn evdns_resolv_conf_parse,
|
||||
.Fn evdns_init,
|
||||
or
|
||||
.Fn evdns_search_add
|
||||
then no searching will occur.
|
||||
.It
|
||||
If you do call
|
||||
.Fn evdns_resolv_conf_parse
|
||||
then don't pass
|
||||
.Va DNS_OPTION_SEARCH
|
||||
(or
|
||||
.Va DNS_OPTIONS_ALL,
|
||||
which implies it).
|
||||
.It
|
||||
When calling
|
||||
.Fn evdns_resolve,
|
||||
pass the
|
||||
.Va DNS_QUERY_NO_SEARCH
|
||||
flag.
|
||||
.El
|
||||
.Pp
|
||||
The order of searches depends on the number of dots in the name. If the
|
||||
number is greater than the ndots setting then the names is first tried
|
||||
globally. Otherwise each search domain is appended in turn.
|
||||
.Pp
|
||||
The ndots setting can either be set from a resolv.conf, or by calling
|
||||
evdns_search_ndots_set.
|
||||
.Pp
|
||||
For example, with ndots set to 1 (the default) and a search domain list of
|
||||
["myhome.net"]:
|
||||
Query: www
|
||||
Order: www.myhome.net, www.
|
||||
.Pp
|
||||
Query: www.abc
|
||||
Order: www.abc., www.abc.myhome.net
|
||||
.Pp
|
||||
.Sh API reference
|
||||
.Pp
|
||||
.Bl -tag -width 0123456
|
||||
.It Ft int Fn evdns_init
|
||||
Initializes support for non-blocking name resolution by calling
|
||||
.Fn evdns_resolv_conf_parse
|
||||
on UNIX and
|
||||
.Fn evdns_config_windows_nameservers
|
||||
on Windows.
|
||||
.It Ft int Fn evdns_nameserver_add "unsigned long int address"
|
||||
Add a nameserver. The address should be an IP address in
|
||||
network byte order. The type of address is chosen so that
|
||||
it matches in_addr.s_addr.
|
||||
Returns non-zero on error.
|
||||
.It Ft int Fn evdns_nameserver_ip_add "const char *ip_as_string"
|
||||
This wraps the above function by parsing a string as an IP
|
||||
address and adds it as a nameserver.
|
||||
Returns non-zero on error
|
||||
.It Ft int Fn evdns_resolve "const char *name" "int flags" "evdns_callback_type callback" "void *ptr"
|
||||
Resolve a name. The name parameter should be a DNS name.
|
||||
The flags parameter should be 0, or DNS_QUERY_NO_SEARCH
|
||||
which disables searching for this query. (see defn of
|
||||
searching above).
|
||||
.Pp
|
||||
The callback argument is a function which is called when
|
||||
this query completes and ptr is an argument which is passed
|
||||
to that callback function.
|
||||
.Pp
|
||||
Returns non-zero on error
|
||||
.It Ft void Fn evdns_search_clear
|
||||
Clears the list of search domains
|
||||
.It Ft void Fn evdns_search_add "const char *domain"
|
||||
Add a domain to the list of search domains
|
||||
.It Ft void Fn evdns_search_ndots_set "int ndots"
|
||||
Set the number of dots which, when found in a name, causes
|
||||
the first query to be without any search domain.
|
||||
.It Ft int Fn evdns_count_nameservers "void"
|
||||
Return the number of configured nameservers (not necessarily the
|
||||
number of running nameservers). This is useful for double-checking
|
||||
whether our calls to the various nameserver configuration functions
|
||||
have been successful.
|
||||
.It Ft int Fn evdns_clear_nameservers_and_suspend "void"
|
||||
Remove all currently configured nameservers, and suspend all pending
|
||||
resolves. Resolves will not necessarily be re-attempted until
|
||||
evdns_resume() is called.
|
||||
.It Ft int Fn evdns_resume "void"
|
||||
Re-attempt resolves left in limbo after an earlier call to
|
||||
evdns_clear_nameservers_and_suspend().
|
||||
.It Ft int Fn evdns_config_windows_nameservers "void"
|
||||
Attempt to configure a set of nameservers based on platform settings on
|
||||
a win32 host. Preferentially tries to use GetNetworkParams; if that fails,
|
||||
looks in the registry. Returns 0 on success, nonzero on failure.
|
||||
.It Ft int Fn evdns_resolv_conf_parse "int flags" "const char *filename"
|
||||
Parse a resolv.conf like file from the given filename.
|
||||
.Pp
|
||||
See the man page for resolv.conf for the format of this file.
|
||||
The flags argument determines what information is parsed from
|
||||
this file:
|
||||
.Bl -tag -width "DNS_OPTION_NAMESERVERS" -offset indent -compact -nested
|
||||
.It DNS_OPTION_SEARCH
|
||||
domain, search and ndots options
|
||||
.It DNS_OPTION_NAMESERVERS
|
||||
nameserver lines
|
||||
.It DNS_OPTION_MISC
|
||||
timeout and attempts options
|
||||
.It DNS_OPTIONS_ALL
|
||||
all of the above
|
||||
.El
|
||||
.Pp
|
||||
The following directives are not parsed from the file:
|
||||
sortlist, rotate, no-check-names, inet6, debug
|
||||
.Pp
|
||||
Returns non-zero on error:
|
||||
.Bl -tag -width "0" -offset indent -compact -nested
|
||||
.It 0
|
||||
no errors
|
||||
.It 1
|
||||
failed to open file
|
||||
.It 2
|
||||
failed to stat file
|
||||
.It 3
|
||||
file too large
|
||||
.It 4
|
||||
out of memory
|
||||
.It 5
|
||||
short read from file
|
||||
.El
|
||||
.El
|
||||
.Sh Internals:
|
||||
Requests are kept in two queues. The first is the inflight queue. In
|
||||
this queue requests have an allocated transaction id and nameserver.
|
||||
They will soon be transmitted if they haven't already been.
|
||||
.Pp
|
||||
The second is the waiting queue. The size of the inflight ring is
|
||||
limited and all other requests wait in waiting queue for space. This
|
||||
bounds the number of concurrent requests so that we don't flood the
|
||||
nameserver. Several algorithms require a full walk of the inflight
|
||||
queue and so bounding its size keeps thing going nicely under huge
|
||||
(many thousands of requests) loads.
|
||||
.Pp
|
||||
If a nameserver loses too many requests it is considered down and we
|
||||
try not to use it. After a while we send a probe to that nameserver
|
||||
(a lookup for google.com) and, if it replies, we consider it working
|
||||
again. If the nameserver fails a probe we wait longer to try again
|
||||
with the next probe.
|
||||
.Sh SEE ALSO
|
||||
.Xr event 3 ,
|
||||
.Xr gethostbyname 3 ,
|
||||
.Xr resolv.conf 5
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm evdns
|
||||
API was developed by Adam Langley on top of the
|
||||
.Nm libevent
|
||||
API.
|
||||
The code was integrate into
|
||||
.Nm Tor
|
||||
by Nick Mathewson and finally put into
|
||||
.Nm libevent
|
||||
itself by Niels Provos.
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm evdns
|
||||
API and code was written by Adam Langley with significant
|
||||
contributions by Nick Mathewson.
|
||||
.Sh BUGS
|
||||
This documentation is neither complete nor authoritative.
|
||||
If you are in doubt about the usage of this API then
|
||||
check the source code to find out how it works, write
|
||||
up the missing piece of documentation and send it to
|
||||
me for inclusion in this man page.
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,532 @@
|
|||
/* event-config.h
|
||||
*
|
||||
* This file was generated by cmake when the makefiles were generated.
|
||||
*
|
||||
* DO NOT EDIT THIS FILE.
|
||||
*
|
||||
* Do not rely on macros in this file existing in later versions.
|
||||
*/
|
||||
#ifndef EVENT2_EVENT_CONFIG_H_INCLUDED_
|
||||
#define EVENT2_EVENT_CONFIG_H_INCLUDED_
|
||||
|
||||
/* Numeric representation of the version */
|
||||
#define EVENT__NUMERIC_VERSION @EVENT_NUMERIC_VERSION@
|
||||
#define EVENT__PACKAGE_VERSION "@EVENT_PACKAGE_VERSION@"
|
||||
|
||||
#define EVENT__VERSION_MAJOR @EVENT_VERSION_MAJOR@
|
||||
#define EVENT__VERSION_MINOR @EVENT_VERSION_MINOR@
|
||||
#define EVENT__VERSION_PATCH @EVENT_VERSION_PATCH@
|
||||
|
||||
/* Version number of package */
|
||||
#define EVENT__VERSION "@EVENT_VERSION@"
|
||||
|
||||
/* Name of package */
|
||||
#define EVENT__PACKAGE "libevent"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define EVENT__PACKAGE_BUGREPORT ""
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define EVENT__PACKAGE_NAME ""
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define EVENT__PACKAGE_STRING ""
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define EVENT__PACKAGE_TARNAME ""
|
||||
|
||||
/* Define if libevent should build without support for a debug mode */
|
||||
#cmakedefine EVENT__DISABLE_DEBUG_MODE
|
||||
|
||||
/* Define if libevent should not allow replacing the mm functions */
|
||||
#cmakedefine EVENT__DISABLE_MM_REPLACEMENT
|
||||
|
||||
/* Define if libevent should not be compiled with thread support */
|
||||
#cmakedefine EVENT__DISABLE_THREAD_SUPPORT
|
||||
|
||||
/* Define to 1 if you have the `accept4' function. */
|
||||
#cmakedefine EVENT__HAVE_ACCEPT4
|
||||
|
||||
/* Define to 1 if you have the `arc4random' function. */
|
||||
#cmakedefine EVENT__HAVE_ARC4RANDOM
|
||||
|
||||
/* Define to 1 if you have the `arc4random_buf' function. */
|
||||
#cmakedefine EVENT__HAVE_ARC4RANDOM_BUF
|
||||
|
||||
/* Define if clock_gettime is available in libc */
|
||||
#cmakedefine EVENT__DNS_USE_CPU_CLOCK_FOR_ID
|
||||
|
||||
/* Define is no secure id variant is available */
|
||||
#cmakedefine EVENT__DNS_USE_GETTIMEOFDAY_FOR_ID
|
||||
#cmakedefine EVENT__DNS_USE_FTIME_FOR_ID
|
||||
|
||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_ARPA_INET_H
|
||||
|
||||
/* Define to 1 if you have the `clock_gettime' function. */
|
||||
#cmakedefine EVENT__HAVE_CLOCK_GETTIME
|
||||
|
||||
/* Define to 1 if you have the declaration of `CTL_KERN'. */
|
||||
#cmakedefine EVENT__HAVE_DECL_CTL_KERN
|
||||
|
||||
/* Define to 1 if you have the declaration of `KERN_ARND'. */
|
||||
#cmakedefine EVENT__HAVE_DECL_KERN_ARND
|
||||
|
||||
/* Define to 1 if you have the declaration of `KERN_RANDOM'. */
|
||||
#cmakedefine EVENT__HAVE_DECL_KERN_RANDOM
|
||||
|
||||
/* Define if /dev/poll is available */
|
||||
#cmakedefine EVENT__HAVE_DEVPOLL
|
||||
|
||||
/* Define to 1 if you have the <netdb.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_NETDB_H
|
||||
|
||||
/* Define to 1 if fd_mask type is defined */
|
||||
#cmakedefine EVENT__HAVE_FD_MASK
|
||||
|
||||
/* Define to 1 if the <sys/queue.h> header file defines TAILQ_FOREACH. */
|
||||
#cmakedefine EVENT__HAVE_TAILQFOREACH
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_DLFCN_H
|
||||
|
||||
/* Define if your system supports the epoll system calls */
|
||||
#cmakedefine EVENT__HAVE_EPOLL
|
||||
|
||||
/* Define to 1 if you have the `epoll_create1' function. */
|
||||
#cmakedefine EVENT__HAVE_EPOLL_CREATE1
|
||||
|
||||
/* Define to 1 if you have the `epoll_ctl' function. */
|
||||
#cmakedefine EVENT__HAVE_EPOLL_CTL
|
||||
|
||||
/* Define to 1 if you have the `eventfd' function. */
|
||||
#cmakedefine EVENT__HAVE_EVENTFD
|
||||
|
||||
/* Define if your system supports event ports */
|
||||
#cmakedefine EVENT__HAVE_EVENT_PORTS
|
||||
|
||||
/* Define to 1 if you have the `fcntl' function. */
|
||||
#cmakedefine EVENT__HAVE_FCNTL
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_FCNTL_H
|
||||
|
||||
/* Define to 1 if you have the `getaddrinfo' function. */
|
||||
#cmakedefine EVENT__HAVE_GETADDRINFO
|
||||
|
||||
/* Define to 1 if you have the `getegid' function. */
|
||||
#cmakedefine EVENT__HAVE_GETEGID
|
||||
|
||||
/* Define to 1 if you have the `geteuid' function. */
|
||||
#cmakedefine EVENT__HAVE_GETEUID
|
||||
|
||||
/* TODO: Check for different gethostname argument counts. CheckPrototypeDefinition.cmake can be used. */
|
||||
/* Define this if you have any gethostbyname_r() */
|
||||
#cmakedefine EVENT__HAVE_GETHOSTBYNAME_R
|
||||
|
||||
/* Define this if gethostbyname_r takes 3 arguments */
|
||||
#cmakedefine EVENT__HAVE_GETHOSTBYNAME_R_3_ARG
|
||||
|
||||
/* Define this if gethostbyname_r takes 5 arguments */
|
||||
#cmakedefine EVENT__HAVE_GETHOSTBYNAME_R_5_ARG
|
||||
|
||||
/* Define this if gethostbyname_r takes 6 arguments */
|
||||
#cmakedefine EVENT__HAVE_GETHOSTBYNAME_R_6_ARG
|
||||
|
||||
/* Define to 1 if you have the `getifaddrs' function. */
|
||||
#cmakedefine EVENT__HAVE_GETIFADDRS
|
||||
|
||||
/* Define to 1 if you have the `getnameinfo' function. */
|
||||
#cmakedefine EVENT__HAVE_GETNAMEINFO
|
||||
|
||||
/* Define to 1 if you have the `getprotobynumber' function. */
|
||||
#cmakedefine EVENT__HAVE_GETPROTOBYNUMBER
|
||||
|
||||
/* Define to 1 if you have the `getservbyname' function. */
|
||||
#cmakedefine EVENT__HAVE_GETSERVBYNAME
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
#cmakedefine EVENT__HAVE_GETTIMEOFDAY
|
||||
|
||||
/* Define to 1 if you have the <ifaddrs.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_IFADDRS_H
|
||||
|
||||
/* Define to 1 if you have the `inet_ntop' function. */
|
||||
#cmakedefine EVENT__HAVE_INET_NTOP
|
||||
|
||||
/* Define to 1 if you have the `inet_pton' function. */
|
||||
#cmakedefine EVENT__HAVE_INET_PTON
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the `issetugid' function. */
|
||||
#cmakedefine EVENT__HAVE_ISSETUGID
|
||||
|
||||
/* Define to 1 if you have the `kqueue' function. */
|
||||
#cmakedefine EVENT__HAVE_KQUEUE
|
||||
|
||||
/* Define if the system has zlib */
|
||||
#cmakedefine EVENT__HAVE_LIBZ
|
||||
|
||||
/* Define to 1 if you have the `mach_absolute_time' function. */
|
||||
#cmakedefine EVENT__HAVE_MACH_ABSOLUTE_TIME
|
||||
|
||||
/* Define to 1 if you have the <mach/mach_time.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_MACH_MACH_TIME_H
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the `mmap' function. */
|
||||
#cmakedefine EVENT__HAVE_MMAP
|
||||
|
||||
/* Define to 1 if you have the `nanosleep' function. */
|
||||
#cmakedefine EVENT__HAVE_NANOSLEEP
|
||||
|
||||
/* Define to 1 if you have the `usleep' function. */
|
||||
#cmakedefine EVENT__HAVE_USLEEP
|
||||
|
||||
/* Define to 1 if you have the <netinet/in6.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_NETINET_IN6_H
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_NETINET_IN_H
|
||||
|
||||
/* Define to 1 if you have the <netinet/tcp.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_NETINET_TCP_H
|
||||
|
||||
/* Define if the system has openssl */
|
||||
#cmakedefine EVENT__HAVE_OPENSSL
|
||||
|
||||
/* Define to 1 if you have the `pipe' function. */
|
||||
#cmakedefine EVENT__HAVE_PIPE
|
||||
|
||||
/* Define to 1 if you have the `pipe2' function. */
|
||||
#cmakedefine EVENT__HAVE_PIPE2
|
||||
|
||||
/* Define to 1 if you have the `poll' function. */
|
||||
#cmakedefine EVENT__HAVE_POLL
|
||||
|
||||
/* Define to 1 if you have the <poll.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_POLL_H
|
||||
|
||||
/* Define to 1 if you have the `port_create' function. */
|
||||
#cmakedefine EVENT__HAVE_PORT_CREATE
|
||||
|
||||
/* Define to 1 if you have the <port.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_PORT_H
|
||||
|
||||
/* Define if we have pthreads on this system */
|
||||
#cmakedefine EVENT__HAVE_PTHREADS
|
||||
|
||||
/* Define to 1 if you have the `putenv' function. */
|
||||
#cmakedefine EVENT__HAVE_PUTENV
|
||||
|
||||
/* Define to 1 if the system has the type `sa_family_t'. */
|
||||
#cmakedefine EVENT__HAVE_SA_FAMILY_T
|
||||
|
||||
/* Define to 1 if you have the `select' function. */
|
||||
#cmakedefine EVENT__HAVE_SELECT
|
||||
|
||||
/* Define to 1 if you have the `setenv' function. */
|
||||
#cmakedefine EVENT__HAVE_SETENV
|
||||
|
||||
/* Define if F_SETFD is defined in <fcntl.h> */
|
||||
#cmakedefine EVENT__HAVE_SETFD
|
||||
|
||||
/* Define to 1 if you have the `setrlimit' function. */
|
||||
#cmakedefine EVENT__HAVE_SETRLIMIT
|
||||
|
||||
/* Define to 1 if you have the `sendfile' function. */
|
||||
#cmakedefine EVENT__HAVE_SENDFILE
|
||||
|
||||
/* Define if F_SETFD is defined in <fcntl.h> */
|
||||
#cmakedefine EVENT__HAVE_SETFD
|
||||
|
||||
/* Define to 1 if you have the `sigaction' function. */
|
||||
#cmakedefine EVENT__HAVE_SIGACTION
|
||||
|
||||
/* Define to 1 if you have the `signal' function. */
|
||||
#cmakedefine EVENT__HAVE_SIGNAL
|
||||
|
||||
/* Define to 1 if you have the `splice' function. */
|
||||
#cmakedefine EVENT__HAVE_SPLICE
|
||||
|
||||
/* Define to 1 if you have the <stdarg.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_STDARG_H
|
||||
|
||||
/* Define to 1 if you have the <stddef.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_STDDEF_H
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the `strlcpy' function. */
|
||||
#cmakedefine EVENT__HAVE_STRLCPY
|
||||
|
||||
/* Define to 1 if you have the `strsep' function. */
|
||||
#cmakedefine EVENT__HAVE_STRSEP
|
||||
|
||||
/* Define to 1 if you have the `strtok_r' function. */
|
||||
#cmakedefine EVENT__HAVE_STRTOK_R
|
||||
|
||||
/* Define to 1 if you have the `strtoll' function. */
|
||||
#cmakedefine EVENT__HAVE_STRTOLL
|
||||
|
||||
/* Define to 1 if the system has the type `struct addrinfo'. */
|
||||
#cmakedefine EVENT__HAVE_STRUCT_ADDRINFO
|
||||
|
||||
/* Define to 1 if the system has the type `struct in6_addr'. */
|
||||
#cmakedefine EVENT__HAVE_STRUCT_IN6_ADDR
|
||||
|
||||
/* Define to 1 if `s6_addr16' is member of `struct in6_addr'. */
|
||||
#cmakedefine EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR16
|
||||
|
||||
/* Define to 1 if `s6_addr32' is member of `struct in6_addr'. */
|
||||
#cmakedefine EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR32
|
||||
|
||||
/* Define to 1 if the system has the type `struct sockaddr_in6'. */
|
||||
#cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_IN6
|
||||
|
||||
/* Define to 1 if `sin6_len' is member of `struct sockaddr_in6'. */
|
||||
#cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
|
||||
|
||||
/* Define to 1 if `sin_len' is member of `struct sockaddr_in'. */
|
||||
#cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
|
||||
|
||||
/* Define to 1 if the system has the type `struct sockaddr_storage'. */
|
||||
#cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_STORAGE
|
||||
|
||||
/* Define to 1 if `ss_family' is a member of `struct sockaddr_storage'. */
|
||||
#cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
|
||||
|
||||
/* Define to 1 if `__ss_family' is a member of `struct sockaddr_storage'. */
|
||||
#cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY
|
||||
|
||||
/* Define to 1 if you have the `sysctl' function. */
|
||||
#cmakedefine EVENT__HAVE_SYSCTL
|
||||
|
||||
/* Define to 1 if you have the <sys/devpoll.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_SYS_DEVPOLL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/epoll.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_SYS_EPOLL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/eventfd.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_SYS_EVENTFD_H
|
||||
|
||||
/* Define to 1 if you have the <sys/event.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_SYS_EVENT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_SYS_IOCTL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_SYS_MMAN_H
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_SYS_PARAM_H
|
||||
|
||||
/* Define to 1 if you have the <sys/queue.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_SYS_QUEUE_H
|
||||
|
||||
/* Define to 1 if you have the <sys/resource.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_SYS_RESOURCE_H
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_SYS_SELECT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/sendfile.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_SYS_SENDFILE_H
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_SYS_SOCKET_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/sysctl.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_SYS_SYSCTL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/timerfd.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_SYS_TIMERFD_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_SYS_TIME_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <sys/uio.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_SYS_UIO_H
|
||||
|
||||
/* Define to 1 if you have the <sys/wait.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_SYS_WAIT_H
|
||||
|
||||
/* Define to 1 if you have the <errno.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_ERRNO_H
|
||||
|
||||
/* Define if TAILQ_FOREACH is defined in <sys/queue.h> */
|
||||
#cmakedefine EVENT__HAVE_TAILQFOREACH
|
||||
|
||||
/* Define if timeradd is defined in <sys/time.h> */
|
||||
#cmakedefine EVENT__HAVE_TIMERADD
|
||||
|
||||
/* Define if timerclear is defined in <sys/time.h> */
|
||||
#cmakedefine EVENT__HAVE_TIMERCLEAR
|
||||
|
||||
/* Define if timercmp is defined in <sys/time.h> */
|
||||
#cmakedefine EVENT__HAVE_TIMERCMP
|
||||
|
||||
|
||||
/* Define to 1 if you have the `timerfd_create' function. */
|
||||
#cmakedefine EVENT__HAVE_TIMERFD_CREATE
|
||||
|
||||
/* Define if timerisset is defined in <sys/time.h> */
|
||||
#cmakedefine EVENT__HAVE_TIMERISSET
|
||||
|
||||
/* Define to 1 if the system has the type `uint8_t'. */
|
||||
#cmakedefine EVENT__HAVE_UINT8_T
|
||||
|
||||
/* Define to 1 if the system has the type `uint16_t'. */
|
||||
#cmakedefine EVENT__HAVE_UINT16_T
|
||||
|
||||
/* Define to 1 if the system has the type `uint32_t'. */
|
||||
#cmakedefine EVENT__HAVE_UINT32_T
|
||||
|
||||
/* Define to 1 if the system has the type `uint64_t'. */
|
||||
#cmakedefine EVENT__HAVE_UINT64_T
|
||||
|
||||
/* Define to 1 if the system has the type `uintptr_t'. */
|
||||
#cmakedefine EVENT__HAVE_UINTPTR_T
|
||||
|
||||
/* Define to 1 if you have the `umask' function. */
|
||||
#cmakedefine EVENT__HAVE_UMASK
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#cmakedefine EVENT__HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if you have the `unsetenv' function. */
|
||||
#cmakedefine EVENT__HAVE_UNSETENV
|
||||
|
||||
/* Define to 1 if you have the `vasprintf' function. */
|
||||
#cmakedefine EVENT__HAVE_VASPRINTF
|
||||
|
||||
/* Define if kqueue works correctly with pipes */
|
||||
#cmakedefine EVENT__HAVE_WORKING_KQUEUE
|
||||
|
||||
#ifdef __USE_UNUSED_DEFINITIONS__
|
||||
/* Define to necessary symbol if this constant uses a non-standard name on your system. */
|
||||
/* XXX: Hello, this isn't even used, nor is it defined anywhere... - Ellzey */
|
||||
#define EVENT__PTHREAD_CREATE_JOINABLE ${EVENT__PTHREAD_CREATE_JOINABLE}
|
||||
#endif
|
||||
|
||||
/* The size of `pthread_t', as computed by sizeof. */
|
||||
#define EVENT__SIZEOF_PTHREAD_T @EVENT__SIZEOF_PTHREAD_T@
|
||||
|
||||
/* The size of a `int', as computed by sizeof. */
|
||||
#define EVENT__SIZEOF_INT @EVENT__SIZEOF_INT@
|
||||
|
||||
/* The size of a `long', as computed by sizeof. */
|
||||
#define EVENT__SIZEOF_LONG @EVENT__SIZEOF_LONG@
|
||||
|
||||
/* The size of a `long long', as computed by sizeof. */
|
||||
#define EVENT__SIZEOF_LONG_LONG @EVENT__SIZEOF_LONG_LONG@
|
||||
|
||||
/* The size of `off_t', as computed by sizeof. */
|
||||
#define EVENT__SIZEOF_OFF_T @EVENT__SIZEOF_OFF_T@
|
||||
|
||||
#define EVENT__SIZEOF_SSIZE_T @EVENT__SIZEOF_SSIZE_T@
|
||||
|
||||
|
||||
/* The size of a `short', as computed by sizeof. */
|
||||
#define EVENT__SIZEOF_SHORT @EVENT__SIZEOF_SHORT@
|
||||
|
||||
/* The size of `size_t', as computed by sizeof. */
|
||||
#define EVENT__SIZEOF_SIZE_T @EVENT__SIZEOF_SIZE_T@
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#cmakedefine EVENT__STDC_HEADERS
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#cmakedefine EVENT__TIME_WITH_SYS_TIME
|
||||
|
||||
/* The size of `socklen_t', as computed by sizeof. */
|
||||
#define EVENT__SIZEOF_SOCKLEN_T @EVENT__SIZEOF_SOCKLEN_T@
|
||||
|
||||
/* The size of 'void *', as computer by sizeof */
|
||||
#define EVENT__SIZEOF_VOID_P @EVENT__SIZEOF_VOID_P@
|
||||
|
||||
/* set an alias for whatever __func__ __FUNCTION__ is, what sillyness */
|
||||
#if defined (__func__)
|
||||
#define EVENT____func__ __func__
|
||||
#elif defined(__FUNCTION__)
|
||||
#define EVENT____func__ __FUNCTION__
|
||||
#else
|
||||
#define EVENT____func__ __FILE__
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __THESE_ARE_NOT_CONFIG_H_THINGS_THEY_ARE_DASH_D_THINGS__
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
/* Ellzey is not satisfied */
|
||||
#define EVENT___FILE_OFFSET_BITS @EVENT___FILE_OFFSET_BITS@
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
#define @_LARGE_FILES@
|
||||
#endif
|
||||
|
||||
#ifdef _WhAT_DOES_THIS_EVEN_DO_
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* lolwut? - ellzey */
|
||||
#undef EVENT__const
|
||||
#endif
|
||||
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
/* why not c++?
|
||||
*
|
||||
* and are we really expected to use EVENT__inline everywhere,
|
||||
* shouldn't we just do:
|
||||
* ifdef EVENT__inline
|
||||
* define inline EVENT__inline
|
||||
*
|
||||
* - Ellzey
|
||||
*/
|
||||
|
||||
#define EVENT__inline @EVENT__inline@
|
||||
#endif
|
||||
|
||||
/* Define to `int' if <sys/tyes.h> does not define. */
|
||||
#define EVENT__pid_t @EVENT__pid_t@
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> does not define. */
|
||||
#define EVENT__size_t @EVENT__size_t@
|
||||
|
||||
/* Define to unsigned int if you dont have it */
|
||||
#define EVENT__socklen_t @EVENT__socklen_t@
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#define EVENT__ssize_t @EVENT__ssize_t@
|
||||
|
||||
#cmakedefine EVENT__NEED_DLLIMPORT
|
||||
|
||||
/* Define to 1 if you have ERR_remove_thread_stat(). */
|
||||
#cmakedefine EVENT__HAVE_ERR_REMOVE_THREAD_STATE
|
||||
|
||||
/* Define if waitpid() supports WNOWAIT */
|
||||
#cmakedefine EVENT__HAVE_WAITPID_WITH_WNOWAIT
|
||||
|
||||
#endif
|
|
@ -24,14 +24,16 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _EVENT_INTERNAL_H_
|
||||
#define _EVENT_INTERNAL_H_
|
||||
#ifndef EVENT_INTERNAL_H_INCLUDED_
|
||||
#define EVENT_INTERNAL_H_INCLUDED_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "event2/event-config.h"
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <sys/queue.h>
|
||||
#include "event2/event_struct.h"
|
||||
|
@ -43,18 +45,42 @@ extern "C" {
|
|||
/* map union members back */
|
||||
|
||||
/* mutually exclusive */
|
||||
#define ev_signal_next _ev.ev_signal.ev_signal_next
|
||||
#define ev_io_next _ev.ev_io.ev_io_next
|
||||
#define ev_io_timeout _ev.ev_io.ev_timeout
|
||||
#define ev_signal_next ev_.ev_signal.ev_signal_next
|
||||
#define ev_io_next ev_.ev_io.ev_io_next
|
||||
#define ev_io_timeout ev_.ev_io.ev_timeout
|
||||
|
||||
/* used only by signals */
|
||||
#define ev_ncalls _ev.ev_signal.ev_ncalls
|
||||
#define ev_pncalls _ev.ev_signal.ev_pncalls
|
||||
#define ev_ncalls ev_.ev_signal.ev_ncalls
|
||||
#define ev_pncalls ev_.ev_signal.ev_pncalls
|
||||
|
||||
/* Possible values for ev_closure in struct event. */
|
||||
#define EV_CLOSURE_NONE 0
|
||||
#define EV_CLOSURE_SIGNAL 1
|
||||
#define EV_CLOSURE_PERSIST 2
|
||||
#define ev_pri ev_evcallback.evcb_pri
|
||||
#define ev_flags ev_evcallback.evcb_flags
|
||||
#define ev_closure ev_evcallback.evcb_closure
|
||||
#define ev_callback ev_evcallback.evcb_cb_union.evcb_callback
|
||||
#define ev_arg ev_evcallback.evcb_arg
|
||||
|
||||
/** @name Event closure codes
|
||||
|
||||
Possible values for evcb_closure in struct event_callback
|
||||
|
||||
@{
|
||||
*/
|
||||
/** A regular event. Uses the evcb_callback callback */
|
||||
#define EV_CLOSURE_EVENT 0
|
||||
/** A signal event. Uses the evcb_callback callback */
|
||||
#define EV_CLOSURE_EVENT_SIGNAL 1
|
||||
/** A persistent non-signal event. Uses the evcb_callback callback */
|
||||
#define EV_CLOSURE_EVENT_PERSIST 2
|
||||
/** A simple callback. Uses the evcb_selfcb callback. */
|
||||
#define EV_CLOSURE_CB_SELF 3
|
||||
/** A finalizing callback. Uses the evcb_cbfinalize callback. */
|
||||
#define EV_CLOSURE_CB_FINALIZE 4
|
||||
/** A finalizing event. Uses the evcb_evfinalize callback. */
|
||||
#define EV_CLOSURE_EVENT_FINALIZE 5
|
||||
/** A finalizing event that should get freed after. Uses the evcb_evfinalize
|
||||
* callback. */
|
||||
#define EV_CLOSURE_EVENT_FINALIZE_FREE 6
|
||||
/** @} */
|
||||
|
||||
/** Structure to define the backend of a given event_base. */
|
||||
struct eventop {
|
||||
|
@ -99,7 +125,7 @@ struct eventop {
|
|||
size_t fdinfo_len;
|
||||
};
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
/* If we're on win32, then file descriptors are not nice low densely packed
|
||||
integers. Instead, they are pointer-like windows handles, and we want to
|
||||
use a hashtable instead of an array to map fds to events.
|
||||
|
@ -110,6 +136,7 @@ struct eventop {
|
|||
/* #define HT_CACHE_HASH_VALS */
|
||||
|
||||
#ifdef EVMAP_USE_HT
|
||||
#define HT_NO_CACHE_HASH_VALUES
|
||||
#include "ht-internal.h"
|
||||
struct event_map_entry;
|
||||
HT_HEAD(event_io_map, event_map_entry);
|
||||
|
@ -159,14 +186,25 @@ struct event_changelist {
|
|||
int changes_size;
|
||||
};
|
||||
|
||||
#ifndef _EVENT_DISABLE_DEBUG_MODE
|
||||
#ifndef EVENT__DISABLE_DEBUG_MODE
|
||||
/* Global internal flag: set to one if debug mode is on. */
|
||||
extern int _event_debug_mode_on;
|
||||
#define EVENT_DEBUG_MODE_IS_ON() (_event_debug_mode_on)
|
||||
extern int event_debug_mode_on_;
|
||||
#define EVENT_DEBUG_MODE_IS_ON() (event_debug_mode_on_)
|
||||
#else
|
||||
#define EVENT_DEBUG_MODE_IS_ON() (0)
|
||||
#endif
|
||||
|
||||
TAILQ_HEAD(evcallback_list, event_callback);
|
||||
|
||||
/* Sets up an event for processing once */
|
||||
struct event_once {
|
||||
LIST_ENTRY(event_once) next_once;
|
||||
struct event ev;
|
||||
|
||||
void (*cb)(evutil_socket_t, short, void *);
|
||||
void *arg;
|
||||
};
|
||||
|
||||
struct event_base {
|
||||
/** Function pointers and other data to describe this event_base's
|
||||
* backend. */
|
||||
|
@ -186,10 +224,16 @@ struct event_base {
|
|||
|
||||
/** Number of virtual events */
|
||||
int virtual_event_count;
|
||||
/** Maximum number of virtual events active */
|
||||
int virtual_event_count_max;
|
||||
/** Number of total events added to this event_base */
|
||||
int event_count;
|
||||
/** Maximum number of total events added to this event_base */
|
||||
int event_count_max;
|
||||
/** Number of total events active in this event_base */
|
||||
int event_count_active;
|
||||
/** Maximum number of total events active in this event_base */
|
||||
int event_count_active_max;
|
||||
|
||||
/** Set if we should terminate the loop once we're done processing
|
||||
* events. */
|
||||
|
@ -206,14 +250,23 @@ struct event_base {
|
|||
* reentrant invocation. */
|
||||
int running_loop;
|
||||
|
||||
/** Set to the number of deferred_cbs we've made 'active' in the
|
||||
* loop. This is a hack to prevent starvation; it would be smarter
|
||||
* to just use event_config_set_max_dispatch_interval's max_callbacks
|
||||
* feature */
|
||||
int n_deferreds_queued;
|
||||
|
||||
/* Active event management. */
|
||||
/** An array of nactivequeues queues for active events (ones that
|
||||
* have triggered, and whose callbacks need to be called). Low
|
||||
/** An array of nactivequeues queues for active event_callbacks (ones
|
||||
* that have triggered, and whose callbacks need to be called). Low
|
||||
* priority numbers are more important, and stall higher ones.
|
||||
*/
|
||||
struct event_list *activequeues;
|
||||
struct evcallback_list *activequeues;
|
||||
/** The length of the activequeues array */
|
||||
int nactivequeues;
|
||||
/** A list of event_callbacks that should become active the next time
|
||||
* we process events, but not this time. */
|
||||
struct evcallback_list active_later_queue;
|
||||
|
||||
/* common timeout logic */
|
||||
|
||||
|
@ -225,22 +278,12 @@ struct event_base {
|
|||
/** The total size of common_timeout_queues. */
|
||||
int n_common_timeouts_allocated;
|
||||
|
||||
/** List of defered_cb that are active. We run these after the active
|
||||
* events. */
|
||||
struct deferred_cb_queue defer_queue;
|
||||
|
||||
/** Mapping from file descriptors to enabled (added) events */
|
||||
struct event_io_map io;
|
||||
|
||||
/** Mapping from signal numbers to enabled (added) events. */
|
||||
struct event_signal_map sigmap;
|
||||
|
||||
/** All events that have been enabled (added) in this event_base */
|
||||
struct event_list eventqueue;
|
||||
|
||||
/** Stored timeval; used to detect when time is running backwards. */
|
||||
struct timeval event_tv;
|
||||
|
||||
/** Priority queue of events with timeouts. */
|
||||
struct min_heap timeheap;
|
||||
|
||||
|
@ -248,30 +291,30 @@ struct event_base {
|
|||
* too often. */
|
||||
struct timeval tv_cache;
|
||||
|
||||
#if defined(_EVENT_HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
|
||||
struct evutil_monotonic_timer monotonic_timer;
|
||||
|
||||
/** Difference between internal time (maybe from clock_gettime) and
|
||||
* gettimeofday. */
|
||||
struct timeval tv_clock_diff;
|
||||
/** Second in which we last updated tv_clock_diff, in monotonic time. */
|
||||
time_t last_updated_clock_diff;
|
||||
#endif
|
||||
|
||||
#ifndef _EVENT_DISABLE_THREAD_SUPPORT
|
||||
#ifndef EVENT__DISABLE_THREAD_SUPPORT
|
||||
/* threading support */
|
||||
/** The thread currently running the event_loop for this base */
|
||||
unsigned long th_owner_id;
|
||||
/** A lock to prevent conflicting accesses to this event_base */
|
||||
void *th_base_lock;
|
||||
/** The event whose callback is executing right now */
|
||||
struct event *current_event;
|
||||
/** A condition that gets signalled when we're done processing an
|
||||
* event with waiters on it. */
|
||||
void *current_event_cond;
|
||||
/** Number of threads blocking on current_event_cond. */
|
||||
int current_event_waiters;
|
||||
#endif
|
||||
/** The event whose callback is executing right now */
|
||||
struct event_callback *current_event;
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
/** IOCP support structure, if IOCP is enabled. */
|
||||
struct event_iocp_port *iocp;
|
||||
#endif
|
||||
|
@ -279,6 +322,10 @@ struct event_base {
|
|||
/** Flags that this base was configured with */
|
||||
enum event_base_config_flag flags;
|
||||
|
||||
struct timeval max_dispatch_time;
|
||||
int max_dispatch_callbacks;
|
||||
int limit_callbacks_after_prio;
|
||||
|
||||
/* Notify main thread to wake up break, etc. */
|
||||
/** True if the base already has a pending notify, and we don't need
|
||||
* to add any more. */
|
||||
|
@ -291,6 +338,14 @@ struct event_base {
|
|||
struct event th_notify;
|
||||
/** A function used to wake up the main thread from another thread. */
|
||||
int (*th_notify_fn)(struct event_base *base);
|
||||
|
||||
/** Saved seed for weak random number generator. Some backends use
|
||||
* this to produce fairness among sockets. Protected by th_base_lock. */
|
||||
struct evutil_weakrand_state weakrand_seed;
|
||||
|
||||
/** List of event_onces that have not yet fired. */
|
||||
LIST_HEAD(once_event_list, event_once) once_events;
|
||||
|
||||
};
|
||||
|
||||
struct event_config_entry {
|
||||
|
@ -305,12 +360,14 @@ struct event_config {
|
|||
TAILQ_HEAD(event_configq, event_config_entry) entries;
|
||||
|
||||
int n_cpus_hint;
|
||||
struct timeval max_dispatch_interval;
|
||||
int max_dispatch_callbacks;
|
||||
int limit_callbacks_after_prio;
|
||||
enum event_method_feature require_features;
|
||||
enum event_base_config_flag flags;
|
||||
};
|
||||
|
||||
/* Internal use only: Functions that might be missing from <sys/queue.h> */
|
||||
#if defined(_EVENT_HAVE_SYS_QUEUE_H) && !defined(_EVENT_HAVE_TAILQFOREACH)
|
||||
#ifndef TAILQ_FIRST
|
||||
#define TAILQ_FIRST(head) ((head)->tqh_first)
|
||||
#endif
|
||||
|
@ -336,21 +393,56 @@ struct event_config {
|
|||
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
|
||||
} while (0)
|
||||
#endif
|
||||
#endif /* TAILQ_FOREACH */
|
||||
|
||||
#define N_ACTIVE_CALLBACKS(base) \
|
||||
((base)->event_count_active + (base)->defer_queue.active_count)
|
||||
((base)->event_count_active)
|
||||
|
||||
int _evsig_set_handler(struct event_base *base, int evsignal,
|
||||
int evsig_set_handler_(struct event_base *base, int evsignal,
|
||||
void (*fn)(int));
|
||||
int _evsig_restore_handler(struct event_base *base, int evsignal);
|
||||
int evsig_restore_handler_(struct event_base *base, int evsignal);
|
||||
|
||||
int event_add_nolock_(struct event *ev,
|
||||
const struct timeval *tv, int tv_is_absolute);
|
||||
/** Argument for event_del_nolock_. Tells event_del not to block on the event
|
||||
* if it's running in another thread. */
|
||||
#define EVENT_DEL_NOBLOCK 0
|
||||
/** Argument for event_del_nolock_. Tells event_del to block on the event
|
||||
* if it's running in another thread, regardless of its value for EV_FINALIZE
|
||||
*/
|
||||
#define EVENT_DEL_BLOCK 1
|
||||
/** Argument for event_del_nolock_. Tells event_del to block on the event
|
||||
* if it is running in another thread and it doesn't have EV_FINALIZE set.
|
||||
*/
|
||||
#define EVENT_DEL_AUTOBLOCK 2
|
||||
/** Argument for event_del_nolock_. Tells event_del to procede even if the
|
||||
* event is set up for finalization rather for regular use.*/
|
||||
#define EVENT_DEL_EVEN_IF_FINALIZING 3
|
||||
int event_del_nolock_(struct event *ev, int blocking);
|
||||
int event_remove_timer_nolock_(struct event *ev);
|
||||
|
||||
void event_active_nolock_(struct event *ev, int res, short count);
|
||||
int event_callback_activate_(struct event_base *, struct event_callback *);
|
||||
int event_callback_activate_nolock_(struct event_base *, struct event_callback *);
|
||||
int event_callback_cancel_(struct event_base *base,
|
||||
struct event_callback *evcb);
|
||||
|
||||
void event_callback_finalize_nolock_(struct event_base *base, unsigned flags, struct event_callback *evcb, void (*cb)(struct event_callback *, void *));
|
||||
void event_callback_finalize_(struct event_base *base, unsigned flags, struct event_callback *evcb, void (*cb)(struct event_callback *, void *));
|
||||
int event_callback_finalize_many_(struct event_base *base, int n_cbs, struct event_callback **evcb, void (*cb)(struct event_callback *, void *));
|
||||
|
||||
|
||||
void event_active_nolock(struct event *ev, int res, short count);
|
||||
void event_active_later_(struct event *ev, int res);
|
||||
void event_active_later_nolock_(struct event *ev, int res);
|
||||
int event_callback_activate_later_nolock_(struct event_base *base,
|
||||
struct event_callback *evcb);
|
||||
int event_callback_cancel_nolock_(struct event_base *base,
|
||||
struct event_callback *evcb, int even_if_finalizing);
|
||||
void event_callback_init_(struct event_base *base,
|
||||
struct event_callback *cb);
|
||||
|
||||
/* FIXME document. */
|
||||
void event_base_add_virtual(struct event_base *base);
|
||||
void event_base_del_virtual(struct event_base *base);
|
||||
void event_base_add_virtual_(struct event_base *base);
|
||||
void event_base_del_virtual_(struct event_base *base);
|
||||
|
||||
/** For debugging: unless assertions are disabled, verify the referential
|
||||
integrity of the internal data structures of 'base'. This operation can
|
||||
|
@ -358,11 +450,30 @@ void event_base_del_virtual(struct event_base *base);
|
|||
|
||||
Returns on success; aborts on failure.
|
||||
*/
|
||||
void event_base_assert_ok(struct event_base *base);
|
||||
void event_base_assert_ok_(struct event_base *base);
|
||||
void event_base_assert_ok_nolock_(struct event_base *base);
|
||||
|
||||
|
||||
/* Helper function: Call 'fn' exactly once every inserted or active event in
|
||||
* the event_base 'base'.
|
||||
*
|
||||
* If fn returns 0, continue on to the next event. Otherwise, return the same
|
||||
* value that fn returned.
|
||||
*
|
||||
* Requires that 'base' be locked.
|
||||
*/
|
||||
int event_base_foreach_event_nolock_(struct event_base *base,
|
||||
event_base_foreach_event_cb cb, void *arg);
|
||||
|
||||
/* Cleanup function to reset debug mode during shutdown.
|
||||
*
|
||||
* Calling this function doesn't mean it'll be possible to re-enable
|
||||
* debug mode if any events were added.
|
||||
*/
|
||||
void event_disable_debug_mode(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _EVENT_INTERNAL_H_ */
|
||||
|
||||
#endif /* EVENT_INTERNAL_H_INCLUDED_ */
|
||||
|
|
|
@ -0,0 +1,624 @@
|
|||
.\" $OpenBSD: event.3,v 1.4 2002/07/12 18:50:48 provos Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2000 Artur Grabowski <art@openbsd.org>
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\"
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. The name of the author may not be used to endorse or promote products
|
||||
.\" derived from this software without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
.\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd August 8, 2000
|
||||
.Dt EVENT 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm event_init ,
|
||||
.Nm event_dispatch ,
|
||||
.Nm event_loop ,
|
||||
.Nm event_loopexit ,
|
||||
.Nm event_loopbreak ,
|
||||
.Nm event_set ,
|
||||
.Nm event_base_dispatch ,
|
||||
.Nm event_base_loop ,
|
||||
.Nm event_base_loopexit ,
|
||||
.Nm event_base_loopbreak ,
|
||||
.Nm event_base_set ,
|
||||
.Nm event_base_free ,
|
||||
.Nm event_add ,
|
||||
.Nm event_del ,
|
||||
.Nm event_once ,
|
||||
.Nm event_base_once ,
|
||||
.Nm event_pending ,
|
||||
.Nm event_initialized ,
|
||||
.Nm event_priority_init ,
|
||||
.Nm event_priority_set ,
|
||||
.Nm evtimer_set ,
|
||||
.Nm evtimer_add ,
|
||||
.Nm evtimer_del ,
|
||||
.Nm evtimer_pending ,
|
||||
.Nm evtimer_initialized ,
|
||||
.Nm signal_set ,
|
||||
.Nm signal_add ,
|
||||
.Nm signal_del ,
|
||||
.Nm signal_pending ,
|
||||
.Nm signal_initialized ,
|
||||
.Nm bufferevent_new ,
|
||||
.Nm bufferevent_free ,
|
||||
.Nm bufferevent_write ,
|
||||
.Nm bufferevent_write_buffer ,
|
||||
.Nm bufferevent_read ,
|
||||
.Nm bufferevent_enable ,
|
||||
.Nm bufferevent_disable ,
|
||||
.Nm bufferevent_settimeout ,
|
||||
.Nm bufferevent_base_set ,
|
||||
.Nm evbuffer_new ,
|
||||
.Nm evbuffer_free ,
|
||||
.Nm evbuffer_add ,
|
||||
.Nm evbuffer_add_buffer ,
|
||||
.Nm evbuffer_add_printf ,
|
||||
.Nm evbuffer_add_vprintf ,
|
||||
.Nm evbuffer_drain ,
|
||||
.Nm evbuffer_write ,
|
||||
.Nm evbuffer_read ,
|
||||
.Nm evbuffer_find ,
|
||||
.Nm evbuffer_readline ,
|
||||
.Nm evhttp_new ,
|
||||
.Nm evhttp_bind_socket ,
|
||||
.Nm evhttp_free
|
||||
.Nd execute a function when a specific event occurs
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <sys/time.h>
|
||||
.Fd #include <event.h>
|
||||
.Ft "struct event_base *"
|
||||
.Fn "event_init" "void"
|
||||
.Ft int
|
||||
.Fn "event_dispatch" "void"
|
||||
.Ft int
|
||||
.Fn "event_loop" "int flags"
|
||||
.Ft int
|
||||
.Fn "event_loopexit" "struct timeval *tv"
|
||||
.Ft int
|
||||
.Fn "event_loopbreak" "void"
|
||||
.Ft void
|
||||
.Fn "event_set" "struct event *ev" "int fd" "short event" "void (*fn)(int, short, void *)" "void *arg"
|
||||
.Ft int
|
||||
.Fn "event_base_dispatch" "struct event_base *base"
|
||||
.Ft int
|
||||
.Fn "event_base_loop" "struct event_base *base" "int flags"
|
||||
.Ft int
|
||||
.Fn "event_base_loopexit" "struct event_base *base" "struct timeval *tv"
|
||||
.Ft int
|
||||
.Fn "event_base_loopbreak" "struct event_base *base"
|
||||
.Ft int
|
||||
.Fn "event_base_set" "struct event_base *base" "struct event *"
|
||||
.Ft void
|
||||
.Fn "event_base_free" "struct event_base *base"
|
||||
.Ft int
|
||||
.Fn "event_add" "struct event *ev" "struct timeval *tv"
|
||||
.Ft int
|
||||
.Fn "event_del" "struct event *ev"
|
||||
.Ft int
|
||||
.Fn "event_once" "int fd" "short event" "void (*fn)(int, short, void *)" "void *arg" "struct timeval *tv"
|
||||
.Ft int
|
||||
.Fn "event_base_once" "struct event_base *base" "int fd" "short event" "void (*fn)(int, short, void *)" "void *arg" "struct timeval *tv"
|
||||
.Ft int
|
||||
.Fn "event_pending" "struct event *ev" "short event" "struct timeval *tv"
|
||||
.Ft int
|
||||
.Fn "event_initialized" "struct event *ev"
|
||||
.Ft int
|
||||
.Fn "event_priority_init" "int npriorities"
|
||||
.Ft int
|
||||
.Fn "event_priority_set" "struct event *ev" "int priority"
|
||||
.Ft void
|
||||
.Fn "evtimer_set" "struct event *ev" "void (*fn)(int, short, void *)" "void *arg"
|
||||
.Ft void
|
||||
.Fn "evtimer_add" "struct event *ev" "struct timeval *"
|
||||
.Ft void
|
||||
.Fn "evtimer_del" "struct event *ev"
|
||||
.Ft int
|
||||
.Fn "evtimer_pending" "struct event *ev" "struct timeval *tv"
|
||||
.Ft int
|
||||
.Fn "evtimer_initialized" "struct event *ev"
|
||||
.Ft void
|
||||
.Fn "signal_set" "struct event *ev" "int signal" "void (*fn)(int, short, void *)" "void *arg"
|
||||
.Ft void
|
||||
.Fn "signal_add" "struct event *ev" "struct timeval *"
|
||||
.Ft void
|
||||
.Fn "signal_del" "struct event *ev"
|
||||
.Ft int
|
||||
.Fn "signal_pending" "struct event *ev" "struct timeval *tv"
|
||||
.Ft int
|
||||
.Fn "signal_initialized" "struct event *ev"
|
||||
.Ft "struct bufferevent *"
|
||||
.Fn "bufferevent_new" "int fd" "evbuffercb readcb" "evbuffercb writecb" "everrorcb" "void *cbarg"
|
||||
.Ft void
|
||||
.Fn "bufferevent_free" "struct bufferevent *bufev"
|
||||
.Ft int
|
||||
.Fn "bufferevent_write" "struct bufferevent *bufev" "void *data" "size_t size"
|
||||
.Ft int
|
||||
.Fn "bufferevent_write_buffer" "struct bufferevent *bufev" "struct evbuffer *buf"
|
||||
.Ft size_t
|
||||
.Fn "bufferevent_read" "struct bufferevent *bufev" "void *data" "size_t size"
|
||||
.Ft int
|
||||
.Fn "bufferevent_enable" "struct bufferevent *bufev" "short event"
|
||||
.Ft int
|
||||
.Fn "bufferevent_disable" "struct bufferevent *bufev" "short event"
|
||||
.Ft void
|
||||
.Fn "bufferevent_settimeout" "struct bufferevent *bufev" "int timeout_read" "int timeout_write"
|
||||
.Ft int
|
||||
.Fn "bufferevent_base_set" "struct event_base *base" "struct bufferevent *bufev"
|
||||
.Ft "struct evbuffer *"
|
||||
.Fn "evbuffer_new" "void"
|
||||
.Ft void
|
||||
.Fn "evbuffer_free" "struct evbuffer *buf"
|
||||
.Ft int
|
||||
.Fn "evbuffer_add" "struct evbuffer *buf" "const void *data" "size_t size"
|
||||
.Ft int
|
||||
.Fn "evbuffer_add_buffer" "struct evbuffer *dst" "struct evbuffer *src"
|
||||
.Ft int
|
||||
.Fn "evbuffer_add_printf" "struct evbuffer *buf" "const char *fmt" "..."
|
||||
.Ft int
|
||||
.Fn "evbuffer_add_vprintf" "struct evbuffer *buf" "const char *fmt" "va_list ap"
|
||||
.Ft void
|
||||
.Fn "evbuffer_drain" "struct evbuffer *buf" "size_t size"
|
||||
.Ft int
|
||||
.Fn "evbuffer_write" "struct evbuffer *buf" "int fd"
|
||||
.Ft int
|
||||
.Fn "evbuffer_read" "struct evbuffer *buf" "int fd" "int size"
|
||||
.Ft "unsigned char *"
|
||||
.Fn "evbuffer_find" "struct evbuffer *buf" "const unsigned char *data" "size_t size"
|
||||
.Ft "char *"
|
||||
.Fn "evbuffer_readline" "struct evbuffer *buf"
|
||||
.Ft "struct evhttp *"
|
||||
.Fn "evhttp_new" "struct event_base *base"
|
||||
.Ft int
|
||||
.Fn "evhttp_bind_socket" "struct evhttp *http" "const char *address" "unsigned short port"
|
||||
.Ft "void"
|
||||
.Fn "evhttp_free" "struct evhttp *http"
|
||||
.Ft int
|
||||
.Fa (*event_sigcb)(void) ;
|
||||
.Ft volatile sig_atomic_t
|
||||
.Fa event_gotsig ;
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm event
|
||||
API provides a mechanism to execute a function when a specific event
|
||||
on a file descriptor occurs or after a given time has passed.
|
||||
.Pp
|
||||
The
|
||||
.Nm event
|
||||
API needs to be initialized with
|
||||
.Fn event_init
|
||||
before it can be used.
|
||||
.Pp
|
||||
In order to process events, an application needs to call
|
||||
.Fn event_dispatch .
|
||||
This function only returns on error, and should replace the event core
|
||||
of the application program.
|
||||
.Pp
|
||||
The function
|
||||
.Fn event_set
|
||||
prepares the event structure
|
||||
.Fa ev
|
||||
to be used in future calls to
|
||||
.Fn event_add
|
||||
and
|
||||
.Fn event_del .
|
||||
The event will be prepared to call the function specified by the
|
||||
.Fa fn
|
||||
argument with an
|
||||
.Fa int
|
||||
argument indicating the file descriptor, a
|
||||
.Fa short
|
||||
argument indicating the type of event, and a
|
||||
.Fa void *
|
||||
argument given in the
|
||||
.Fa arg
|
||||
argument.
|
||||
The
|
||||
.Fa fd
|
||||
indicates the file descriptor that should be monitored for events.
|
||||
The events can be either
|
||||
.Va EV_READ ,
|
||||
.Va EV_WRITE ,
|
||||
or both,
|
||||
indicating that an application can read or write from the file descriptor
|
||||
respectively without blocking.
|
||||
.Pp
|
||||
The function
|
||||
.Fa fn
|
||||
will be called with the file descriptor that triggered the event and
|
||||
the type of event which will be either
|
||||
.Va EV_TIMEOUT ,
|
||||
.Va EV_SIGNAL ,
|
||||
.Va EV_READ ,
|
||||
or
|
||||
.Va EV_WRITE .
|
||||
Additionally, an event which has registered interest in more than one of the
|
||||
preceeding events, via bitwise-OR to
|
||||
.Fn event_set ,
|
||||
can provide its callback function with a bitwise-OR of more than one triggered
|
||||
event.
|
||||
The additional flag
|
||||
.Va EV_PERSIST
|
||||
makes an
|
||||
.Fn event_add
|
||||
persistent until
|
||||
.Fn event_del
|
||||
has been called.
|
||||
.Pp
|
||||
Once initialized, the
|
||||
.Fa ev
|
||||
structure can be used repeatedly with
|
||||
.Fn event_add
|
||||
and
|
||||
.Fn event_del
|
||||
and does not need to be reinitialized unless the function called and/or
|
||||
the argument to it are to be changed.
|
||||
However, when an
|
||||
.Fa ev
|
||||
structure has been added to libevent using
|
||||
.Fn event_add
|
||||
the structure must persist until the event occurs (assuming
|
||||
.Fa EV_PERSIST
|
||||
is not set) or is removed
|
||||
using
|
||||
.Fn event_del .
|
||||
You may not reuse the same
|
||||
.Fa ev
|
||||
structure for multiple monitored descriptors; each descriptor
|
||||
needs its own
|
||||
.Fa ev .
|
||||
.Pp
|
||||
The function
|
||||
.Fn event_add
|
||||
schedules the execution of the
|
||||
.Fa ev
|
||||
event when the event specified in
|
||||
.Fn event_set
|
||||
occurs or in at least the time specified in the
|
||||
.Fa tv .
|
||||
If
|
||||
.Fa tv
|
||||
is
|
||||
.Dv NULL ,
|
||||
no timeout occurs and the function will only be called
|
||||
if a matching event occurs on the file descriptor.
|
||||
The event in the
|
||||
.Fa ev
|
||||
argument must be already initialized by
|
||||
.Fn event_set
|
||||
and may not be used in calls to
|
||||
.Fn event_set
|
||||
until it has timed out or been removed with
|
||||
.Fn event_del .
|
||||
If the event in the
|
||||
.Fa ev
|
||||
argument already has a scheduled timeout, the old timeout will be
|
||||
replaced by the new one.
|
||||
.Pp
|
||||
The function
|
||||
.Fn event_del
|
||||
will cancel the event in the argument
|
||||
.Fa ev .
|
||||
If the event has already executed or has never been added
|
||||
the call will have no effect.
|
||||
.Pp
|
||||
The functions
|
||||
.Fn evtimer_set ,
|
||||
.Fn evtimer_add ,
|
||||
.Fn evtimer_del ,
|
||||
.Fn evtimer_initialized ,
|
||||
and
|
||||
.Fn evtimer_pending
|
||||
are abbreviations for common situations where only a timeout is required.
|
||||
The file descriptor passed will be \-1, and the event type will be
|
||||
.Va EV_TIMEOUT .
|
||||
.Pp
|
||||
The functions
|
||||
.Fn signal_set ,
|
||||
.Fn signal_add ,
|
||||
.Fn signal_del ,
|
||||
.Fn signal_initialized ,
|
||||
and
|
||||
.Fn signal_pending
|
||||
are abbreviations.
|
||||
The event type will be a persistent
|
||||
.Va EV_SIGNAL .
|
||||
That means
|
||||
.Fn signal_set
|
||||
adds
|
||||
.Va EV_PERSIST .
|
||||
.Pp
|
||||
In order to avoid races in signal handlers, the
|
||||
.Nm event
|
||||
API provides two variables:
|
||||
.Va event_sigcb
|
||||
and
|
||||
.Va event_gotsig .
|
||||
A signal handler
|
||||
sets
|
||||
.Va event_gotsig
|
||||
to indicate that a signal has been received.
|
||||
The application sets
|
||||
.Va event_sigcb
|
||||
to a callback function.
|
||||
After the signal handler sets
|
||||
.Va event_gotsig ,
|
||||
.Nm event_dispatch
|
||||
will execute the callback function to process received signals.
|
||||
The callback returns 1 when no events are registered any more.
|
||||
It can return \-1 to indicate an error to the
|
||||
.Nm event
|
||||
library, causing
|
||||
.Fn event_dispatch
|
||||
to terminate with
|
||||
.Va errno
|
||||
set to
|
||||
.Er EINTR .
|
||||
.Pp
|
||||
The function
|
||||
.Fn event_once
|
||||
is similar to
|
||||
.Fn event_set .
|
||||
However, it schedules a callback to be called exactly once and does not
|
||||
require the caller to prepare an
|
||||
.Fa event
|
||||
structure.
|
||||
This function supports
|
||||
.Fa EV_TIMEOUT ,
|
||||
.Fa EV_READ ,
|
||||
and
|
||||
.Fa EV_WRITE .
|
||||
.Pp
|
||||
The
|
||||
.Fn event_pending
|
||||
function can be used to check if the event specified by
|
||||
.Fa event
|
||||
is pending to run.
|
||||
If
|
||||
.Va EV_TIMEOUT
|
||||
was specified and
|
||||
.Fa tv
|
||||
is not
|
||||
.Dv NULL ,
|
||||
the expiration time of the event will be returned in
|
||||
.Fa tv .
|
||||
.Pp
|
||||
The
|
||||
.Fn event_initialized
|
||||
macro can be used to check if an event has been initialized.
|
||||
.Pp
|
||||
The
|
||||
.Nm event_loop
|
||||
function provides an interface for single pass execution of pending
|
||||
events.
|
||||
The flags
|
||||
.Va EVLOOP_ONCE
|
||||
and
|
||||
.Va EVLOOP_NONBLOCK
|
||||
are recognized.
|
||||
The
|
||||
.Nm event_loopexit
|
||||
function exits from the event loop. The next
|
||||
.Fn event_loop
|
||||
iteration after the
|
||||
given timer expires will complete normally (handling all queued events) then
|
||||
exit without blocking for events again. Subsequent invocations of
|
||||
.Fn event_loop
|
||||
will proceed normally.
|
||||
The
|
||||
.Nm event_loopbreak
|
||||
function exits from the event loop immediately.
|
||||
.Fn event_loop
|
||||
will abort after the next event is completed;
|
||||
.Fn event_loopbreak
|
||||
is typically invoked from this event's callback. This behavior is analogous
|
||||
to the "break;" statement. Subsequent invocations of
|
||||
.Fn event_loop
|
||||
will proceed normally.
|
||||
.Pp
|
||||
It is the responsibility of the caller to provide these functions with
|
||||
pre-allocated event structures.
|
||||
.Pp
|
||||
.Sh EVENT PRIORITIES
|
||||
By default
|
||||
.Nm libevent
|
||||
schedules all active events with the same priority.
|
||||
However, sometimes it is desirable to process some events with a higher
|
||||
priority than others.
|
||||
For that reason,
|
||||
.Nm libevent
|
||||
supports strict priority queues.
|
||||
Active events with a lower priority are always processed before events
|
||||
with a higher priority.
|
||||
.Pp
|
||||
The number of different priorities can be set initially with the
|
||||
.Fn event_priority_init
|
||||
function.
|
||||
This function should be called before the first call to
|
||||
.Fn event_dispatch .
|
||||
The
|
||||
.Fn event_priority_set
|
||||
function can be used to assign a priority to an event.
|
||||
By default,
|
||||
.Nm libevent
|
||||
assigns the middle priority to all events unless their priority
|
||||
is explicitly set.
|
||||
.Sh THREAD SAFE EVENTS
|
||||
.Nm Libevent
|
||||
has experimental support for thread-safe events.
|
||||
When initializing the library via
|
||||
.Fn event_init ,
|
||||
an event base is returned.
|
||||
This event base can be used in conjunction with calls to
|
||||
.Fn event_base_set ,
|
||||
.Fn event_base_dispatch ,
|
||||
.Fn event_base_loop ,
|
||||
.Fn event_base_loopexit ,
|
||||
.Fn bufferevent_base_set
|
||||
and
|
||||
.Fn event_base_free .
|
||||
.Fn event_base_set
|
||||
should be called after preparing an event with
|
||||
.Fn event_set ,
|
||||
as
|
||||
.Fn event_set
|
||||
assigns the provided event to the most recently created event base.
|
||||
.Fn bufferevent_base_set
|
||||
should be called after preparing a bufferevent with
|
||||
.Fn bufferevent_new .
|
||||
.Fn event_base_free
|
||||
should be used to free memory associated with the event base
|
||||
when it is no longer needed.
|
||||
.Sh BUFFERED EVENTS
|
||||
.Nm libevent
|
||||
provides an abstraction on top of the regular event callbacks.
|
||||
This abstraction is called a
|
||||
.Va "buffered event" .
|
||||
A buffered event provides input and output buffers that get filled
|
||||
and drained automatically.
|
||||
The user of a buffered event no longer deals directly with the IO,
|
||||
but instead is reading from input and writing to output buffers.
|
||||
.Pp
|
||||
A new bufferevent is created by
|
||||
.Fn bufferevent_new .
|
||||
The parameter
|
||||
.Fa fd
|
||||
specifies the file descriptor from which data is read and written to.
|
||||
This file descriptor is not allowed to be a
|
||||
.Xr pipe 2 .
|
||||
The next three parameters are callbacks.
|
||||
The read and write callback have the following form:
|
||||
.Ft void
|
||||
.Fn "(*cb)" "struct bufferevent *bufev" "void *arg" .
|
||||
The error callback has the following form:
|
||||
.Ft void
|
||||
.Fn "(*cb)" "struct bufferevent *bufev" "short what" "void *arg" .
|
||||
The argument is specified by the fourth parameter
|
||||
.Fa "cbarg" .
|
||||
A
|
||||
.Fa bufferevent struct
|
||||
pointer is returned on success, NULL on error.
|
||||
Both the read and the write callback may be NULL.
|
||||
The error callback has to be always provided.
|
||||
.Pp
|
||||
Once initialized, the bufferevent structure can be used repeatedly with
|
||||
bufferevent_enable() and bufferevent_disable().
|
||||
The flags parameter can be a combination of
|
||||
.Va EV_READ
|
||||
and
|
||||
.Va EV_WRITE .
|
||||
When read enabled the bufferevent will try to read from the file
|
||||
descriptor and call the read callback.
|
||||
The write callback is executed
|
||||
whenever the output buffer is drained below the write low watermark,
|
||||
which is
|
||||
.Va 0
|
||||
by default.
|
||||
.Pp
|
||||
The
|
||||
.Fn bufferevent_write
|
||||
function can be used to write data to the file descriptor.
|
||||
The data is appended to the output buffer and written to the descriptor
|
||||
automatically as it becomes available for writing.
|
||||
.Fn bufferevent_write
|
||||
returns 0 on success or \-1 on failure.
|
||||
The
|
||||
.Fn bufferevent_read
|
||||
function is used to read data from the input buffer,
|
||||
returning the amount of data read.
|
||||
.Pp
|
||||
If multiple bases are in use, bufferevent_base_set() must be called before
|
||||
enabling the bufferevent for the first time.
|
||||
.Sh NON-BLOCKING HTTP SUPPORT
|
||||
.Nm libevent
|
||||
provides a very thin HTTP layer that can be used both to host an HTTP
|
||||
server and also to make HTTP requests.
|
||||
An HTTP server can be created by calling
|
||||
.Fn evhttp_new .
|
||||
It can be bound to any port and address with the
|
||||
.Fn evhttp_bind_socket
|
||||
function.
|
||||
When the HTTP server is no longer used, it can be freed via
|
||||
.Fn evhttp_free .
|
||||
.Pp
|
||||
To be notified of HTTP requests, a user needs to register callbacks with the
|
||||
HTTP server.
|
||||
This can be done by calling
|
||||
.Fn evhttp_set_cb .
|
||||
The second argument is the URI for which a callback is being registered.
|
||||
The corresponding callback will receive an
|
||||
.Va struct evhttp_request
|
||||
object that contains all information about the request.
|
||||
.Pp
|
||||
This section does not document all the possible function calls; please
|
||||
check
|
||||
.Va event.h
|
||||
for the public interfaces.
|
||||
.Sh ADDITIONAL NOTES
|
||||
It is possible to disable support for
|
||||
.Va epoll , kqueue , devpoll , poll
|
||||
or
|
||||
.Va select
|
||||
by setting the environment variable
|
||||
.Va EVENT_NOEPOLL , EVENT_NOKQUEUE , EVENT_NODEVPOLL , EVENT_NOPOLL
|
||||
or
|
||||
.Va EVENT_NOSELECT ,
|
||||
respectively.
|
||||
By setting the environment variable
|
||||
.Va EVENT_SHOW_METHOD ,
|
||||
.Nm libevent
|
||||
displays the kernel notification method that it uses.
|
||||
.Sh RETURN VALUES
|
||||
Upon successful completion
|
||||
.Fn event_add
|
||||
and
|
||||
.Fn event_del
|
||||
return 0.
|
||||
Otherwise, \-1 is returned and the global variable errno is
|
||||
set to indicate the error.
|
||||
.Sh SEE ALSO
|
||||
.Xr kqueue 2 ,
|
||||
.Xr poll 2 ,
|
||||
.Xr select 2 ,
|
||||
.Xr evdns 3 ,
|
||||
.Xr timeout 9
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm event
|
||||
API manpage is based on the
|
||||
.Xr timeout 9
|
||||
manpage by Artur Grabowski.
|
||||
The port of
|
||||
.Nm libevent
|
||||
to Windows is due to Michael A. Davis.
|
||||
Support for real-time signals is due to Taral.
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm event
|
||||
library was written by Niels Provos.
|
||||
.Sh BUGS
|
||||
This documentation is neither complete nor authoritative.
|
||||
If you are in doubt about the usage of this API then
|
||||
check the source code to find out how it works, write
|
||||
up the missing piece of documentation and send it to
|
||||
me for inclusion in this man page.
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -23,6 +23,7 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#ifndef _WIN32_WINNT
|
||||
/* Minimum required for InitializeCriticalSectionAndSpinCount */
|
||||
|
@ -45,7 +46,7 @@
|
|||
#define NOTIFICATION_KEY ((ULONG_PTR)-1)
|
||||
|
||||
void
|
||||
event_overlapped_init(struct event_overlapped *o, iocp_callback cb)
|
||||
event_overlapped_init_(struct event_overlapped *o, iocp_callback cb)
|
||||
{
|
||||
memset(o, 0, sizeof(struct event_overlapped));
|
||||
o->cb = cb;
|
||||
|
@ -60,9 +61,9 @@ handle_entry(OVERLAPPED *o, ULONG_PTR completion_key, DWORD nBytes, int ok)
|
|||
}
|
||||
|
||||
static void
|
||||
loop(void *_port)
|
||||
loop(void *port_)
|
||||
{
|
||||
struct event_iocp_port *port = _port;
|
||||
struct event_iocp_port *port = port_;
|
||||
long ms = port->ms;
|
||||
HANDLE p = port->port;
|
||||
|
||||
|
@ -98,7 +99,7 @@ loop(void *_port)
|
|||
}
|
||||
|
||||
int
|
||||
event_iocp_port_associate(struct event_iocp_port *port, evutil_socket_t fd,
|
||||
event_iocp_port_associate_(struct event_iocp_port *port, evutil_socket_t fd,
|
||||
ev_uintptr_t key)
|
||||
{
|
||||
HANDLE h;
|
||||
|
@ -164,7 +165,7 @@ init_extension_functions(struct win32_extension_fns *ext)
|
|||
static struct win32_extension_fns the_extension_fns;
|
||||
|
||||
const struct win32_extension_fns *
|
||||
event_get_win32_extension_fns(void)
|
||||
event_get_win32_extension_fns_(void)
|
||||
{
|
||||
return &the_extension_fns;
|
||||
}
|
||||
|
@ -172,7 +173,7 @@ event_get_win32_extension_fns(void)
|
|||
#define N_CPUS_DEFAULT 2
|
||||
|
||||
struct event_iocp_port *
|
||||
event_iocp_port_launch(int n_cpus)
|
||||
event_iocp_port_launch_(int n_cpus)
|
||||
{
|
||||
struct event_iocp_port *port;
|
||||
int i;
|
||||
|
@ -223,7 +224,7 @@ err:
|
|||
}
|
||||
|
||||
static void
|
||||
_event_iocp_port_unlock_and_free(struct event_iocp_port *port)
|
||||
event_iocp_port_unlock_and_free_(struct event_iocp_port *port)
|
||||
{
|
||||
DeleteCriticalSection(&port->lock);
|
||||
CloseHandle(port->port);
|
||||
|
@ -246,7 +247,7 @@ event_iocp_notify_all(struct event_iocp_port *port)
|
|||
}
|
||||
|
||||
int
|
||||
event_iocp_shutdown(struct event_iocp_port *port, long waitMsec)
|
||||
event_iocp_shutdown_(struct event_iocp_port *port, long waitMsec)
|
||||
{
|
||||
DWORD ms = INFINITE;
|
||||
int n;
|
||||
|
@ -264,7 +265,7 @@ event_iocp_shutdown(struct event_iocp_port *port, long waitMsec)
|
|||
n = port->n_live_threads;
|
||||
LeaveCriticalSection(&port->lock);
|
||||
if (n == 0) {
|
||||
_event_iocp_port_unlock_and_free(port);
|
||||
event_iocp_port_unlock_and_free_(port);
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
|
@ -272,7 +273,7 @@ event_iocp_shutdown(struct event_iocp_port *port, long waitMsec)
|
|||
}
|
||||
|
||||
int
|
||||
event_iocp_activate_overlapped(
|
||||
event_iocp_activate_overlapped_(
|
||||
struct event_iocp_port *port, struct event_overlapped *o,
|
||||
ev_uintptr_t key, ev_uint32_t n)
|
||||
{
|
||||
|
@ -283,9 +284,9 @@ event_iocp_activate_overlapped(
|
|||
}
|
||||
|
||||
struct event_iocp_port *
|
||||
event_base_get_iocp(struct event_base *base)
|
||||
event_base_get_iocp_(struct event_base *base)
|
||||
{
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
return base->iocp;
|
||||
#else
|
||||
return NULL;
|
||||
|
|
|
@ -32,6 +32,12 @@ structdef = re.compile(r'^struct +[a-zA-Z_][a-zA-Z0-9_]* *{$')
|
|||
headerdirect = []
|
||||
cppdirect = []
|
||||
|
||||
QUIETLY = 0
|
||||
|
||||
def declare(s):
|
||||
if not QUIETLY:
|
||||
print s
|
||||
|
||||
def TranslateList(mylist, mydict):
|
||||
return map(lambda x: x % mydict, mylist)
|
||||
|
||||
|
@ -48,7 +54,7 @@ class Struct:
|
|||
self._name = name
|
||||
self._entries = []
|
||||
self._tags = {}
|
||||
print >>sys.stderr, ' Created struct: %s' % name
|
||||
declare(' Created struct: %s' % name)
|
||||
|
||||
def AddEntry(self, entry):
|
||||
if self._tags.has_key(entry.Tag()):
|
||||
|
@ -58,7 +64,7 @@ class Struct:
|
|||
self._tags[entry.Tag()], line_count))
|
||||
self._entries.append(entry)
|
||||
self._tags[entry.Tag()] = entry.Name()
|
||||
print >>sys.stderr, ' Added entry: %s' % entry.Name()
|
||||
declare(' Added entry: %s' % entry.Name())
|
||||
|
||||
def Name(self):
|
||||
return self._name
|
||||
|
@ -148,7 +154,7 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, ev_uint32_t,
|
|||
' */\n') % self._name
|
||||
|
||||
print >>file, \
|
||||
'static struct %(name)s_access_ __%(name)s_base = {' % \
|
||||
'static struct %(name)s_access_ %(name)s_base__ = {' % \
|
||||
{ 'name' : self._name }
|
||||
for entry in self._entries:
|
||||
self.PrintIndented(file, ' ', entry.CodeBase())
|
||||
|
@ -170,7 +176,7 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, ev_uint32_t,
|
|||
' event_warn("%%s: malloc", __func__);\n'
|
||||
' return (NULL);\n'
|
||||
' }\n'
|
||||
' tmp->base = &__%(name)s_base;\n') % { 'name' : self._name }
|
||||
' tmp->base = &%(name)s_base__;\n') % { 'name' : self._name }
|
||||
|
||||
for entry in self._entries:
|
||||
self.PrintIndented(file, ' ', entry.CodeInitialize('tmp'))
|
||||
|
@ -332,11 +338,11 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, ev_uint32_t,
|
|||
'evtag_marshal_%(name)s(struct evbuffer *evbuf, ev_uint32_t tag, '
|
||||
'const struct %(name)s *msg)\n'
|
||||
'{\n'
|
||||
' struct evbuffer *_buf = evbuffer_new();\n'
|
||||
' assert(_buf != NULL);\n'
|
||||
' %(name)s_marshal(_buf, msg);\n'
|
||||
' evtag_marshal_buffer(evbuf, tag, _buf);\n '
|
||||
' evbuffer_free(_buf);\n'
|
||||
' struct evbuffer *buf_ = evbuffer_new();\n'
|
||||
' assert(buf_ != NULL);\n'
|
||||
' %(name)s_marshal(buf_, msg);\n'
|
||||
' evtag_marshal_buffer(evbuf, tag, buf_);\n '
|
||||
' evbuffer_free(buf_);\n'
|
||||
'}\n' ) % { 'name' : self._name }
|
||||
|
||||
class Entry:
|
||||
|
@ -1532,7 +1538,7 @@ class CCodeGenerator:
|
|||
# Use the complete provided path to the input file, with all
|
||||
# non-identifier characters replaced with underscores, to
|
||||
# reduce the chance of a collision between guard macros.
|
||||
return '_' + nonident.sub('_', name).upper() + '_'
|
||||
return 'EVENT_RPCOUT_' + nonident.sub('_', name).upper() + '_'
|
||||
|
||||
def HeaderPreamble(self, name):
|
||||
guard = self.GuardName(name)
|
||||
|
@ -1579,8 +1585,8 @@ class CCodeGenerator:
|
|||
'#include <event2/event.h>\n'
|
||||
'#include <event2/buffer.h>\n'
|
||||
'#include <event2/tag.h>\n\n'
|
||||
'#ifdef _EVENT___func__\n'
|
||||
'#define __func__ _EVENT___func__\n'
|
||||
'#if defined(EVENT____func__) && !defined(__func__)\n'
|
||||
'#define __func__ EVENT____func__\n'
|
||||
'#endif\n\n'
|
||||
)
|
||||
|
||||
|
@ -1638,6 +1644,11 @@ class CommandLine:
|
|||
self.impl_file = None
|
||||
self.factory = CCodeGenerator()
|
||||
|
||||
if len(argv) >= 2 and argv[1] == '--quiet':
|
||||
global QUIETLY
|
||||
QUIETLY = 1
|
||||
del argv[1]
|
||||
|
||||
if len(argv) < 2 or len(argv) > 4:
|
||||
raise Usage(argv[0])
|
||||
|
||||
|
@ -1668,13 +1679,13 @@ class CommandLine:
|
|||
impl_file = self.impl_file
|
||||
factory = self.factory
|
||||
|
||||
print >>sys.stderr, 'Reading \"%s\"' % filename
|
||||
declare('Reading \"%s\"' % filename)
|
||||
|
||||
fp = open(filename, 'r')
|
||||
entities = Parse(factory, fp)
|
||||
fp.close()
|
||||
|
||||
print >>sys.stderr, '... creating "%s"' % header_file
|
||||
declare('... creating "%s"' % header_file)
|
||||
header_fp = open(header_file, 'w')
|
||||
print >>header_fp, factory.HeaderPreamble(filename)
|
||||
|
||||
|
@ -1690,7 +1701,7 @@ class CommandLine:
|
|||
print >>header_fp, factory.HeaderPostamble(filename)
|
||||
header_fp.close()
|
||||
|
||||
print >>sys.stderr, '... creating "%s"' % impl_file
|
||||
declare('... creating "%s"' % impl_file)
|
||||
impl_fp = open(impl_file, 'w')
|
||||
print >>impl_fp, factory.BodyPreamble(filename, header_file)
|
||||
for entry in entities:
|
||||
|
|
|
@ -26,25 +26,27 @@
|
|||
*/
|
||||
|
||||
#include "event2/event-config.h"
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#ifdef _EVENT_HAVE_SYS_TYPES_H
|
||||
#ifdef EVENT__HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef _EVENT_HAVE_SYS_PARAM_H
|
||||
#ifdef EVENT__HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#else
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#ifdef EVENT__HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
#include <sys/queue.h>
|
||||
#ifdef _EVENT_HAVE_SYS_TIME_H
|
||||
#ifdef EVENT__HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
|
@ -52,10 +54,10 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
#ifdef _EVENT_HAVE_UNISTD_H
|
||||
#ifdef EVENT__HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
|
@ -211,7 +213,14 @@ decode_tag_internal(ev_uint32_t *ptag, struct evbuffer *evbuf, int dodrain)
|
|||
|
||||
while (count++ < len) {
|
||||
ev_uint8_t lower = *data++;
|
||||
number |= (lower & 0x7f) << shift;
|
||||
if (shift >= 28) {
|
||||
/* Make sure it fits into 32 bits */
|
||||
if (shift > 28)
|
||||
return (-1);
|
||||
if ((lower & 0x7f) > 15)
|
||||
return (-1);
|
||||
}
|
||||
number |= (lower & (unsigned)0x7f) << shift;
|
||||
shift += 7;
|
||||
|
||||
if (!(lower & 0x80)) {
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _EVMAP_H_
|
||||
#define _EVMAP_H_
|
||||
#ifndef EVMAP_INTERNAL_H_INCLUDED_
|
||||
#define EVMAP_INTERNAL_H_INCLUDED_
|
||||
|
||||
/** @file evmap-internal.h
|
||||
*
|
||||
|
@ -39,15 +39,15 @@ struct event;
|
|||
|
||||
/** Initialize an event_map for use.
|
||||
*/
|
||||
void evmap_io_initmap(struct event_io_map* ctx);
|
||||
void evmap_signal_initmap(struct event_signal_map* ctx);
|
||||
void evmap_io_initmap_(struct event_io_map* ctx);
|
||||
void evmap_signal_initmap_(struct event_signal_map* ctx);
|
||||
|
||||
/** Remove all entries from an event_map.
|
||||
|
||||
@param ctx the map to clear.
|
||||
*/
|
||||
void evmap_io_clear(struct event_io_map* ctx);
|
||||
void evmap_signal_clear(struct event_signal_map* ctx);
|
||||
void evmap_io_clear_(struct event_io_map* ctx);
|
||||
void evmap_signal_clear_(struct event_signal_map* ctx);
|
||||
|
||||
/** Add an IO event (some combination of EV_READ or EV_WRITE) to an
|
||||
event_base's list of events on a given file descriptor, and tell the
|
||||
|
@ -59,7 +59,7 @@ void evmap_signal_clear(struct event_signal_map* ctx);
|
|||
@param fd the file descriptor corresponding to ev.
|
||||
@param ev the event to add.
|
||||
*/
|
||||
int evmap_io_add(struct event_base *base, evutil_socket_t fd, struct event *ev);
|
||||
int evmap_io_add_(struct event_base *base, evutil_socket_t fd, struct event *ev);
|
||||
/** Remove an IO event (some combination of EV_READ or EV_WRITE) to an
|
||||
event_base's list of events on a given file descriptor, and tell the
|
||||
underlying eventops about the fd if its state has changed.
|
||||
|
@ -68,25 +68,50 @@ int evmap_io_add(struct event_base *base, evutil_socket_t fd, struct event *ev);
|
|||
@param fd the file descriptor corresponding to ev.
|
||||
@param ev the event to remove.
|
||||
*/
|
||||
int evmap_io_del(struct event_base *base, evutil_socket_t fd, struct event *ev);
|
||||
int evmap_io_del_(struct event_base *base, evutil_socket_t fd, struct event *ev);
|
||||
/** Active the set of events waiting on an event_base for a given fd.
|
||||
|
||||
@param base the event_base to operate on.
|
||||
@param fd the file descriptor that has become active.
|
||||
@param events a bitmask of EV_READ|EV_WRITE|EV_ET.
|
||||
*/
|
||||
void evmap_io_active(struct event_base *base, evutil_socket_t fd, short events);
|
||||
void evmap_io_active_(struct event_base *base, evutil_socket_t fd, short events);
|
||||
|
||||
|
||||
/* These functions behave in the same way as evmap_io_*, except they work on
|
||||
* signals rather than fds. signals use a linear map everywhere; fds use
|
||||
* either a linear map or a hashtable. */
|
||||
int evmap_signal_add(struct event_base *base, int signum, struct event *ev);
|
||||
int evmap_signal_del(struct event_base *base, int signum, struct event *ev);
|
||||
void evmap_signal_active(struct event_base *base, evutil_socket_t signum, int ncalls);
|
||||
int evmap_signal_add_(struct event_base *base, int signum, struct event *ev);
|
||||
int evmap_signal_del_(struct event_base *base, int signum, struct event *ev);
|
||||
void evmap_signal_active_(struct event_base *base, evutil_socket_t signum, int ncalls);
|
||||
|
||||
void *evmap_io_get_fdinfo(struct event_io_map *ctx, evutil_socket_t fd);
|
||||
/* Return the fdinfo object associated with a given fd. If the fd has no
|
||||
* events associated with it, the result may be NULL.
|
||||
*/
|
||||
void *evmap_io_get_fdinfo_(struct event_io_map *ctx, evutil_socket_t fd);
|
||||
|
||||
void evmap_check_integrity(struct event_base *base);
|
||||
/* Helper for event_reinit(): Tell the backend to re-add every fd and signal
|
||||
* for which we have a pending event.
|
||||
*/
|
||||
int evmap_reinit_(struct event_base *base);
|
||||
|
||||
#endif /* _EVMAP_H_ */
|
||||
/* Helper for event_base_free(): Call event_del() on every pending fd and
|
||||
* signal event.
|
||||
*/
|
||||
void evmap_delete_all_(struct event_base *base);
|
||||
|
||||
/* Helper for event_base_assert_ok_(): Check referential integrity of the
|
||||
* evmaps.
|
||||
*/
|
||||
void evmap_check_integrity_(struct event_base *base);
|
||||
|
||||
/* Helper: Call fn on every fd or signal event, passing as its arguments the
|
||||
* provided event_base, the event, and arg. If fn returns 0, process the next
|
||||
* event. If it returns any other value, return that value and process no
|
||||
* more events.
|
||||
*/
|
||||
int evmap_foreach_event_(struct event_base *base,
|
||||
event_base_foreach_event_cb fn,
|
||||
void *arg);
|
||||
|
||||
#endif /* EVMAP_INTERNAL_H_INCLUDED_ */
|
||||
|
|
|
@ -24,21 +24,22 @@
|
|||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "event2/event-config.h"
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#if !defined(WIN32) && defined(_EVENT_HAVE_SYS_TIME_H)
|
||||
#if !defined(_WIN32) && defined(EVENT__HAVE_SYS_TIME_H)
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include <sys/queue.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
|
@ -55,15 +56,16 @@
|
|||
write on a given fd, and the number of each.
|
||||
*/
|
||||
struct evmap_io {
|
||||
struct event_list events;
|
||||
struct event_dlist events;
|
||||
ev_uint16_t nread;
|
||||
ev_uint16_t nwrite;
|
||||
ev_uint16_t nclose;
|
||||
};
|
||||
|
||||
/* An entry for an evmap_signal list: notes all the events that want to know
|
||||
when a signal triggers. */
|
||||
struct evmap_signal {
|
||||
struct event_list events;
|
||||
struct event_dlist events;
|
||||
};
|
||||
|
||||
/* On some platforms, fds start at 0 and increment by 1 as they are
|
||||
|
@ -110,38 +112,38 @@ HT_GENERATE(event_io_map, event_map_entry, map_node, hashsocket, eqsocket,
|
|||
|
||||
#define GET_IO_SLOT(x, map, slot, type) \
|
||||
do { \
|
||||
struct event_map_entry _key, *_ent; \
|
||||
_key.fd = slot; \
|
||||
_ent = HT_FIND(event_io_map, map, &_key); \
|
||||
(x) = _ent ? &_ent->ent.type : NULL; \
|
||||
struct event_map_entry key_, *ent_; \
|
||||
key_.fd = slot; \
|
||||
ent_ = HT_FIND(event_io_map, map, &key_); \
|
||||
(x) = ent_ ? &ent_->ent.type : NULL; \
|
||||
} while (0);
|
||||
|
||||
#define GET_IO_SLOT_AND_CTOR(x, map, slot, type, ctor, fdinfo_len) \
|
||||
do { \
|
||||
struct event_map_entry _key, *_ent; \
|
||||
_key.fd = slot; \
|
||||
_HT_FIND_OR_INSERT(event_io_map, map_node, hashsocket, map, \
|
||||
event_map_entry, &_key, ptr, \
|
||||
struct event_map_entry key_, *ent_; \
|
||||
key_.fd = slot; \
|
||||
HT_FIND_OR_INSERT_(event_io_map, map_node, hashsocket, map, \
|
||||
event_map_entry, &key_, ptr, \
|
||||
{ \
|
||||
_ent = *ptr; \
|
||||
ent_ = *ptr; \
|
||||
}, \
|
||||
{ \
|
||||
_ent = mm_calloc(1,sizeof(struct event_map_entry)+fdinfo_len); \
|
||||
if (EVUTIL_UNLIKELY(_ent == NULL)) \
|
||||
ent_ = mm_calloc(1,sizeof(struct event_map_entry)+fdinfo_len); \
|
||||
if (EVUTIL_UNLIKELY(ent_ == NULL)) \
|
||||
return (-1); \
|
||||
_ent->fd = slot; \
|
||||
(ctor)(&_ent->ent.type); \
|
||||
_HT_FOI_INSERT(map_node, map, &_key, _ent, ptr) \
|
||||
ent_->fd = slot; \
|
||||
(ctor)(&ent_->ent.type); \
|
||||
HT_FOI_INSERT_(map_node, map, &key_, ent_, ptr) \
|
||||
}); \
|
||||
(x) = &_ent->ent.type; \
|
||||
(x) = &ent_->ent.type; \
|
||||
} while (0)
|
||||
|
||||
void evmap_io_initmap(struct event_io_map *ctx)
|
||||
void evmap_io_initmap_(struct event_io_map *ctx)
|
||||
{
|
||||
HT_INIT(event_io_map, ctx);
|
||||
}
|
||||
|
||||
void evmap_io_clear(struct event_io_map *ctx)
|
||||
void evmap_io_clear_(struct event_io_map *ctx)
|
||||
{
|
||||
struct event_map_entry **ent, **next, *this;
|
||||
for (ent = HT_START(event_io_map, ctx); ent; ent = next) {
|
||||
|
@ -183,14 +185,14 @@ void evmap_io_clear(struct event_io_map *ctx)
|
|||
GET_SIGNAL_SLOT_AND_CTOR(x,map,slot,type,ctor,fdinfo_len)
|
||||
#define FDINFO_OFFSET sizeof(struct evmap_io)
|
||||
void
|
||||
evmap_io_initmap(struct event_io_map* ctx)
|
||||
evmap_io_initmap_(struct event_io_map* ctx)
|
||||
{
|
||||
evmap_signal_initmap(ctx);
|
||||
evmap_signal_initmap_(ctx);
|
||||
}
|
||||
void
|
||||
evmap_io_clear(struct event_io_map* ctx)
|
||||
evmap_io_clear_(struct event_io_map* ctx)
|
||||
{
|
||||
evmap_signal_clear(ctx);
|
||||
evmap_signal_clear_(ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -223,14 +225,14 @@ evmap_make_space(struct event_signal_map *map, int slot, int msize)
|
|||
}
|
||||
|
||||
void
|
||||
evmap_signal_initmap(struct event_signal_map *ctx)
|
||||
evmap_signal_initmap_(struct event_signal_map *ctx)
|
||||
{
|
||||
ctx->nentries = 0;
|
||||
ctx->entries = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
evmap_signal_clear(struct event_signal_map *ctx)
|
||||
evmap_signal_clear_(struct event_signal_map *ctx)
|
||||
{
|
||||
if (ctx->entries != NULL) {
|
||||
int i;
|
||||
|
@ -251,21 +253,22 @@ evmap_signal_clear(struct event_signal_map *ctx)
|
|||
static void
|
||||
evmap_io_init(struct evmap_io *entry)
|
||||
{
|
||||
TAILQ_INIT(&entry->events);
|
||||
LIST_INIT(&entry->events);
|
||||
entry->nread = 0;
|
||||
entry->nwrite = 0;
|
||||
entry->nclose = 0;
|
||||
}
|
||||
|
||||
|
||||
/* return -1 on error, 0 on success if nothing changed in the event backend,
|
||||
* and 1 on success if something did. */
|
||||
int
|
||||
evmap_io_add(struct event_base *base, evutil_socket_t fd, struct event *ev)
|
||||
evmap_io_add_(struct event_base *base, evutil_socket_t fd, struct event *ev)
|
||||
{
|
||||
const struct eventop *evsel = base->evsel;
|
||||
struct event_io_map *io = &base->io;
|
||||
struct evmap_io *ctx = NULL;
|
||||
int nread, nwrite, retval = 0;
|
||||
int nread, nwrite, nclose, retval = 0;
|
||||
short res = 0, old = 0;
|
||||
struct event *old_ev;
|
||||
|
||||
|
@ -285,11 +288,14 @@ evmap_io_add(struct event_base *base, evutil_socket_t fd, struct event *ev)
|
|||
|
||||
nread = ctx->nread;
|
||||
nwrite = ctx->nwrite;
|
||||
nclose = ctx->nclose;
|
||||
|
||||
if (nread)
|
||||
old |= EV_READ;
|
||||
if (nwrite)
|
||||
old |= EV_WRITE;
|
||||
if (nclose)
|
||||
old |= EV_CLOSED;
|
||||
|
||||
if (ev->ev_events & EV_READ) {
|
||||
if (++nread == 1)
|
||||
|
@ -299,13 +305,17 @@ evmap_io_add(struct event_base *base, evutil_socket_t fd, struct event *ev)
|
|||
if (++nwrite == 1)
|
||||
res |= EV_WRITE;
|
||||
}
|
||||
if (EVUTIL_UNLIKELY(nread > 0xffff || nwrite > 0xffff)) {
|
||||
if (ev->ev_events & EV_CLOSED) {
|
||||
if (++nclose == 1)
|
||||
res |= EV_CLOSED;
|
||||
}
|
||||
if (EVUTIL_UNLIKELY(nread > 0xffff || nwrite > 0xffff || nclose > 0xffff)) {
|
||||
event_warnx("Too many events reading or writing on fd %d",
|
||||
(int)fd);
|
||||
return -1;
|
||||
}
|
||||
if (EVENT_DEBUG_MODE_IS_ON() &&
|
||||
(old_ev = TAILQ_FIRST(&ctx->events)) &&
|
||||
(old_ev = LIST_FIRST(&ctx->events)) &&
|
||||
(old_ev->ev_events&EV_ET) != (ev->ev_events&EV_ET)) {
|
||||
event_warnx("Tried to mix edge-triggered and non-edge-triggered"
|
||||
" events on fd %d", (int)fd);
|
||||
|
@ -325,7 +335,8 @@ evmap_io_add(struct event_base *base, evutil_socket_t fd, struct event *ev)
|
|||
|
||||
ctx->nread = (ev_uint16_t) nread;
|
||||
ctx->nwrite = (ev_uint16_t) nwrite;
|
||||
TAILQ_INSERT_TAIL(&ctx->events, ev, ev_io_next);
|
||||
ctx->nclose = (ev_uint16_t) nclose;
|
||||
LIST_INSERT_HEAD(&ctx->events, ev, ev_io_next);
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
@ -333,12 +344,12 @@ evmap_io_add(struct event_base *base, evutil_socket_t fd, struct event *ev)
|
|||
/* return -1 on error, 0 on success if nothing changed in the event backend,
|
||||
* and 1 on success if something did. */
|
||||
int
|
||||
evmap_io_del(struct event_base *base, evutil_socket_t fd, struct event *ev)
|
||||
evmap_io_del_(struct event_base *base, evutil_socket_t fd, struct event *ev)
|
||||
{
|
||||
const struct eventop *evsel = base->evsel;
|
||||
struct event_io_map *io = &base->io;
|
||||
struct evmap_io *ctx;
|
||||
int nread, nwrite, retval = 0;
|
||||
int nread, nwrite, nclose, retval = 0;
|
||||
short res = 0, old = 0;
|
||||
|
||||
if (fd < 0)
|
||||
|
@ -355,11 +366,14 @@ evmap_io_del(struct event_base *base, evutil_socket_t fd, struct event *ev)
|
|||
|
||||
nread = ctx->nread;
|
||||
nwrite = ctx->nwrite;
|
||||
nclose = ctx->nclose;
|
||||
|
||||
if (nread)
|
||||
old |= EV_READ;
|
||||
if (nwrite)
|
||||
old |= EV_WRITE;
|
||||
if (nclose)
|
||||
old |= EV_CLOSED;
|
||||
|
||||
if (ev->ev_events & EV_READ) {
|
||||
if (--nread == 0)
|
||||
|
@ -371,37 +385,47 @@ evmap_io_del(struct event_base *base, evutil_socket_t fd, struct event *ev)
|
|||
res |= EV_WRITE;
|
||||
EVUTIL_ASSERT(nwrite >= 0);
|
||||
}
|
||||
if (ev->ev_events & EV_CLOSED) {
|
||||
if (--nclose == 0)
|
||||
res |= EV_CLOSED;
|
||||
EVUTIL_ASSERT(nclose >= 0);
|
||||
}
|
||||
|
||||
if (res) {
|
||||
void *extra = ((char*)ctx) + sizeof(struct evmap_io);
|
||||
if (evsel->del(base, ev->ev_fd, old, res, extra) == -1)
|
||||
return (-1);
|
||||
retval = 1;
|
||||
if (evsel->del(base, ev->ev_fd, old, res, extra) == -1) {
|
||||
retval = -1;
|
||||
} else {
|
||||
retval = 1;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->nread = nread;
|
||||
ctx->nwrite = nwrite;
|
||||
TAILQ_REMOVE(&ctx->events, ev, ev_io_next);
|
||||
ctx->nclose = nclose;
|
||||
LIST_REMOVE(ev, ev_io_next);
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
void
|
||||
evmap_io_active(struct event_base *base, evutil_socket_t fd, short events)
|
||||
evmap_io_active_(struct event_base *base, evutil_socket_t fd, short events)
|
||||
{
|
||||
struct event_io_map *io = &base->io;
|
||||
struct evmap_io *ctx;
|
||||
struct event *ev;
|
||||
|
||||
#ifndef EVMAP_USE_HT
|
||||
EVUTIL_ASSERT(fd < io->nentries);
|
||||
if (fd < 0 || fd >= io->nentries)
|
||||
return;
|
||||
#endif
|
||||
GET_IO_SLOT(ctx, io, fd, evmap_io);
|
||||
|
||||
EVUTIL_ASSERT(ctx);
|
||||
TAILQ_FOREACH(ev, &ctx->events, ev_io_next) {
|
||||
if (NULL == ctx)
|
||||
return;
|
||||
LIST_FOREACH(ev, &ctx->events, ev_io_next) {
|
||||
if (ev->ev_events & events)
|
||||
event_active_nolock(ev, ev->ev_events & events, 1);
|
||||
event_active_nolock_(ev, ev->ev_events & events, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -410,12 +434,12 @@ evmap_io_active(struct event_base *base, evutil_socket_t fd, short events)
|
|||
static void
|
||||
evmap_signal_init(struct evmap_signal *entry)
|
||||
{
|
||||
TAILQ_INIT(&entry->events);
|
||||
LIST_INIT(&entry->events);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
evmap_signal_add(struct event_base *base, int sig, struct event *ev)
|
||||
evmap_signal_add_(struct event_base *base, int sig, struct event *ev)
|
||||
{
|
||||
const struct eventop *evsel = base->evsigsel;
|
||||
struct event_signal_map *map = &base->sigmap;
|
||||
|
@ -429,19 +453,19 @@ evmap_signal_add(struct event_base *base, int sig, struct event *ev)
|
|||
GET_SIGNAL_SLOT_AND_CTOR(ctx, map, sig, evmap_signal, evmap_signal_init,
|
||||
base->evsigsel->fdinfo_len);
|
||||
|
||||
if (TAILQ_EMPTY(&ctx->events)) {
|
||||
if (LIST_EMPTY(&ctx->events)) {
|
||||
if (evsel->add(base, ev->ev_fd, 0, EV_SIGNAL, NULL)
|
||||
== -1)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
TAILQ_INSERT_TAIL(&ctx->events, ev, ev_signal_next);
|
||||
LIST_INSERT_HEAD(&ctx->events, ev, ev_signal_next);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
evmap_signal_del(struct event_base *base, int sig, struct event *ev)
|
||||
evmap_signal_del_(struct event_base *base, int sig, struct event *ev)
|
||||
{
|
||||
const struct eventop *evsel = base->evsigsel;
|
||||
struct event_signal_map *map = &base->sigmap;
|
||||
|
@ -452,32 +476,35 @@ evmap_signal_del(struct event_base *base, int sig, struct event *ev)
|
|||
|
||||
GET_SIGNAL_SLOT(ctx, map, sig, evmap_signal);
|
||||
|
||||
if (TAILQ_FIRST(&ctx->events) == TAILQ_LAST(&ctx->events, event_list)) {
|
||||
LIST_REMOVE(ev, ev_signal_next);
|
||||
|
||||
if (LIST_FIRST(&ctx->events) == NULL) {
|
||||
if (evsel->del(base, ev->ev_fd, 0, EV_SIGNAL, NULL) == -1)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
TAILQ_REMOVE(&ctx->events, ev, ev_signal_next);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
evmap_signal_active(struct event_base *base, evutil_socket_t sig, int ncalls)
|
||||
evmap_signal_active_(struct event_base *base, evutil_socket_t sig, int ncalls)
|
||||
{
|
||||
struct event_signal_map *map = &base->sigmap;
|
||||
struct evmap_signal *ctx;
|
||||
struct event *ev;
|
||||
|
||||
EVUTIL_ASSERT(sig < map->nentries);
|
||||
if (sig < 0 || sig >= map->nentries)
|
||||
return;
|
||||
GET_SIGNAL_SLOT(ctx, map, sig, evmap_signal);
|
||||
|
||||
TAILQ_FOREACH(ev, &ctx->events, ev_signal_next)
|
||||
event_active_nolock(ev, EV_SIGNAL, ncalls);
|
||||
if (!ctx)
|
||||
return;
|
||||
LIST_FOREACH(ev, &ctx->events, ev_signal_next)
|
||||
event_active_nolock_(ev, EV_SIGNAL, ncalls);
|
||||
}
|
||||
|
||||
void *
|
||||
evmap_io_get_fdinfo(struct event_io_map *map, evutil_socket_t fd)
|
||||
evmap_io_get_fdinfo_(struct event_io_map *map, evutil_socket_t fd)
|
||||
{
|
||||
struct evmap_io *ctx;
|
||||
GET_IO_SLOT(ctx, map, fd, evmap_io);
|
||||
|
@ -487,6 +514,177 @@ evmap_io_get_fdinfo(struct event_io_map *map, evutil_socket_t fd)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Callback type for evmap_io_foreach_fd */
|
||||
typedef int (*evmap_io_foreach_fd_cb)(
|
||||
struct event_base *, evutil_socket_t, struct evmap_io *, void *);
|
||||
|
||||
/* Multipurpose helper function: Iterate over every file descriptor event_base
|
||||
* for which we could have EV_READ or EV_WRITE events. For each such fd, call
|
||||
* fn(base, signum, evmap_io, arg), where fn is the user-provided
|
||||
* function, base is the event_base, signum is the signal number, evmap_io
|
||||
* is an evmap_io structure containing a list of events pending on the
|
||||
* file descriptor, and arg is the user-supplied argument.
|
||||
*
|
||||
* If fn returns 0, continue on to the next signal. Otherwise, return the same
|
||||
* value that fn returned.
|
||||
*
|
||||
* Note that there is no guarantee that the file descriptors will be processed
|
||||
* in any particular order.
|
||||
*/
|
||||
static int
|
||||
evmap_io_foreach_fd(struct event_base *base,
|
||||
evmap_io_foreach_fd_cb fn,
|
||||
void *arg)
|
||||
{
|
||||
evutil_socket_t fd;
|
||||
struct event_io_map *iomap = &base->io;
|
||||
int r = 0;
|
||||
#ifdef EVMAP_USE_HT
|
||||
struct event_map_entry **mapent;
|
||||
HT_FOREACH(mapent, event_io_map, iomap) {
|
||||
struct evmap_io *ctx = &(*mapent)->ent.evmap_io;
|
||||
fd = (*mapent)->fd;
|
||||
#else
|
||||
for (fd = 0; fd < iomap->nentries; ++fd) {
|
||||
struct evmap_io *ctx = iomap->entries[fd];
|
||||
if (!ctx)
|
||||
continue;
|
||||
#endif
|
||||
if ((r = fn(base, fd, ctx, arg)))
|
||||
break;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Callback type for evmap_signal_foreach_signal */
|
||||
typedef int (*evmap_signal_foreach_signal_cb)(
|
||||
struct event_base *, int, struct evmap_signal *, void *);
|
||||
|
||||
/* Multipurpose helper function: Iterate over every signal number in the
|
||||
* event_base for which we could have signal events. For each such signal,
|
||||
* call fn(base, signum, evmap_signal, arg), where fn is the user-provided
|
||||
* function, base is the event_base, signum is the signal number, evmap_signal
|
||||
* is an evmap_signal structure containing a list of events pending on the
|
||||
* signal, and arg is the user-supplied argument.
|
||||
*
|
||||
* If fn returns 0, continue on to the next signal. Otherwise, return the same
|
||||
* value that fn returned.
|
||||
*/
|
||||
static int
|
||||
evmap_signal_foreach_signal(struct event_base *base,
|
||||
evmap_signal_foreach_signal_cb fn,
|
||||
void *arg)
|
||||
{
|
||||
struct event_signal_map *sigmap = &base->sigmap;
|
||||
int r = 0;
|
||||
int signum;
|
||||
|
||||
for (signum = 0; signum < sigmap->nentries; ++signum) {
|
||||
struct evmap_signal *ctx = sigmap->entries[signum];
|
||||
if (!ctx)
|
||||
continue;
|
||||
if ((r = fn(base, signum, ctx, arg)))
|
||||
break;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Helper for evmap_reinit_: tell the backend to add every fd for which we have
|
||||
* pending events, with the appropriate combination of EV_READ, EV_WRITE, and
|
||||
* EV_ET. */
|
||||
static int
|
||||
evmap_io_reinit_iter_fn(struct event_base *base, evutil_socket_t fd,
|
||||
struct evmap_io *ctx, void *arg)
|
||||
{
|
||||
const struct eventop *evsel = base->evsel;
|
||||
void *extra;
|
||||
int *result = arg;
|
||||
short events = 0;
|
||||
struct event *ev;
|
||||
EVUTIL_ASSERT(ctx);
|
||||
|
||||
extra = ((char*)ctx) + sizeof(struct evmap_io);
|
||||
if (ctx->nread)
|
||||
events |= EV_READ;
|
||||
if (ctx->nwrite)
|
||||
events |= EV_WRITE;
|
||||
if (ctx->nclose)
|
||||
events |= EV_CLOSED;
|
||||
if (evsel->fdinfo_len)
|
||||
memset(extra, 0, evsel->fdinfo_len);
|
||||
if (events &&
|
||||
(ev = LIST_FIRST(&ctx->events)) &&
|
||||
(ev->ev_events & EV_ET))
|
||||
events |= EV_ET;
|
||||
if (evsel->add(base, fd, 0, events, extra) == -1)
|
||||
*result = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Helper for evmap_reinit_: tell the backend to add every signal for which we
|
||||
* have pending events. */
|
||||
static int
|
||||
evmap_signal_reinit_iter_fn(struct event_base *base,
|
||||
int signum, struct evmap_signal *ctx, void *arg)
|
||||
{
|
||||
const struct eventop *evsel = base->evsigsel;
|
||||
int *result = arg;
|
||||
|
||||
if (!LIST_EMPTY(&ctx->events)) {
|
||||
if (evsel->add(base, signum, 0, EV_SIGNAL, NULL) == -1)
|
||||
*result = -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
evmap_reinit_(struct event_base *base)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
evmap_io_foreach_fd(base, evmap_io_reinit_iter_fn, &result);
|
||||
if (result < 0)
|
||||
return -1;
|
||||
evmap_signal_foreach_signal(base, evmap_signal_reinit_iter_fn, &result);
|
||||
if (result < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Helper for evmap_delete_all_: delete every event in an event_dlist. */
|
||||
static int
|
||||
delete_all_in_dlist(struct event_dlist *dlist)
|
||||
{
|
||||
struct event *ev;
|
||||
while ((ev = LIST_FIRST(dlist)))
|
||||
event_del(ev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Helper for evmap_delete_all_: delete every event pending on an fd. */
|
||||
static int
|
||||
evmap_io_delete_all_iter_fn(struct event_base *base, evutil_socket_t fd,
|
||||
struct evmap_io *io_info, void *arg)
|
||||
{
|
||||
return delete_all_in_dlist(&io_info->events);
|
||||
}
|
||||
|
||||
/* Helper for evmap_delete_all_: delete every event pending on a signal. */
|
||||
static int
|
||||
evmap_signal_delete_all_iter_fn(struct event_base *base, int signum,
|
||||
struct evmap_signal *sig_info, void *arg)
|
||||
{
|
||||
return delete_all_in_dlist(&sig_info->events);
|
||||
}
|
||||
|
||||
void
|
||||
evmap_delete_all_(struct event_base *base)
|
||||
{
|
||||
evmap_signal_foreach_signal(base, evmap_signal_delete_all_iter_fn, NULL);
|
||||
evmap_io_foreach_fd(base, evmap_io_delete_all_iter_fn, NULL);
|
||||
}
|
||||
|
||||
/** Per-fd structure for use with changelists. It keeps track, for each fd or
|
||||
* signal using the changelist, of where its entry in the changelist is.
|
||||
*/
|
||||
|
@ -496,7 +694,7 @@ struct event_changelist_fdinfo {
|
|||
};
|
||||
|
||||
void
|
||||
event_changelist_init(struct event_changelist *changelist)
|
||||
event_changelist_init_(struct event_changelist *changelist)
|
||||
{
|
||||
changelist->changes = NULL;
|
||||
changelist->changes_size = 0;
|
||||
|
@ -521,10 +719,26 @@ event_change_get_fdinfo(struct event_base *base,
|
|||
return (void*)ptr;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CHANGELIST
|
||||
/** Callback helper for event_changelist_assert_ok */
|
||||
static int
|
||||
event_changelist_assert_ok_foreach_iter_fn(
|
||||
struct event_base *base,
|
||||
evutil_socket_t fd, struct evmap_io *io, void *arg)
|
||||
{
|
||||
struct event_changelist *changelist = &base->changelist;
|
||||
struct event_changelist_fdinfo *f;
|
||||
f = (void*)
|
||||
( ((char*)io) + sizeof(struct evmap_io) );
|
||||
if (f->idxplus1) {
|
||||
struct event_change *c = &changelist->changes[f->idxplus1 - 1];
|
||||
EVUTIL_ASSERT(c->fd == fd);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Make sure that the changelist is consistent with the evmap structures. */
|
||||
static void
|
||||
event_changelist_check(struct event_base *base)
|
||||
event_changelist_assert_ok(struct event_base *base)
|
||||
{
|
||||
int i;
|
||||
struct event_changelist *changelist = &base->changelist;
|
||||
|
@ -539,25 +753,19 @@ event_changelist_check(struct event_base *base)
|
|||
EVUTIL_ASSERT(f->idxplus1 == i + 1);
|
||||
}
|
||||
|
||||
for (i = 0; i < base->io.nentries; ++i) {
|
||||
struct evmap_io *io = base->io.entries[i];
|
||||
struct event_changelist_fdinfo *f;
|
||||
if (!io)
|
||||
continue;
|
||||
f = (void*)
|
||||
( ((char*)io) + sizeof(struct evmap_io) );
|
||||
if (f->idxplus1) {
|
||||
struct event_change *c = &changelist->changes[f->idxplus1 - 1];
|
||||
EVUTIL_ASSERT(c->fd == i);
|
||||
}
|
||||
}
|
||||
evmap_io_foreach_fd(base,
|
||||
event_changelist_assert_ok_foreach_iter_fn,
|
||||
NULL);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CHANGELIST
|
||||
#define event_changelist_check(base) event_changelist_assert_ok((base))
|
||||
#else
|
||||
#define event_changelist_check(base) ((void)0)
|
||||
#endif
|
||||
|
||||
void
|
||||
event_changelist_remove_all(struct event_changelist *changelist,
|
||||
event_changelist_remove_all_(struct event_changelist *changelist,
|
||||
struct event_base *base)
|
||||
{
|
||||
int i;
|
||||
|
@ -578,11 +786,11 @@ event_changelist_remove_all(struct event_changelist *changelist,
|
|||
}
|
||||
|
||||
void
|
||||
event_changelist_freemem(struct event_changelist *changelist)
|
||||
event_changelist_freemem_(struct event_changelist *changelist)
|
||||
{
|
||||
if (changelist->changes)
|
||||
mm_free(changelist->changes);
|
||||
event_changelist_init(changelist); /* zero it all out. */
|
||||
event_changelist_init_(changelist); /* zero it all out. */
|
||||
}
|
||||
|
||||
/** Increase the size of 'changelist' to hold more changes. */
|
||||
|
@ -644,7 +852,7 @@ event_changelist_get_or_construct(struct event_changelist *changelist,
|
|||
}
|
||||
|
||||
int
|
||||
event_changelist_add(struct event_base *base, evutil_socket_t fd, short old, short events,
|
||||
event_changelist_add_(struct event_base *base, evutil_socket_t fd, short old, short events,
|
||||
void *p)
|
||||
{
|
||||
struct event_changelist *changelist = &base->changelist;
|
||||
|
@ -669,13 +877,17 @@ event_changelist_add(struct event_base *base, evutil_socket_t fd, short old, sho
|
|||
change->write_change = EV_CHANGE_ADD |
|
||||
(events & (EV_ET|EV_PERSIST|EV_SIGNAL));
|
||||
}
|
||||
if (events & EV_CLOSED) {
|
||||
change->close_change = EV_CHANGE_ADD |
|
||||
(events & (EV_ET|EV_PERSIST|EV_SIGNAL));
|
||||
}
|
||||
|
||||
event_changelist_check(base);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
event_changelist_del(struct event_base *base, evutil_socket_t fd, short old, short events,
|
||||
event_changelist_del_(struct event_base *base, evutil_socket_t fd, short old, short events,
|
||||
void *p)
|
||||
{
|
||||
struct event_changelist *changelist = &base->changelist;
|
||||
|
@ -688,14 +900,11 @@ event_changelist_del(struct event_base *base, evutil_socket_t fd, short old, sho
|
|||
if (!change)
|
||||
return -1;
|
||||
|
||||
/* A delete removes any previous add, rather than replacing it:
|
||||
on those platforms where "add, delete, dispatch" is not the same
|
||||
as "no-op, dispatch", we want the no-op behavior.
|
||||
|
||||
As well as checking the current operation we should also check
|
||||
the original set of events to make sure were not ignoring
|
||||
the case where the add operation is present on an event that
|
||||
was already set.
|
||||
/* A delete on an event set that doesn't contain the event to be
|
||||
deleted produces a no-op. This effectively emoves any previous
|
||||
uncommitted add, rather than replacing it: on those platforms where
|
||||
"add, delete, dispatch" is not the same as "no-op, dispatch", we
|
||||
want the no-op behavior.
|
||||
|
||||
If we have a no-op item, we could remove it it from the list
|
||||
entirely, but really there's not much point: skipping the no-op
|
||||
|
@ -707,93 +916,140 @@ event_changelist_del(struct event_base *base, evutil_socket_t fd, short old, sho
|
|||
*/
|
||||
|
||||
if (events & (EV_READ|EV_SIGNAL)) {
|
||||
if (!(change->old_events & (EV_READ | EV_SIGNAL)) &&
|
||||
(change->read_change & EV_CHANGE_ADD))
|
||||
if (!(change->old_events & (EV_READ | EV_SIGNAL)))
|
||||
change->read_change = 0;
|
||||
else
|
||||
change->read_change = EV_CHANGE_DEL;
|
||||
}
|
||||
if (events & EV_WRITE) {
|
||||
if (!(change->old_events & EV_WRITE) &&
|
||||
(change->write_change & EV_CHANGE_ADD))
|
||||
if (!(change->old_events & EV_WRITE))
|
||||
change->write_change = 0;
|
||||
else
|
||||
change->write_change = EV_CHANGE_DEL;
|
||||
}
|
||||
if (events & EV_CLOSED) {
|
||||
if (!(change->old_events & EV_CLOSED))
|
||||
change->close_change = 0;
|
||||
else
|
||||
change->close_change = EV_CHANGE_DEL;
|
||||
}
|
||||
|
||||
event_changelist_check(base);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
evmap_check_integrity(struct event_base *base)
|
||||
/* Helper for evmap_check_integrity_: verify that all of the events pending on
|
||||
* given fd are set up correctly, and that the nread and nwrite counts on that
|
||||
* fd are correct. */
|
||||
static int
|
||||
evmap_io_check_integrity_fn(struct event_base *base, evutil_socket_t fd,
|
||||
struct evmap_io *io_info, void *arg)
|
||||
{
|
||||
#define EVLIST_X_SIGFOUND 0x1000
|
||||
#define EVLIST_X_IOFOUND 0x2000
|
||||
|
||||
evutil_socket_t i;
|
||||
struct event *ev;
|
||||
struct event_io_map *io = &base->io;
|
||||
struct event_signal_map *sigmap = &base->sigmap;
|
||||
#ifdef EVMAP_USE_HT
|
||||
struct event_map_entry **mapent;
|
||||
#endif
|
||||
int nsignals, ntimers, nio;
|
||||
nsignals = ntimers = nio = 0;
|
||||
int n_read = 0, n_write = 0, n_close = 0;
|
||||
|
||||
TAILQ_FOREACH(ev, &base->eventqueue, ev_next) {
|
||||
/* First, make sure the list itself isn't corrupt. Otherwise,
|
||||
* running LIST_FOREACH could be an exciting adventure. */
|
||||
EVUTIL_ASSERT_LIST_OK(&io_info->events, event, ev_io_next);
|
||||
|
||||
LIST_FOREACH(ev, &io_info->events, ev_io_next) {
|
||||
EVUTIL_ASSERT(ev->ev_flags & EVLIST_INSERTED);
|
||||
EVUTIL_ASSERT(ev->ev_flags & EVLIST_INIT);
|
||||
ev->ev_flags &= ~(EVLIST_X_SIGFOUND|EVLIST_X_IOFOUND);
|
||||
EVUTIL_ASSERT(ev->ev_fd == fd);
|
||||
EVUTIL_ASSERT(!(ev->ev_events & EV_SIGNAL));
|
||||
EVUTIL_ASSERT((ev->ev_events & (EV_READ|EV_WRITE|EV_CLOSED)));
|
||||
if (ev->ev_events & EV_READ)
|
||||
++n_read;
|
||||
if (ev->ev_events & EV_WRITE)
|
||||
++n_write;
|
||||
if (ev->ev_events & EV_CLOSED)
|
||||
++n_close;
|
||||
}
|
||||
|
||||
#ifdef EVMAP_USE_HT
|
||||
HT_FOREACH(mapent, event_io_map, io) {
|
||||
struct evmap_io *ctx = &(*mapent)->ent.evmap_io;
|
||||
i = (*mapent)->fd;
|
||||
#else
|
||||
for (i = 0; i < io->nentries; ++i) {
|
||||
struct evmap_io *ctx = io->entries[i];
|
||||
EVUTIL_ASSERT(n_read == io_info->nread);
|
||||
EVUTIL_ASSERT(n_write == io_info->nwrite);
|
||||
EVUTIL_ASSERT(n_close == io_info->nclose);
|
||||
|
||||
if (!ctx)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
TAILQ_FOREACH(ev, &ctx->events, ev_io_next) {
|
||||
EVUTIL_ASSERT(!(ev->ev_flags & EVLIST_X_IOFOUND));
|
||||
EVUTIL_ASSERT(ev->ev_fd == i);
|
||||
ev->ev_flags |= EVLIST_X_IOFOUND;
|
||||
nio++;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < sigmap->nentries; ++i) {
|
||||
struct evmap_signal *ctx = sigmap->entries[i];
|
||||
if (!ctx)
|
||||
continue;
|
||||
|
||||
TAILQ_FOREACH(ev, &ctx->events, ev_signal_next) {
|
||||
EVUTIL_ASSERT(!(ev->ev_flags & EVLIST_X_SIGFOUND));
|
||||
EVUTIL_ASSERT(ev->ev_fd == i);
|
||||
ev->ev_flags |= EVLIST_X_SIGFOUND;
|
||||
nsignals++;
|
||||
}
|
||||
}
|
||||
|
||||
TAILQ_FOREACH(ev, &base->eventqueue, ev_next) {
|
||||
if (ev->ev_events & (EV_READ|EV_WRITE)) {
|
||||
EVUTIL_ASSERT(ev->ev_flags & EVLIST_X_IOFOUND);
|
||||
--nio;
|
||||
}
|
||||
if (ev->ev_events & EV_SIGNAL) {
|
||||
EVUTIL_ASSERT(ev->ev_flags & EVLIST_X_SIGFOUND);
|
||||
--nsignals;
|
||||
}
|
||||
}
|
||||
|
||||
EVUTIL_ASSERT(nio == 0);
|
||||
EVUTIL_ASSERT(nsignals == 0);
|
||||
/* There is no "EVUTIL_ASSERT(ntimers == 0)": eventqueue is only for
|
||||
* pending signals and io events.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Helper for evmap_check_integrity_: verify that all of the events pending
|
||||
* on given signal are set up correctly. */
|
||||
static int
|
||||
evmap_signal_check_integrity_fn(struct event_base *base,
|
||||
int signum, struct evmap_signal *sig_info, void *arg)
|
||||
{
|
||||
struct event *ev;
|
||||
/* First, make sure the list itself isn't corrupt. */
|
||||
EVUTIL_ASSERT_LIST_OK(&sig_info->events, event, ev_signal_next);
|
||||
|
||||
LIST_FOREACH(ev, &sig_info->events, ev_io_next) {
|
||||
EVUTIL_ASSERT(ev->ev_flags & EVLIST_INSERTED);
|
||||
EVUTIL_ASSERT(ev->ev_fd == signum);
|
||||
EVUTIL_ASSERT((ev->ev_events & EV_SIGNAL));
|
||||
EVUTIL_ASSERT(!(ev->ev_events & (EV_READ|EV_WRITE|EV_CLOSED)));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
evmap_check_integrity_(struct event_base *base)
|
||||
{
|
||||
evmap_io_foreach_fd(base, evmap_io_check_integrity_fn, NULL);
|
||||
evmap_signal_foreach_signal(base, evmap_signal_check_integrity_fn, NULL);
|
||||
|
||||
if (base->evsel->add == event_changelist_add_)
|
||||
event_changelist_assert_ok(base);
|
||||
}
|
||||
|
||||
/* Helper type for evmap_foreach_event_: Bundles a function to call on every
|
||||
* event, and the user-provided void* to use as its third argument. */
|
||||
struct evmap_foreach_event_helper {
|
||||
event_base_foreach_event_cb fn;
|
||||
void *arg;
|
||||
};
|
||||
|
||||
/* Helper for evmap_foreach_event_: calls a provided function on every event
|
||||
* pending on a given fd. */
|
||||
static int
|
||||
evmap_io_foreach_event_fn(struct event_base *base, evutil_socket_t fd,
|
||||
struct evmap_io *io_info, void *arg)
|
||||
{
|
||||
struct evmap_foreach_event_helper *h = arg;
|
||||
struct event *ev;
|
||||
int r;
|
||||
LIST_FOREACH(ev, &io_info->events, ev_io_next) {
|
||||
if ((r = h->fn(base, ev, h->arg)))
|
||||
return r;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Helper for evmap_foreach_event_: calls a provided function on every event
|
||||
* pending on a given signal. */
|
||||
static int
|
||||
evmap_signal_foreach_event_fn(struct event_base *base, int signum,
|
||||
struct evmap_signal *sig_info, void *arg)
|
||||
{
|
||||
struct event *ev;
|
||||
struct evmap_foreach_event_helper *h = arg;
|
||||
int r;
|
||||
LIST_FOREACH(ev, &sig_info->events, ev_signal_next) {
|
||||
if ((r = h->fn(base, ev, h->arg)))
|
||||
return r;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
evmap_foreach_event_(struct event_base *base,
|
||||
event_base_foreach_event_cb fn, void *arg)
|
||||
{
|
||||
struct evmap_foreach_event_helper h;
|
||||
int r;
|
||||
h.fn = fn;
|
||||
h.arg = arg;
|
||||
if ((r = evmap_io_foreach_fd(base, evmap_io_foreach_event_fn, &h)))
|
||||
return r;
|
||||
return evmap_signal_foreach_signal(base, evmap_signal_foreach_event_fn, &h);
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,9 @@
|
|||
*/
|
||||
|
||||
#include "event2/event-config.h"
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#ifdef EVENT__HAVE_EVENT_PORTS
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/queue.h>
|
||||
|
@ -75,20 +78,8 @@
|
|||
#include "evsignal-internal.h"
|
||||
#include "evmap-internal.h"
|
||||
|
||||
/*
|
||||
* Default value for ed_nevents, which is the maximum file descriptor number we
|
||||
* can handle. If an event comes in for a file descriptor F > nevents, we will
|
||||
* grow the array of file descriptors, doubling its size.
|
||||
*/
|
||||
#define DEFAULT_NFDS 16
|
||||
|
||||
|
||||
/*
|
||||
* EVENTS_PER_GETN is the maximum number of events to retrieve from port_getn on
|
||||
* any particular call. You can speed things up by increasing this, but it will
|
||||
* (obviously) require more memory.
|
||||
*/
|
||||
#define EVENTS_PER_GETN 8
|
||||
#define INITIAL_EVENTS_PER_GETN 8
|
||||
#define MAX_EVENTS_PER_GETN 4096
|
||||
|
||||
/*
|
||||
* Per-file-descriptor information about what events we're subscribed to. These
|
||||
|
@ -96,7 +87,12 @@
|
|||
*/
|
||||
|
||||
struct fd_info {
|
||||
short fdi_what; /* combinations of EV_READ and EV_WRITE */
|
||||
/* combinations of EV_READ and EV_WRITE */
|
||||
short fdi_what;
|
||||
/* Index of this fd within ed_pending, plus 1. Zero if this fd is
|
||||
* not in ed_pending. (The +1 is a hack so that memset(0) will set
|
||||
* it to a nil index. */
|
||||
int pending_idx_plus_1;
|
||||
};
|
||||
|
||||
#define FDI_HAS_READ(fdi) ((fdi)->fdi_what & EV_READ)
|
||||
|
@ -107,10 +103,15 @@ struct fd_info {
|
|||
|
||||
struct evport_data {
|
||||
int ed_port; /* event port for system events */
|
||||
int ed_nevents; /* number of allocated fdi's */
|
||||
struct fd_info *ed_fds; /* allocated fdi table */
|
||||
/* How many elements of ed_pending should we look at? */
|
||||
int ed_npending;
|
||||
/* How many elements are allocated in ed_pending and pevtlist? */
|
||||
int ed_maxevents;
|
||||
/* fdi's that we need to reassoc */
|
||||
int ed_pending[EVENTS_PER_GETN]; /* fd's with pending events */
|
||||
int *ed_pending;
|
||||
/* storage space for incoming events. */
|
||||
port_event_t *ed_pevtlist;
|
||||
|
||||
};
|
||||
|
||||
static void* evport_init(struct event_base *);
|
||||
|
@ -118,6 +119,7 @@ static int evport_add(struct event_base *, int fd, short old, short events, void
|
|||
static int evport_del(struct event_base *, int fd, short old, short events, void *);
|
||||
static int evport_dispatch(struct event_base *, struct timeval *);
|
||||
static void evport_dealloc(struct event_base *);
|
||||
static int grow(struct evport_data *, int min_events);
|
||||
|
||||
const struct eventop evportops = {
|
||||
"evport",
|
||||
|
@ -128,7 +130,7 @@ const struct eventop evportops = {
|
|||
evport_dealloc,
|
||||
1, /* need reinit */
|
||||
0, /* features */
|
||||
0, /* fdinfo length */
|
||||
sizeof(struct fd_info), /* fdinfo length */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -139,7 +141,6 @@ static void*
|
|||
evport_init(struct event_base *base)
|
||||
{
|
||||
struct evport_data *evpd;
|
||||
int i;
|
||||
|
||||
if (!(evpd = mm_calloc(1, sizeof(struct evport_data))))
|
||||
return (NULL);
|
||||
|
@ -149,24 +150,47 @@ evport_init(struct event_base *base)
|
|||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize file descriptor structure
|
||||
*/
|
||||
evpd->ed_fds = mm_calloc(DEFAULT_NFDS, sizeof(struct fd_info));
|
||||
if (evpd->ed_fds == NULL) {
|
||||
if (grow(evpd, INITIAL_EVENTS_PER_GETN) < 0) {
|
||||
close(evpd->ed_port);
|
||||
mm_free(evpd);
|
||||
return (NULL);
|
||||
return NULL;
|
||||
}
|
||||
evpd->ed_nevents = DEFAULT_NFDS;
|
||||
for (i = 0; i < EVENTS_PER_GETN; i++)
|
||||
evpd->ed_pending[i] = -1;
|
||||
|
||||
evpd->ed_npending = 0;
|
||||
|
||||
evsig_init(base);
|
||||
evsig_init_(base);
|
||||
|
||||
return (evpd);
|
||||
}
|
||||
|
||||
static int
|
||||
grow(struct evport_data *data, int min_events)
|
||||
{
|
||||
int newsize;
|
||||
int *new_pending;
|
||||
port_event_t *new_pevtlist;
|
||||
if (data->ed_maxevents) {
|
||||
newsize = data->ed_maxevents;
|
||||
do {
|
||||
newsize *= 2;
|
||||
} while (newsize < min_events);
|
||||
} else {
|
||||
newsize = min_events;
|
||||
}
|
||||
|
||||
new_pending = mm_realloc(data->ed_pending, sizeof(int)*newsize);
|
||||
if (new_pending == NULL)
|
||||
return -1;
|
||||
data->ed_pending = new_pending;
|
||||
new_pevtlist = mm_realloc(data->ed_pevtlist, sizeof(port_event_t)*newsize);
|
||||
if (new_pevtlist == NULL)
|
||||
return -1;
|
||||
data->ed_pevtlist = new_pevtlist;
|
||||
|
||||
data->ed_maxevents = newsize;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CHECK_INVARIANTS
|
||||
/*
|
||||
* Checks some basic properties about the evport_data structure. Because it
|
||||
|
@ -178,9 +202,7 @@ static void
|
|||
check_evportop(struct evport_data *evpd)
|
||||
{
|
||||
EVUTIL_ASSERT(evpd);
|
||||
EVUTIL_ASSERT(evpd->ed_nevents > 0);
|
||||
EVUTIL_ASSERT(evpd->ed_port > 0);
|
||||
EVUTIL_ASSERT(evpd->ed_fds > 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -196,7 +218,6 @@ check_event(port_event_t* pevt)
|
|||
* PORT_SOURCE_FD.
|
||||
*/
|
||||
EVUTIL_ASSERT(pevt->portev_source == PORT_SOURCE_FD);
|
||||
EVUTIL_ASSERT(pevt->portev_user == NULL);
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -204,33 +225,6 @@ check_event(port_event_t* pevt)
|
|||
#define check_event(pevt)
|
||||
#endif /* CHECK_INVARIANTS */
|
||||
|
||||
/*
|
||||
* Doubles the size of the allocated file descriptor array.
|
||||
*/
|
||||
static int
|
||||
grow(struct evport_data *epdp, int factor)
|
||||
{
|
||||
struct fd_info *tmp;
|
||||
int oldsize = epdp->ed_nevents;
|
||||
int newsize = factor * oldsize;
|
||||
EVUTIL_ASSERT(factor > 1);
|
||||
|
||||
check_evportop(epdp);
|
||||
|
||||
tmp = mm_realloc(epdp->ed_fds, sizeof(struct fd_info) * newsize);
|
||||
if (NULL == tmp)
|
||||
return -1;
|
||||
epdp->ed_fds = tmp;
|
||||
memset((char*) (epdp->ed_fds + oldsize), 0,
|
||||
(newsize - oldsize)*sizeof(struct fd_info));
|
||||
epdp->ed_nevents = newsize;
|
||||
|
||||
check_evportop(epdp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (Re)associates the given file descriptor with the event port. The OS events
|
||||
* are specified (implicitly) from the fd_info struct.
|
||||
|
@ -242,7 +236,7 @@ reassociate(struct evport_data *epdp, struct fd_info *fdip, int fd)
|
|||
|
||||
if (sysevents != 0) {
|
||||
if (port_associate(epdp->ed_port, PORT_SOURCE_FD,
|
||||
fd, sysevents, NULL) == -1) {
|
||||
fd, sysevents, fdip) == -1) {
|
||||
event_warn("port_associate");
|
||||
return (-1);
|
||||
}
|
||||
|
@ -263,12 +257,12 @@ evport_dispatch(struct event_base *base, struct timeval *tv)
|
|||
{
|
||||
int i, res;
|
||||
struct evport_data *epdp = base->evbase;
|
||||
port_event_t pevtlist[EVENTS_PER_GETN];
|
||||
port_event_t *pevtlist = epdp->ed_pevtlist;
|
||||
|
||||
/*
|
||||
* port_getn will block until it has at least nevents events. It will
|
||||
* also return how many it's given us (which may be more than we asked
|
||||
* for, as long as it's less than our maximum (EVENTS_PER_GETN)) in
|
||||
* for, as long as it's less than our maximum (ed_maxevents)) in
|
||||
* nevents.
|
||||
*/
|
||||
int nevents = 1;
|
||||
|
@ -291,22 +285,25 @@ evport_dispatch(struct event_base *base, struct timeval *tv)
|
|||
* last time which need reassociation. See comment at the end of the
|
||||
* loop below.
|
||||
*/
|
||||
for (i = 0; i < EVENTS_PER_GETN; ++i) {
|
||||
for (i = 0; i < epdp->ed_npending; ++i) {
|
||||
struct fd_info *fdi = NULL;
|
||||
if (epdp->ed_pending[i] != -1) {
|
||||
fdi = &(epdp->ed_fds[epdp->ed_pending[i]]);
|
||||
const int fd = epdp->ed_pending[i];
|
||||
if (fd != -1) {
|
||||
/* We might have cleared out this event; we need
|
||||
* to be sure that it's still set. */
|
||||
fdi = evmap_io_get_fdinfo_(&base->io, fd);
|
||||
}
|
||||
|
||||
if (fdi != NULL && FDI_HAS_EVENTS(fdi)) {
|
||||
int fd = epdp->ed_pending[i];
|
||||
reassociate(epdp, fdi, fd);
|
||||
epdp->ed_pending[i] = -1;
|
||||
/* epdp->ed_pending[i] = -1; */
|
||||
fdi->pending_idx_plus_1 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
EVBASE_RELEASE_LOCK(base, th_base_lock);
|
||||
|
||||
res = port_getn(epdp->ed_port, pevtlist, EVENTS_PER_GETN,
|
||||
res = port_getn(epdp->ed_port, pevtlist, epdp->ed_maxevents,
|
||||
(unsigned int *) &nevents, ts_p);
|
||||
|
||||
EVBASE_ACQUIRE_LOCK(base, th_base_lock);
|
||||
|
@ -326,13 +323,15 @@ evport_dispatch(struct event_base *base, struct timeval *tv)
|
|||
event_debug(("%s: port_getn reports %d events", __func__, nevents));
|
||||
|
||||
for (i = 0; i < nevents; ++i) {
|
||||
struct fd_info *fdi;
|
||||
port_event_t *pevt = &pevtlist[i];
|
||||
int fd = (int) pevt->portev_object;
|
||||
struct fd_info *fdi = pevt->portev_user;
|
||||
/*EVUTIL_ASSERT(evmap_io_get_fdinfo_(&base->io, fd) == fdi);*/
|
||||
|
||||
check_evportop(epdp);
|
||||
check_event(pevt);
|
||||
epdp->ed_pending[i] = fd;
|
||||
fdi->pending_idx_plus_1 = i + 1;
|
||||
|
||||
/*
|
||||
* Figure out what kind of event it was
|
||||
|
@ -354,11 +353,16 @@ evport_dispatch(struct event_base *base, struct timeval *tv)
|
|||
if (pevt->portev_events & (POLLERR|POLLHUP|POLLNVAL))
|
||||
res |= EV_READ|EV_WRITE;
|
||||
|
||||
EVUTIL_ASSERT(epdp->ed_nevents > fd);
|
||||
fdi = &(epdp->ed_fds[fd]);
|
||||
|
||||
evmap_io_active(base, fd, res);
|
||||
evmap_io_active_(base, fd, res);
|
||||
} /* end of all events gotten */
|
||||
epdp->ed_npending = nevents;
|
||||
|
||||
if (nevents == epdp->ed_maxevents &&
|
||||
epdp->ed_maxevents < MAX_EVENTS_PER_GETN) {
|
||||
/* we used all the space this time. We should be ready
|
||||
* for more events next time around. */
|
||||
grow(epdp, epdp->ed_maxevents * 2);
|
||||
}
|
||||
|
||||
check_evportop(epdp);
|
||||
|
||||
|
@ -375,27 +379,10 @@ static int
|
|||
evport_add(struct event_base *base, int fd, short old, short events, void *p)
|
||||
{
|
||||
struct evport_data *evpd = base->evbase;
|
||||
struct fd_info *fdi;
|
||||
int factor;
|
||||
(void)p;
|
||||
struct fd_info *fdi = p;
|
||||
|
||||
check_evportop(evpd);
|
||||
|
||||
/*
|
||||
* If necessary, grow the file descriptor info table
|
||||
*/
|
||||
|
||||
factor = 1;
|
||||
while (fd >= factor * evpd->ed_nevents)
|
||||
factor *= 2;
|
||||
|
||||
if (factor > 1) {
|
||||
if (-1 == grow(evpd, factor)) {
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
fdi = &evpd->ed_fds[fd];
|
||||
fdi->fdi_what |= events;
|
||||
|
||||
return reassociate(evpd, fdi, fd);
|
||||
|
@ -409,29 +396,12 @@ static int
|
|||
evport_del(struct event_base *base, int fd, short old, short events, void *p)
|
||||
{
|
||||
struct evport_data *evpd = base->evbase;
|
||||
struct fd_info *fdi;
|
||||
int i;
|
||||
int associated = 1;
|
||||
(void)p;
|
||||
struct fd_info *fdi = p;
|
||||
int associated = ! fdi->pending_idx_plus_1;
|
||||
|
||||
check_evportop(evpd);
|
||||
|
||||
if (evpd->ed_nevents < fd) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
for (i = 0; i < EVENTS_PER_GETN; ++i) {
|
||||
if (evpd->ed_pending[i] == fd) {
|
||||
associated = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fdi = &evpd->ed_fds[fd];
|
||||
if (events & EV_READ)
|
||||
fdi->fdi_what &= ~EV_READ;
|
||||
if (events & EV_WRITE)
|
||||
fdi->fdi_what &= ~EV_WRITE;
|
||||
fdi->fdi_what &= ~(events &(EV_READ|EV_WRITE));
|
||||
|
||||
if (associated) {
|
||||
if (!FDI_HAS_EVENTS(fdi) &&
|
||||
|
@ -451,7 +421,10 @@ evport_del(struct event_base *base, int fd, short old, short events, void *p)
|
|||
}
|
||||
} else {
|
||||
if ((fdi->fdi_what & (EV_READ|EV_WRITE)) == 0) {
|
||||
const int i = fdi->pending_idx_plus_1 - 1;
|
||||
EVUTIL_ASSERT(evpd->ed_pending[i] == fd);
|
||||
evpd->ed_pending[i] = -1;
|
||||
fdi->pending_idx_plus_1 = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -463,11 +436,16 @@ evport_dealloc(struct event_base *base)
|
|||
{
|
||||
struct evport_data *evpd = base->evbase;
|
||||
|
||||
evsig_dealloc(base);
|
||||
evsig_dealloc_(base);
|
||||
|
||||
close(evpd->ed_port);
|
||||
|
||||
if (evpd->ed_fds)
|
||||
mm_free(evpd->ed_fds);
|
||||
if (evpd->ed_pending)
|
||||
mm_free(evpd->ed_pending);
|
||||
if (evpd->ed_pevtlist)
|
||||
mm_free(evpd->ed_pevtlist);
|
||||
|
||||
mm_free(evpd);
|
||||
}
|
||||
|
||||
#endif /* EVENT__HAVE_EVENT_PORTS */
|
||||
|
|
|
@ -24,9 +24,10 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _EVRPC_INTERNAL_H_
|
||||
#define _EVRPC_INTERNAL_H_
|
||||
#ifndef EVRPC_INTERNAL_H_INCLUDED_
|
||||
#define EVRPC_INTERNAL_H_INCLUDED_
|
||||
|
||||
#include "event2/http.h"
|
||||
#include "http-internal.h"
|
||||
|
||||
struct evrpc;
|
||||
|
@ -56,7 +57,7 @@ TAILQ_HEAD(evrpc_hook_list, evrpc_hook);
|
|||
struct evrpc_hook_ctx;
|
||||
TAILQ_HEAD(evrpc_pause_list, evrpc_hook_ctx);
|
||||
|
||||
struct _evrpc_hooks {
|
||||
struct evrpc_hooks_ {
|
||||
/* hooks for processing outbound and inbound rpcs */
|
||||
struct evrpc_hook_list in_hooks;
|
||||
struct evrpc_hook_list out_hooks;
|
||||
|
@ -69,7 +70,7 @@ struct _evrpc_hooks {
|
|||
#define paused_requests common.pause_requests
|
||||
|
||||
struct evrpc_base {
|
||||
struct _evrpc_hooks common;
|
||||
struct evrpc_hooks_ common;
|
||||
|
||||
/* the HTTP server under which we register our RPC calls */
|
||||
struct evhttp* http_server;
|
||||
|
@ -79,11 +80,11 @@ struct evrpc_base {
|
|||
};
|
||||
|
||||
struct evrpc_req_generic;
|
||||
void evrpc_reqstate_free(struct evrpc_req_generic* rpc_state);
|
||||
void evrpc_reqstate_free_(struct evrpc_req_generic* rpc_state);
|
||||
|
||||
/* A pool for holding evhttp_connection objects */
|
||||
struct evrpc_pool {
|
||||
struct _evrpc_hooks common;
|
||||
struct evrpc_hooks_ common;
|
||||
|
||||
struct event_base *base;
|
||||
|
||||
|
@ -117,14 +118,14 @@ struct evrpc_hook_meta {
|
|||
};
|
||||
|
||||
/* allows association of meta data with a request */
|
||||
static void evrpc_hook_associate_meta(struct evrpc_hook_meta **pctx,
|
||||
static void evrpc_hook_associate_meta_(struct evrpc_hook_meta **pctx,
|
||||
struct evhttp_connection *evcon);
|
||||
|
||||
/* creates a new meta data store */
|
||||
static struct evrpc_hook_meta *evrpc_hook_meta_new(void);
|
||||
static struct evrpc_hook_meta *evrpc_hook_meta_new_(void);
|
||||
|
||||
/* frees the meta data associated with a request */
|
||||
static void evrpc_hook_context_free(struct evrpc_hook_meta *ctx);
|
||||
static void evrpc_hook_context_free_(struct evrpc_hook_meta *ctx);
|
||||
|
||||
/* the server side of an rpc */
|
||||
|
||||
|
@ -201,4 +202,4 @@ struct evrpc_request_wrapper {
|
|||
int (*reply_unmarshal)(void *, struct evbuffer*);
|
||||
};
|
||||
|
||||
#endif /* _EVRPC_INTERNAL_H_ */
|
||||
#endif /* EVRPC_INTERNAL_H_INCLUDED_ */
|
||||
|
|
|
@ -25,8 +25,9 @@
|
|||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "event2/event-config.h"
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
|
@ -34,16 +35,16 @@
|
|||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef _EVENT_HAVE_SYS_TIME_H
|
||||
#ifdef EVENT__HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include <sys/queue.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
|
@ -121,7 +122,7 @@ evrpc_add_hook(void *vbase,
|
|||
int (*cb)(void *, struct evhttp_request *, struct evbuffer *, void *),
|
||||
void *cb_arg)
|
||||
{
|
||||
struct _evrpc_hooks *base = vbase;
|
||||
struct evrpc_hooks_ *base = vbase;
|
||||
struct evrpc_hook_list *head = NULL;
|
||||
struct evrpc_hook *hook = NULL;
|
||||
switch (hook_type) {
|
||||
|
@ -167,7 +168,7 @@ evrpc_remove_hook_internal(struct evrpc_hook_list *head, void *handle)
|
|||
int
|
||||
evrpc_remove_hook(void *vbase, enum EVRPC_HOOK_TYPE hook_type, void *handle)
|
||||
{
|
||||
struct _evrpc_hooks *base = vbase;
|
||||
struct evrpc_hooks_ *base = vbase;
|
||||
struct evrpc_hook_list *head = NULL;
|
||||
switch (hook_type) {
|
||||
case EVRPC_INPUT:
|
||||
|
@ -301,7 +302,7 @@ evrpc_request_cb(struct evhttp_request *req, void *arg)
|
|||
if (TAILQ_FIRST(&rpc->base->input_hooks) != NULL) {
|
||||
int hook_res;
|
||||
|
||||
evrpc_hook_associate_meta(&rpc_state->hook_meta, req->evcon);
|
||||
evrpc_hook_associate_meta_(&rpc_state->hook_meta, req->evcon);
|
||||
|
||||
/*
|
||||
* allow hooks to modify the outgoing request
|
||||
|
@ -328,8 +329,7 @@ evrpc_request_cb(struct evhttp_request *req, void *arg)
|
|||
return;
|
||||
|
||||
error:
|
||||
if (rpc_state != NULL)
|
||||
evrpc_reqstate_free(rpc_state);
|
||||
evrpc_reqstate_free_(rpc_state);
|
||||
evhttp_send_error(req, HTTP_SERVUNAVAIL, NULL);
|
||||
return;
|
||||
}
|
||||
|
@ -371,15 +371,14 @@ evrpc_request_cb_closure(void *arg, enum EVRPC_HOOK_RESULT hook_res)
|
|||
return;
|
||||
|
||||
error:
|
||||
if (rpc_state != NULL)
|
||||
evrpc_reqstate_free(rpc_state);
|
||||
evrpc_reqstate_free_(rpc_state);
|
||||
evhttp_send_error(req, HTTP_SERVUNAVAIL, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
evrpc_reqstate_free(struct evrpc_req_generic* rpc_state)
|
||||
evrpc_reqstate_free_(struct evrpc_req_generic* rpc_state)
|
||||
{
|
||||
struct evrpc *rpc;
|
||||
EVUTIL_ASSERT(rpc_state != NULL);
|
||||
|
@ -387,7 +386,7 @@ evrpc_reqstate_free(struct evrpc_req_generic* rpc_state)
|
|||
|
||||
/* clean up all memory */
|
||||
if (rpc_state->hook_meta != NULL)
|
||||
evrpc_hook_context_free(rpc_state->hook_meta);
|
||||
evrpc_hook_context_free_(rpc_state->hook_meta);
|
||||
if (rpc_state->request != NULL)
|
||||
rpc->request_free(rpc_state->request);
|
||||
if (rpc_state->reply != NULL)
|
||||
|
@ -427,7 +426,7 @@ evrpc_request_done(struct evrpc_req_generic *rpc_state)
|
|||
if (TAILQ_FIRST(&rpc->base->output_hooks) != NULL) {
|
||||
int hook_res;
|
||||
|
||||
evrpc_hook_associate_meta(&rpc_state->hook_meta, req->evcon);
|
||||
evrpc_hook_associate_meta_(&rpc_state->hook_meta, req->evcon);
|
||||
|
||||
/* do hook based tweaks to the request */
|
||||
hook_res = evrpc_process_hooks(&rpc->base->output_hooks,
|
||||
|
@ -453,8 +452,7 @@ evrpc_request_done(struct evrpc_req_generic *rpc_state)
|
|||
return;
|
||||
|
||||
error:
|
||||
if (rpc_state != NULL)
|
||||
evrpc_reqstate_free(rpc_state);
|
||||
evrpc_reqstate_free_(rpc_state);
|
||||
evhttp_send_error(req, HTTP_SERVUNAVAIL, NULL);
|
||||
return;
|
||||
}
|
||||
|
@ -489,13 +487,12 @@ evrpc_request_done_closure(void *arg, enum EVRPC_HOOK_RESULT hook_res)
|
|||
}
|
||||
evhttp_send_reply(req, HTTP_OK, "OK", rpc_state->rpc_data);
|
||||
|
||||
evrpc_reqstate_free(rpc_state);
|
||||
evrpc_reqstate_free_(rpc_state);
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
if (rpc_state != NULL)
|
||||
evrpc_reqstate_free(rpc_state);
|
||||
evrpc_reqstate_free_(rpc_state);
|
||||
evhttp_send_error(req, HTTP_SERVUNAVAIL, NULL);
|
||||
return;
|
||||
}
|
||||
|
@ -531,7 +528,7 @@ static void
|
|||
evrpc_request_wrapper_free(struct evrpc_request_wrapper *request)
|
||||
{
|
||||
if (request->hook_meta != NULL)
|
||||
evrpc_hook_context_free(request->hook_meta);
|
||||
evrpc_hook_context_free_(request->hook_meta);
|
||||
mm_free(request->name);
|
||||
mm_free(request);
|
||||
}
|
||||
|
@ -595,8 +592,8 @@ evrpc_pool_add_connection(struct evrpc_pool *pool,
|
|||
* unless a timeout was specifically set for a connection,
|
||||
* the connection inherits the timeout from the pool.
|
||||
*/
|
||||
if (connection->timeout == -1)
|
||||
connection->timeout = pool->timeout;
|
||||
if (!evutil_timerisset(&connection->timeout))
|
||||
evhttp_connection_set_timeout(connection, pool->timeout);
|
||||
|
||||
/*
|
||||
* if we have any requests pending, schedule them with the new
|
||||
|
@ -623,7 +620,7 @@ evrpc_pool_set_timeout(struct evrpc_pool *pool, int timeout_in_secs)
|
|||
{
|
||||
struct evhttp_connection *evcon;
|
||||
TAILQ_FOREACH(evcon, &pool->connections, next) {
|
||||
evcon->timeout = timeout_in_secs;
|
||||
evhttp_connection_set_timeout(evcon, timeout_in_secs);
|
||||
}
|
||||
pool->timeout = timeout_in_secs;
|
||||
}
|
||||
|
@ -680,7 +677,7 @@ evrpc_schedule_request(struct evhttp_connection *connection,
|
|||
if (TAILQ_FIRST(&pool->output_hooks) != NULL) {
|
||||
int hook_res;
|
||||
|
||||
evrpc_hook_associate_meta(&ctx->hook_meta, connection);
|
||||
evrpc_hook_associate_meta_(&ctx->hook_meta, connection);
|
||||
|
||||
/* apply hooks to the outgoing request */
|
||||
hook_res = evrpc_process_hooks(&pool->output_hooks,
|
||||
|
@ -765,7 +762,7 @@ static int
|
|||
evrpc_pause_request(void *vbase, void *ctx,
|
||||
void (*cb)(void *, enum EVRPC_HOOK_RESULT))
|
||||
{
|
||||
struct _evrpc_hooks *base = vbase;
|
||||
struct evrpc_hooks_ *base = vbase;
|
||||
struct evrpc_hook_ctx *pause = mm_malloc(sizeof(*pause));
|
||||
if (pause == NULL)
|
||||
return (-1);
|
||||
|
@ -780,7 +777,7 @@ evrpc_pause_request(void *vbase, void *ctx,
|
|||
int
|
||||
evrpc_resume_request(void *vbase, void *ctx, enum EVRPC_HOOK_RESULT res)
|
||||
{
|
||||
struct _evrpc_hooks *base = vbase;
|
||||
struct evrpc_hooks_ *base = vbase;
|
||||
struct evrpc_pause_list *head = &base->pause_requests;
|
||||
struct evrpc_hook_ctx *pause;
|
||||
|
||||
|
@ -877,7 +874,7 @@ evrpc_reply_done(struct evhttp_request *req, void *arg)
|
|||
}
|
||||
|
||||
if (TAILQ_FIRST(&pool->input_hooks) != NULL) {
|
||||
evrpc_hook_associate_meta(&ctx->hook_meta, ctx->evcon);
|
||||
evrpc_hook_associate_meta_(&ctx->hook_meta, ctx->evcon);
|
||||
|
||||
/* apply hooks to the incoming request */
|
||||
hook_res = evrpc_process_hooks(&pool->input_hooks,
|
||||
|
@ -976,7 +973,7 @@ evrpc_request_timeout(evutil_socket_t fd, short what, void *arg)
|
|||
struct evhttp_connection *evcon = ctx->evcon;
|
||||
EVUTIL_ASSERT(evcon != NULL);
|
||||
|
||||
evhttp_connection_fail(evcon, EVCON_HTTP_TIMEOUT);
|
||||
evhttp_connection_fail_(evcon, EVREQ_HTTP_TIMEOUT);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -998,7 +995,7 @@ evrpc_meta_data_free(struct evrpc_meta_list *meta_data)
|
|||
}
|
||||
|
||||
static struct evrpc_hook_meta *
|
||||
evrpc_hook_meta_new(void)
|
||||
evrpc_hook_meta_new_(void)
|
||||
{
|
||||
struct evrpc_hook_meta *ctx;
|
||||
ctx = mm_malloc(sizeof(struct evrpc_hook_meta));
|
||||
|
@ -1011,17 +1008,17 @@ evrpc_hook_meta_new(void)
|
|||
}
|
||||
|
||||
static void
|
||||
evrpc_hook_associate_meta(struct evrpc_hook_meta **pctx,
|
||||
evrpc_hook_associate_meta_(struct evrpc_hook_meta **pctx,
|
||||
struct evhttp_connection *evcon)
|
||||
{
|
||||
struct evrpc_hook_meta *ctx = *pctx;
|
||||
if (ctx == NULL)
|
||||
*pctx = ctx = evrpc_hook_meta_new();
|
||||
*pctx = ctx = evrpc_hook_meta_new_();
|
||||
ctx->evcon = evcon;
|
||||
}
|
||||
|
||||
static void
|
||||
evrpc_hook_context_free(struct evrpc_hook_meta *ctx)
|
||||
evrpc_hook_context_free_(struct evrpc_hook_meta *ctx)
|
||||
{
|
||||
evrpc_meta_data_free(&ctx->meta_data);
|
||||
mm_free(ctx);
|
||||
|
@ -1037,7 +1034,7 @@ evrpc_hook_add_meta(void *ctx, const char *key,
|
|||
struct evrpc_meta *meta = NULL;
|
||||
|
||||
if ((store = req->hook_meta) == NULL)
|
||||
store = req->hook_meta = evrpc_hook_meta_new();
|
||||
store = req->hook_meta = evrpc_hook_meta_new_();
|
||||
|
||||
meta = mm_malloc(sizeof(struct evrpc_meta));
|
||||
EVUTIL_ASSERT(meta != NULL);
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _EVSIGNAL_H_
|
||||
#define _EVSIGNAL_H_
|
||||
#ifndef EVSIGNAL_INTERNAL_H_INCLUDED_
|
||||
#define EVSIGNAL_INTERNAL_H_INCLUDED_
|
||||
|
||||
#ifndef evutil_socket_t
|
||||
#include "event2/util.h"
|
||||
|
@ -48,7 +48,7 @@ struct evsig_info {
|
|||
|
||||
/* Array of previous signal handler objects before Libevent started
|
||||
* messing with them. Used to restore old signal handlers. */
|
||||
#ifdef _EVENT_HAVE_SIGACTION
|
||||
#ifdef EVENT__HAVE_SIGACTION
|
||||
struct sigaction **sh_old;
|
||||
#else
|
||||
ev_sighandler_t **sh_old;
|
||||
|
@ -56,9 +56,10 @@ struct evsig_info {
|
|||
/* Size of sh_old. */
|
||||
int sh_old_max;
|
||||
};
|
||||
int evsig_init(struct event_base *);
|
||||
void evsig_dealloc(struct event_base *);
|
||||
int evsig_init_(struct event_base *);
|
||||
void evsig_dealloc_(struct event_base *);
|
||||
|
||||
void evsig_set_base(struct event_base *base);
|
||||
void evsig_set_base_(struct event_base *base);
|
||||
void evsig_free_globals_(void);
|
||||
|
||||
#endif /* _EVSIGNAL_H_ */
|
||||
#endif /* EVSIGNAL_INTERNAL_H_INCLUDED_ */
|
||||
|
|
|
@ -23,20 +23,22 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _EVTHREAD_INTERNAL_H_
|
||||
#define _EVTHREAD_INTERNAL_H_
|
||||
#ifndef EVTHREAD_INTERNAL_H_INCLUDED_
|
||||
#define EVTHREAD_INTERNAL_H_INCLUDED_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "event2/thread.h"
|
||||
#include "event2/event-config.h"
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#include "event2/thread.h"
|
||||
#include "util-internal.h"
|
||||
|
||||
struct event_base;
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
/* On Windows, the way we currently make DLLs, it's not allowed for us to
|
||||
* have shared global structures. Thus, we only do the direct-call-to-function
|
||||
* code path if we know that the local shared library system supports it.
|
||||
|
@ -44,62 +46,62 @@ struct event_base;
|
|||
#define EVTHREAD_EXPOSE_STRUCTS
|
||||
#endif
|
||||
|
||||
#if ! defined(_EVENT_DISABLE_THREAD_SUPPORT) && defined(EVTHREAD_EXPOSE_STRUCTS)
|
||||
#if ! defined(EVENT__DISABLE_THREAD_SUPPORT) && defined(EVTHREAD_EXPOSE_STRUCTS)
|
||||
/* Global function pointers to lock-related functions. NULL if locking isn't
|
||||
enabled. */
|
||||
extern struct evthread_lock_callbacks _evthread_lock_fns;
|
||||
extern struct evthread_condition_callbacks _evthread_cond_fns;
|
||||
extern unsigned long (*_evthread_id_fn)(void);
|
||||
extern int _evthread_lock_debugging_enabled;
|
||||
extern struct evthread_lock_callbacks evthread_lock_fns_;
|
||||
extern struct evthread_condition_callbacks evthread_cond_fns_;
|
||||
extern unsigned long (*evthread_id_fn_)(void);
|
||||
extern int evthread_lock_debugging_enabled_;
|
||||
|
||||
/** Return the ID of the current thread, or 1 if threading isn't enabled. */
|
||||
#define EVTHREAD_GET_ID() \
|
||||
(_evthread_id_fn ? _evthread_id_fn() : 1)
|
||||
(evthread_id_fn_ ? evthread_id_fn_() : 1)
|
||||
|
||||
/** Return true iff we're in the thread that is currently (or most recently)
|
||||
* running a given event_base's loop. Requires lock. */
|
||||
#define EVBASE_IN_THREAD(base) \
|
||||
(_evthread_id_fn == NULL || \
|
||||
(base)->th_owner_id == _evthread_id_fn())
|
||||
(evthread_id_fn_ == NULL || \
|
||||
(base)->th_owner_id == evthread_id_fn_())
|
||||
|
||||
/** Return true iff we need to notify the base's main thread about changes to
|
||||
* its state, because it's currently running the main loop in another
|
||||
* thread. Requires lock. */
|
||||
#define EVBASE_NEED_NOTIFY(base) \
|
||||
(_evthread_id_fn != NULL && \
|
||||
(evthread_id_fn_ != NULL && \
|
||||
(base)->running_loop && \
|
||||
(base)->th_owner_id != _evthread_id_fn())
|
||||
(base)->th_owner_id != evthread_id_fn_())
|
||||
|
||||
/** Allocate a new lock, and store it in lockvar, a void*. Sets lockvar to
|
||||
NULL if locking is not enabled. */
|
||||
#define EVTHREAD_ALLOC_LOCK(lockvar, locktype) \
|
||||
((lockvar) = _evthread_lock_fns.alloc ? \
|
||||
_evthread_lock_fns.alloc(locktype) : NULL)
|
||||
((lockvar) = evthread_lock_fns_.alloc ? \
|
||||
evthread_lock_fns_.alloc(locktype) : NULL)
|
||||
|
||||
/** Free a given lock, if it is present and locking is enabled. */
|
||||
#define EVTHREAD_FREE_LOCK(lockvar, locktype) \
|
||||
do { \
|
||||
void *_lock_tmp_ = (lockvar); \
|
||||
if (_lock_tmp_ && _evthread_lock_fns.free) \
|
||||
_evthread_lock_fns.free(_lock_tmp_, (locktype)); \
|
||||
void *lock_tmp_ = (lockvar); \
|
||||
if (lock_tmp_ && evthread_lock_fns_.free) \
|
||||
evthread_lock_fns_.free(lock_tmp_, (locktype)); \
|
||||
} while (0)
|
||||
|
||||
/** Acquire a lock. */
|
||||
#define EVLOCK_LOCK(lockvar,mode) \
|
||||
do { \
|
||||
if (lockvar) \
|
||||
_evthread_lock_fns.lock(mode, lockvar); \
|
||||
evthread_lock_fns_.lock(mode, lockvar); \
|
||||
} while (0)
|
||||
|
||||
/** Release a lock */
|
||||
#define EVLOCK_UNLOCK(lockvar,mode) \
|
||||
do { \
|
||||
if (lockvar) \
|
||||
_evthread_lock_fns.unlock(mode, lockvar); \
|
||||
evthread_lock_fns_.unlock(mode, lockvar); \
|
||||
} while (0)
|
||||
|
||||
/** Helper: put lockvar1 and lockvar2 into pointerwise ascending order. */
|
||||
#define _EVLOCK_SORTLOCKS(lockvar1, lockvar2) \
|
||||
#define EVLOCK_SORTLOCKS_(lockvar1, lockvar2) \
|
||||
do { \
|
||||
if (lockvar1 && lockvar2 && lockvar1 > lockvar2) { \
|
||||
void *tmp = lockvar1; \
|
||||
|
@ -123,19 +125,19 @@ extern int _evthread_lock_debugging_enabled;
|
|||
* locked and held by us. */
|
||||
#define EVLOCK_ASSERT_LOCKED(lock) \
|
||||
do { \
|
||||
if ((lock) && _evthread_lock_debugging_enabled) { \
|
||||
EVUTIL_ASSERT(_evthread_is_debug_lock_held(lock)); \
|
||||
if ((lock) && evthread_lock_debugging_enabled_) { \
|
||||
EVUTIL_ASSERT(evthread_is_debug_lock_held_(lock)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/** Try to grab the lock for 'lockvar' without blocking, and return 1 if we
|
||||
* manage to get it. */
|
||||
static inline int EVLOCK_TRY_LOCK(void *lock);
|
||||
static inline int EVLOCK_TRY_LOCK_(void *lock);
|
||||
static inline int
|
||||
EVLOCK_TRY_LOCK(void *lock)
|
||||
EVLOCK_TRY_LOCK_(void *lock)
|
||||
{
|
||||
if (lock && _evthread_lock_fns.lock) {
|
||||
int r = _evthread_lock_fns.lock(EVTHREAD_TRY, lock);
|
||||
if (lock && evthread_lock_fns_.lock) {
|
||||
int r = evthread_lock_fns_.lock(EVTHREAD_TRY, lock);
|
||||
return !r;
|
||||
} else {
|
||||
/* Locking is disabled either globally or for this thing;
|
||||
|
@ -147,79 +149,79 @@ EVLOCK_TRY_LOCK(void *lock)
|
|||
/** Allocate a new condition variable and store it in the void *, condvar */
|
||||
#define EVTHREAD_ALLOC_COND(condvar) \
|
||||
do { \
|
||||
(condvar) = _evthread_cond_fns.alloc_condition ? \
|
||||
_evthread_cond_fns.alloc_condition(0) : NULL; \
|
||||
(condvar) = evthread_cond_fns_.alloc_condition ? \
|
||||
evthread_cond_fns_.alloc_condition(0) : NULL; \
|
||||
} while (0)
|
||||
/** Deallocate and free a condition variable in condvar */
|
||||
#define EVTHREAD_FREE_COND(cond) \
|
||||
do { \
|
||||
if (cond) \
|
||||
_evthread_cond_fns.free_condition((cond)); \
|
||||
evthread_cond_fns_.free_condition((cond)); \
|
||||
} while (0)
|
||||
/** Signal one thread waiting on cond */
|
||||
#define EVTHREAD_COND_SIGNAL(cond) \
|
||||
( (cond) ? _evthread_cond_fns.signal_condition((cond), 0) : 0 )
|
||||
( (cond) ? evthread_cond_fns_.signal_condition((cond), 0) : 0 )
|
||||
/** Signal all threads waiting on cond */
|
||||
#define EVTHREAD_COND_BROADCAST(cond) \
|
||||
( (cond) ? _evthread_cond_fns.signal_condition((cond), 1) : 0 )
|
||||
( (cond) ? evthread_cond_fns_.signal_condition((cond), 1) : 0 )
|
||||
/** Wait until the condition 'cond' is signalled. Must be called while
|
||||
* holding 'lock'. The lock will be released until the condition is
|
||||
* signalled, at which point it will be acquired again. Returns 0 for
|
||||
* success, -1 for failure. */
|
||||
#define EVTHREAD_COND_WAIT(cond, lock) \
|
||||
( (cond) ? _evthread_cond_fns.wait_condition((cond), (lock), NULL) : 0 )
|
||||
( (cond) ? evthread_cond_fns_.wait_condition((cond), (lock), NULL) : 0 )
|
||||
/** As EVTHREAD_COND_WAIT, but gives up after 'tv' has elapsed. Returns 1
|
||||
* on timeout. */
|
||||
#define EVTHREAD_COND_WAIT_TIMED(cond, lock, tv) \
|
||||
( (cond) ? _evthread_cond_fns.wait_condition((cond), (lock), (tv)) : 0 )
|
||||
( (cond) ? evthread_cond_fns_.wait_condition((cond), (lock), (tv)) : 0 )
|
||||
|
||||
/** True iff locking functions have been configured. */
|
||||
#define EVTHREAD_LOCKING_ENABLED() \
|
||||
(_evthread_lock_fns.lock != NULL)
|
||||
(evthread_lock_fns_.lock != NULL)
|
||||
|
||||
#elif ! defined(_EVENT_DISABLE_THREAD_SUPPORT)
|
||||
#elif ! defined(EVENT__DISABLE_THREAD_SUPPORT)
|
||||
|
||||
unsigned long _evthreadimpl_get_id(void);
|
||||
int _evthreadimpl_is_lock_debugging_enabled(void);
|
||||
void *_evthreadimpl_lock_alloc(unsigned locktype);
|
||||
void _evthreadimpl_lock_free(void *lock, unsigned locktype);
|
||||
int _evthreadimpl_lock_lock(unsigned mode, void *lock);
|
||||
int _evthreadimpl_lock_unlock(unsigned mode, void *lock);
|
||||
void *_evthreadimpl_cond_alloc(unsigned condtype);
|
||||
void _evthreadimpl_cond_free(void *cond);
|
||||
int _evthreadimpl_cond_signal(void *cond, int broadcast);
|
||||
int _evthreadimpl_cond_wait(void *cond, void *lock, const struct timeval *tv);
|
||||
int _evthreadimpl_locking_enabled(void);
|
||||
unsigned long evthreadimpl_get_id_(void);
|
||||
int evthreadimpl_is_lock_debugging_enabled_(void);
|
||||
void *evthreadimpl_lock_alloc_(unsigned locktype);
|
||||
void evthreadimpl_lock_free_(void *lock, unsigned locktype);
|
||||
int evthreadimpl_lock_lock_(unsigned mode, void *lock);
|
||||
int evthreadimpl_lock_unlock_(unsigned mode, void *lock);
|
||||
void *evthreadimpl_cond_alloc_(unsigned condtype);
|
||||
void evthreadimpl_cond_free_(void *cond);
|
||||
int evthreadimpl_cond_signal_(void *cond, int broadcast);
|
||||
int evthreadimpl_cond_wait_(void *cond, void *lock, const struct timeval *tv);
|
||||
int evthreadimpl_locking_enabled_(void);
|
||||
|
||||
#define EVTHREAD_GET_ID() _evthreadimpl_get_id()
|
||||
#define EVTHREAD_GET_ID() evthreadimpl_get_id_()
|
||||
#define EVBASE_IN_THREAD(base) \
|
||||
((base)->th_owner_id == _evthreadimpl_get_id())
|
||||
((base)->th_owner_id == evthreadimpl_get_id_())
|
||||
#define EVBASE_NEED_NOTIFY(base) \
|
||||
((base)->running_loop && \
|
||||
((base)->th_owner_id != _evthreadimpl_get_id()))
|
||||
((base)->th_owner_id != evthreadimpl_get_id_()))
|
||||
|
||||
#define EVTHREAD_ALLOC_LOCK(lockvar, locktype) \
|
||||
((lockvar) = _evthreadimpl_lock_alloc(locktype))
|
||||
((lockvar) = evthreadimpl_lock_alloc_(locktype))
|
||||
|
||||
#define EVTHREAD_FREE_LOCK(lockvar, locktype) \
|
||||
do { \
|
||||
void *_lock_tmp_ = (lockvar); \
|
||||
if (_lock_tmp_) \
|
||||
_evthreadimpl_lock_free(_lock_tmp_, (locktype)); \
|
||||
void *lock_tmp_ = (lockvar); \
|
||||
if (lock_tmp_) \
|
||||
evthreadimpl_lock_free_(lock_tmp_, (locktype)); \
|
||||
} while (0)
|
||||
|
||||
/** Acquire a lock. */
|
||||
#define EVLOCK_LOCK(lockvar,mode) \
|
||||
do { \
|
||||
if (lockvar) \
|
||||
_evthreadimpl_lock_lock(mode, lockvar); \
|
||||
evthreadimpl_lock_lock_(mode, lockvar); \
|
||||
} while (0)
|
||||
|
||||
/** Release a lock */
|
||||
#define EVLOCK_UNLOCK(lockvar,mode) \
|
||||
do { \
|
||||
if (lockvar) \
|
||||
_evthreadimpl_lock_unlock(mode, lockvar); \
|
||||
evthreadimpl_lock_unlock_(mode, lockvar); \
|
||||
} while (0)
|
||||
|
||||
/** Lock an event_base, if it is set up for locking. Acquires the lock
|
||||
|
@ -237,19 +239,19 @@ int _evthreadimpl_locking_enabled(void);
|
|||
* locked and held by us. */
|
||||
#define EVLOCK_ASSERT_LOCKED(lock) \
|
||||
do { \
|
||||
if ((lock) && _evthreadimpl_is_lock_debugging_enabled()) { \
|
||||
EVUTIL_ASSERT(_evthread_is_debug_lock_held(lock)); \
|
||||
if ((lock) && evthreadimpl_is_lock_debugging_enabled_()) { \
|
||||
EVUTIL_ASSERT(evthread_is_debug_lock_held_(lock)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/** Try to grab the lock for 'lockvar' without blocking, and return 1 if we
|
||||
* manage to get it. */
|
||||
static inline int EVLOCK_TRY_LOCK(void *lock);
|
||||
static inline int EVLOCK_TRY_LOCK_(void *lock);
|
||||
static inline int
|
||||
EVLOCK_TRY_LOCK(void *lock)
|
||||
EVLOCK_TRY_LOCK_(void *lock)
|
||||
{
|
||||
if (lock) {
|
||||
int r = _evthreadimpl_lock_lock(EVTHREAD_TRY, lock);
|
||||
int r = evthreadimpl_lock_lock_(EVTHREAD_TRY, lock);
|
||||
return !r;
|
||||
} else {
|
||||
/* Locking is disabled either globally or for this thing;
|
||||
|
@ -261,68 +263,68 @@ EVLOCK_TRY_LOCK(void *lock)
|
|||
/** Allocate a new condition variable and store it in the void *, condvar */
|
||||
#define EVTHREAD_ALLOC_COND(condvar) \
|
||||
do { \
|
||||
(condvar) = _evthreadimpl_cond_alloc(0); \
|
||||
(condvar) = evthreadimpl_cond_alloc_(0); \
|
||||
} while (0)
|
||||
/** Deallocate and free a condition variable in condvar */
|
||||
#define EVTHREAD_FREE_COND(cond) \
|
||||
do { \
|
||||
if (cond) \
|
||||
_evthreadimpl_cond_free((cond)); \
|
||||
evthreadimpl_cond_free_((cond)); \
|
||||
} while (0)
|
||||
/** Signal one thread waiting on cond */
|
||||
#define EVTHREAD_COND_SIGNAL(cond) \
|
||||
( (cond) ? _evthreadimpl_cond_signal((cond), 0) : 0 )
|
||||
( (cond) ? evthreadimpl_cond_signal_((cond), 0) : 0 )
|
||||
/** Signal all threads waiting on cond */
|
||||
#define EVTHREAD_COND_BROADCAST(cond) \
|
||||
( (cond) ? _evthreadimpl_cond_signal((cond), 1) : 0 )
|
||||
( (cond) ? evthreadimpl_cond_signal_((cond), 1) : 0 )
|
||||
/** Wait until the condition 'cond' is signalled. Must be called while
|
||||
* holding 'lock'. The lock will be released until the condition is
|
||||
* signalled, at which point it will be acquired again. Returns 0 for
|
||||
* success, -1 for failure. */
|
||||
#define EVTHREAD_COND_WAIT(cond, lock) \
|
||||
( (cond) ? _evthreadimpl_cond_wait((cond), (lock), NULL) : 0 )
|
||||
( (cond) ? evthreadimpl_cond_wait_((cond), (lock), NULL) : 0 )
|
||||
/** As EVTHREAD_COND_WAIT, but gives up after 'tv' has elapsed. Returns 1
|
||||
* on timeout. */
|
||||
#define EVTHREAD_COND_WAIT_TIMED(cond, lock, tv) \
|
||||
( (cond) ? _evthreadimpl_cond_wait((cond), (lock), (tv)) : 0 )
|
||||
( (cond) ? evthreadimpl_cond_wait_((cond), (lock), (tv)) : 0 )
|
||||
|
||||
#define EVTHREAD_LOCKING_ENABLED() \
|
||||
(_evthreadimpl_locking_enabled())
|
||||
(evthreadimpl_locking_enabled_())
|
||||
|
||||
#else /* _EVENT_DISABLE_THREAD_SUPPORT */
|
||||
#else /* EVENT__DISABLE_THREAD_SUPPORT */
|
||||
|
||||
#define EVTHREAD_GET_ID() 1
|
||||
#define EVTHREAD_ALLOC_LOCK(lockvar, locktype) _EVUTIL_NIL_STMT
|
||||
#define EVTHREAD_FREE_LOCK(lockvar, locktype) _EVUTIL_NIL_STMT
|
||||
#define EVTHREAD_ALLOC_LOCK(lockvar, locktype) EVUTIL_NIL_STMT_
|
||||
#define EVTHREAD_FREE_LOCK(lockvar, locktype) EVUTIL_NIL_STMT_
|
||||
|
||||
#define EVLOCK_LOCK(lockvar, mode) _EVUTIL_NIL_STMT
|
||||
#define EVLOCK_UNLOCK(lockvar, mode) _EVUTIL_NIL_STMT
|
||||
#define EVLOCK_LOCK2(lock1,lock2,mode1,mode2) _EVUTIL_NIL_STMT
|
||||
#define EVLOCK_UNLOCK2(lock1,lock2,mode1,mode2) _EVUTIL_NIL_STMT
|
||||
#define EVLOCK_LOCK(lockvar, mode) EVUTIL_NIL_STMT_
|
||||
#define EVLOCK_UNLOCK(lockvar, mode) EVUTIL_NIL_STMT_
|
||||
#define EVLOCK_LOCK2(lock1,lock2,mode1,mode2) EVUTIL_NIL_STMT_
|
||||
#define EVLOCK_UNLOCK2(lock1,lock2,mode1,mode2) EVUTIL_NIL_STMT_
|
||||
|
||||
#define EVBASE_IN_THREAD(base) 1
|
||||
#define EVBASE_NEED_NOTIFY(base) 0
|
||||
#define EVBASE_ACQUIRE_LOCK(base, lock) _EVUTIL_NIL_STMT
|
||||
#define EVBASE_RELEASE_LOCK(base, lock) _EVUTIL_NIL_STMT
|
||||
#define EVLOCK_ASSERT_LOCKED(lock) _EVUTIL_NIL_STMT
|
||||
#define EVBASE_ACQUIRE_LOCK(base, lock) EVUTIL_NIL_STMT_
|
||||
#define EVBASE_RELEASE_LOCK(base, lock) EVUTIL_NIL_STMT_
|
||||
#define EVLOCK_ASSERT_LOCKED(lock) EVUTIL_NIL_STMT_
|
||||
|
||||
#define EVLOCK_TRY_LOCK(lock) 1
|
||||
#define EVLOCK_TRY_LOCK_(lock) 1
|
||||
|
||||
#define EVTHREAD_ALLOC_COND(condvar) _EVUTIL_NIL_STMT
|
||||
#define EVTHREAD_FREE_COND(cond) _EVUTIL_NIL_STMT
|
||||
#define EVTHREAD_COND_SIGNAL(cond) _EVUTIL_NIL_STMT
|
||||
#define EVTHREAD_COND_BROADCAST(cond) _EVUTIL_NIL_STMT
|
||||
#define EVTHREAD_COND_WAIT(cond, lock) _EVUTIL_NIL_STMT
|
||||
#define EVTHREAD_COND_WAIT_TIMED(cond, lock, howlong) _EVUTIL_NIL_STMT
|
||||
#define EVTHREAD_ALLOC_COND(condvar) EVUTIL_NIL_STMT_
|
||||
#define EVTHREAD_FREE_COND(cond) EVUTIL_NIL_STMT_
|
||||
#define EVTHREAD_COND_SIGNAL(cond) EVUTIL_NIL_STMT_
|
||||
#define EVTHREAD_COND_BROADCAST(cond) EVUTIL_NIL_STMT_
|
||||
#define EVTHREAD_COND_WAIT(cond, lock) EVUTIL_NIL_STMT_
|
||||
#define EVTHREAD_COND_WAIT_TIMED(cond, lock, howlong) EVUTIL_NIL_STMT_
|
||||
|
||||
#define EVTHREAD_LOCKING_ENABLED() 0
|
||||
|
||||
#endif
|
||||
|
||||
/* This code is shared between both lock impls */
|
||||
#if ! defined(_EVENT_DISABLE_THREAD_SUPPORT)
|
||||
#if ! defined(EVENT__DISABLE_THREAD_SUPPORT)
|
||||
/** Helper: put lockvar1 and lockvar2 into pointerwise ascending order. */
|
||||
#define _EVLOCK_SORTLOCKS(lockvar1, lockvar2) \
|
||||
#define EVLOCK_SORTLOCKS_(lockvar1, lockvar2) \
|
||||
do { \
|
||||
if (lockvar1 && lockvar2 && lockvar1 > lockvar2) { \
|
||||
void *tmp = lockvar1; \
|
||||
|
@ -335,26 +337,26 @@ EVLOCK_TRY_LOCK(void *lock)
|
|||
* so that two threads locking two locks with LOCK2 will not deadlock. */
|
||||
#define EVLOCK_LOCK2(lock1,lock2,mode1,mode2) \
|
||||
do { \
|
||||
void *_lock1_tmplock = (lock1); \
|
||||
void *_lock2_tmplock = (lock2); \
|
||||
_EVLOCK_SORTLOCKS(_lock1_tmplock,_lock2_tmplock); \
|
||||
EVLOCK_LOCK(_lock1_tmplock,mode1); \
|
||||
if (_lock2_tmplock != _lock1_tmplock) \
|
||||
EVLOCK_LOCK(_lock2_tmplock,mode2); \
|
||||
void *lock1_tmplock_ = (lock1); \
|
||||
void *lock2_tmplock_ = (lock2); \
|
||||
EVLOCK_SORTLOCKS_(lock1_tmplock_,lock2_tmplock_); \
|
||||
EVLOCK_LOCK(lock1_tmplock_,mode1); \
|
||||
if (lock2_tmplock_ != lock1_tmplock_) \
|
||||
EVLOCK_LOCK(lock2_tmplock_,mode2); \
|
||||
} while (0)
|
||||
/** Release both lock1 and lock2. */
|
||||
#define EVLOCK_UNLOCK2(lock1,lock2,mode1,mode2) \
|
||||
do { \
|
||||
void *_lock1_tmplock = (lock1); \
|
||||
void *_lock2_tmplock = (lock2); \
|
||||
_EVLOCK_SORTLOCKS(_lock1_tmplock,_lock2_tmplock); \
|
||||
if (_lock2_tmplock != _lock1_tmplock) \
|
||||
EVLOCK_UNLOCK(_lock2_tmplock,mode2); \
|
||||
EVLOCK_UNLOCK(_lock1_tmplock,mode1); \
|
||||
void *lock1_tmplock_ = (lock1); \
|
||||
void *lock2_tmplock_ = (lock2); \
|
||||
EVLOCK_SORTLOCKS_(lock1_tmplock_,lock2_tmplock_); \
|
||||
if (lock2_tmplock_ != lock1_tmplock_) \
|
||||
EVLOCK_UNLOCK(lock2_tmplock_,mode2); \
|
||||
EVLOCK_UNLOCK(lock1_tmplock_,mode1); \
|
||||
} while (0)
|
||||
|
||||
int _evthread_is_debug_lock_held(void *lock);
|
||||
void *_evthread_debug_get_real_lock(void *lock);
|
||||
int evthread_is_debug_lock_held_(void *lock);
|
||||
void *evthread_debug_get_real_lock_(void *lock);
|
||||
|
||||
void *evthread_setup_global_lock_(void *lock_, unsigned locktype,
|
||||
int enable_locks);
|
||||
|
@ -371,12 +373,20 @@ void *evthread_setup_global_lock_(void *lock_, unsigned locktype,
|
|||
|
||||
int event_global_setup_locks_(const int enable_locks);
|
||||
int evsig_global_setup_locks_(const int enable_locks);
|
||||
int evutil_global_setup_locks_(const int enable_locks);
|
||||
int evutil_secure_rng_global_setup_locks_(const int enable_locks);
|
||||
|
||||
/** Return current evthread_lock_callbacks */
|
||||
struct evthread_lock_callbacks *evthread_get_lock_callbacks(void);
|
||||
/** Return current evthread_condition_callbacks */
|
||||
struct evthread_condition_callbacks *evthread_get_condition_callbacks(void);
|
||||
/** Disable locking for internal usage (like global shutdown) */
|
||||
void evthreadimpl_disable_lock_debugging_(void);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _EVTHREAD_INTERNAL_H_ */
|
||||
#endif /* EVTHREAD_INTERNAL_H_INCLUDED_ */
|
||||
|
|
|
@ -25,8 +25,9 @@
|
|||
*/
|
||||
|
||||
#include "event2/event-config.h"
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#ifndef _EVENT_DISABLE_THREAD_SUPPORT
|
||||
#ifndef EVENT__DISABLE_THREAD_SUPPORT
|
||||
|
||||
#include "event2/thread.h"
|
||||
|
||||
|
@ -44,42 +45,68 @@
|
|||
#define GLOBAL static
|
||||
#endif
|
||||
|
||||
#ifndef EVENT__DISABLE_DEBUG_MODE
|
||||
extern int event_debug_created_threadable_ctx_;
|
||||
extern int event_debug_mode_on_;
|
||||
#endif
|
||||
|
||||
/* globals */
|
||||
GLOBAL int _evthread_lock_debugging_enabled = 0;
|
||||
GLOBAL struct evthread_lock_callbacks _evthread_lock_fns = {
|
||||
GLOBAL int evthread_lock_debugging_enabled_ = 0;
|
||||
GLOBAL struct evthread_lock_callbacks evthread_lock_fns_ = {
|
||||
0, 0, NULL, NULL, NULL, NULL
|
||||
};
|
||||
GLOBAL unsigned long (*_evthread_id_fn)(void) = NULL;
|
||||
GLOBAL struct evthread_condition_callbacks _evthread_cond_fns = {
|
||||
GLOBAL unsigned long (*evthread_id_fn_)(void) = NULL;
|
||||
GLOBAL struct evthread_condition_callbacks evthread_cond_fns_ = {
|
||||
0, NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
/* Used for debugging */
|
||||
static struct evthread_lock_callbacks _original_lock_fns = {
|
||||
static struct evthread_lock_callbacks original_lock_fns_ = {
|
||||
0, 0, NULL, NULL, NULL, NULL
|
||||
};
|
||||
static struct evthread_condition_callbacks _original_cond_fns = {
|
||||
static struct evthread_condition_callbacks original_cond_fns_ = {
|
||||
0, NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
void
|
||||
evthread_set_id_callback(unsigned long (*id_fn)(void))
|
||||
{
|
||||
_evthread_id_fn = id_fn;
|
||||
evthread_id_fn_ = id_fn;
|
||||
}
|
||||
|
||||
struct evthread_lock_callbacks *evthread_get_lock_callbacks()
|
||||
{
|
||||
return evthread_lock_debugging_enabled_
|
||||
? &original_lock_fns_ : &evthread_lock_fns_;
|
||||
}
|
||||
struct evthread_condition_callbacks *evthread_get_condition_callbacks()
|
||||
{
|
||||
return evthread_lock_debugging_enabled_
|
||||
? &original_cond_fns_ : &evthread_cond_fns_;
|
||||
}
|
||||
void evthreadimpl_disable_lock_debugging_(void)
|
||||
{
|
||||
evthread_lock_debugging_enabled_ = 0;
|
||||
}
|
||||
|
||||
int
|
||||
evthread_set_lock_callbacks(const struct evthread_lock_callbacks *cbs)
|
||||
{
|
||||
struct evthread_lock_callbacks *target =
|
||||
_evthread_lock_debugging_enabled
|
||||
? &_original_lock_fns : &_evthread_lock_fns;
|
||||
struct evthread_lock_callbacks *target = evthread_get_lock_callbacks();
|
||||
|
||||
#ifndef EVENT__DISABLE_DEBUG_MODE
|
||||
if (event_debug_mode_on_) {
|
||||
if (event_debug_created_threadable_ctx_) {
|
||||
event_errx(1, "evthread initialization must be called BEFORE anything else!");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!cbs) {
|
||||
if (target->alloc)
|
||||
event_warnx("Trying to disable lock functions after "
|
||||
"they have been set up will probaby not work.");
|
||||
memset(target, 0, sizeof(_evthread_lock_fns));
|
||||
memset(target, 0, sizeof(evthread_lock_fns_));
|
||||
return 0;
|
||||
}
|
||||
if (target->alloc) {
|
||||
|
@ -98,7 +125,7 @@ evthread_set_lock_callbacks(const struct evthread_lock_callbacks *cbs)
|
|||
return -1;
|
||||
}
|
||||
if (cbs->alloc && cbs->free && cbs->lock && cbs->unlock) {
|
||||
memcpy(target, cbs, sizeof(_evthread_lock_fns));
|
||||
memcpy(target, cbs, sizeof(evthread_lock_fns_));
|
||||
return event_global_setup_locks_(1);
|
||||
} else {
|
||||
return -1;
|
||||
|
@ -108,16 +135,22 @@ evthread_set_lock_callbacks(const struct evthread_lock_callbacks *cbs)
|
|||
int
|
||||
evthread_set_condition_callbacks(const struct evthread_condition_callbacks *cbs)
|
||||
{
|
||||
struct evthread_condition_callbacks *target =
|
||||
_evthread_lock_debugging_enabled
|
||||
? &_original_cond_fns : &_evthread_cond_fns;
|
||||
struct evthread_condition_callbacks *target = evthread_get_condition_callbacks();
|
||||
|
||||
#ifndef EVENT__DISABLE_DEBUG_MODE
|
||||
if (event_debug_mode_on_) {
|
||||
if (event_debug_created_threadable_ctx_) {
|
||||
event_errx(1, "evthread initialization must be called BEFORE anything else!");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!cbs) {
|
||||
if (target->alloc_condition)
|
||||
event_warnx("Trying to disable condition functions "
|
||||
"after they have been set up will probaby not "
|
||||
"work.");
|
||||
memset(target, 0, sizeof(_evthread_cond_fns));
|
||||
memset(target, 0, sizeof(evthread_cond_fns_));
|
||||
return 0;
|
||||
}
|
||||
if (target->alloc_condition) {
|
||||
|
@ -136,17 +169,20 @@ evthread_set_condition_callbacks(const struct evthread_condition_callbacks *cbs)
|
|||
}
|
||||
if (cbs->alloc_condition && cbs->free_condition &&
|
||||
cbs->signal_condition && cbs->wait_condition) {
|
||||
memcpy(target, cbs, sizeof(_evthread_cond_fns));
|
||||
memcpy(target, cbs, sizeof(evthread_cond_fns_));
|
||||
}
|
||||
if (_evthread_lock_debugging_enabled) {
|
||||
_evthread_cond_fns.alloc_condition = cbs->alloc_condition;
|
||||
_evthread_cond_fns.free_condition = cbs->free_condition;
|
||||
_evthread_cond_fns.signal_condition = cbs->signal_condition;
|
||||
if (evthread_lock_debugging_enabled_) {
|
||||
evthread_cond_fns_.alloc_condition = cbs->alloc_condition;
|
||||
evthread_cond_fns_.free_condition = cbs->free_condition;
|
||||
evthread_cond_fns_.signal_condition = cbs->signal_condition;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define DEBUG_LOCK_SIG 0xdeb0b10c
|
||||
|
||||
struct debug_lock {
|
||||
unsigned signature;
|
||||
unsigned locktype;
|
||||
unsigned long held_by;
|
||||
/* XXXX if we ever use read-write locks, we will need a separate
|
||||
|
@ -161,8 +197,8 @@ debug_lock_alloc(unsigned locktype)
|
|||
struct debug_lock *result = mm_malloc(sizeof(struct debug_lock));
|
||||
if (!result)
|
||||
return NULL;
|
||||
if (_original_lock_fns.alloc) {
|
||||
if (!(result->lock = _original_lock_fns.alloc(
|
||||
if (original_lock_fns_.alloc) {
|
||||
if (!(result->lock = original_lock_fns_.alloc(
|
||||
locktype|EVTHREAD_LOCKTYPE_RECURSIVE))) {
|
||||
mm_free(result);
|
||||
return NULL;
|
||||
|
@ -170,6 +206,7 @@ debug_lock_alloc(unsigned locktype)
|
|||
} else {
|
||||
result->lock = NULL;
|
||||
}
|
||||
result->signature = DEBUG_LOCK_SIG;
|
||||
result->locktype = locktype;
|
||||
result->count = 0;
|
||||
result->held_by = 0;
|
||||
|
@ -182,24 +219,27 @@ debug_lock_free(void *lock_, unsigned locktype)
|
|||
struct debug_lock *lock = lock_;
|
||||
EVUTIL_ASSERT(lock->count == 0);
|
||||
EVUTIL_ASSERT(locktype == lock->locktype);
|
||||
if (_original_lock_fns.free) {
|
||||
_original_lock_fns.free(lock->lock,
|
||||
EVUTIL_ASSERT(DEBUG_LOCK_SIG == lock->signature);
|
||||
if (original_lock_fns_.free) {
|
||||
original_lock_fns_.free(lock->lock,
|
||||
lock->locktype|EVTHREAD_LOCKTYPE_RECURSIVE);
|
||||
}
|
||||
lock->lock = NULL;
|
||||
lock->count = -100;
|
||||
lock->signature = 0x12300fda;
|
||||
mm_free(lock);
|
||||
}
|
||||
|
||||
static void
|
||||
evthread_debug_lock_mark_locked(unsigned mode, struct debug_lock *lock)
|
||||
{
|
||||
EVUTIL_ASSERT(DEBUG_LOCK_SIG == lock->signature);
|
||||
++lock->count;
|
||||
if (!(lock->locktype & EVTHREAD_LOCKTYPE_RECURSIVE))
|
||||
EVUTIL_ASSERT(lock->count == 1);
|
||||
if (_evthread_id_fn) {
|
||||
if (evthread_id_fn_) {
|
||||
unsigned long me;
|
||||
me = _evthread_id_fn();
|
||||
me = evthread_id_fn_();
|
||||
if (lock->count > 1)
|
||||
EVUTIL_ASSERT(lock->held_by == me);
|
||||
lock->held_by = me;
|
||||
|
@ -215,8 +255,8 @@ debug_lock_lock(unsigned mode, void *lock_)
|
|||
EVUTIL_ASSERT(mode & (EVTHREAD_READ|EVTHREAD_WRITE));
|
||||
else
|
||||
EVUTIL_ASSERT((mode & (EVTHREAD_READ|EVTHREAD_WRITE)) == 0);
|
||||
if (_original_lock_fns.lock)
|
||||
res = _original_lock_fns.lock(mode, lock->lock);
|
||||
if (original_lock_fns_.lock)
|
||||
res = original_lock_fns_.lock(mode, lock->lock);
|
||||
if (!res) {
|
||||
evthread_debug_lock_mark_locked(mode, lock);
|
||||
}
|
||||
|
@ -226,12 +266,15 @@ debug_lock_lock(unsigned mode, void *lock_)
|
|||
static void
|
||||
evthread_debug_lock_mark_unlocked(unsigned mode, struct debug_lock *lock)
|
||||
{
|
||||
EVUTIL_ASSERT(DEBUG_LOCK_SIG == lock->signature);
|
||||
if (lock->locktype & EVTHREAD_LOCKTYPE_READWRITE)
|
||||
EVUTIL_ASSERT(mode & (EVTHREAD_READ|EVTHREAD_WRITE));
|
||||
else
|
||||
EVUTIL_ASSERT((mode & (EVTHREAD_READ|EVTHREAD_WRITE)) == 0);
|
||||
if (_evthread_id_fn) {
|
||||
EVUTIL_ASSERT(lock->held_by == _evthread_id_fn());
|
||||
if (evthread_id_fn_) {
|
||||
unsigned long me;
|
||||
me = evthread_id_fn_();
|
||||
EVUTIL_ASSERT(lock->held_by == me);
|
||||
if (lock->count == 1)
|
||||
lock->held_by = 0;
|
||||
}
|
||||
|
@ -245,26 +288,34 @@ debug_lock_unlock(unsigned mode, void *lock_)
|
|||
struct debug_lock *lock = lock_;
|
||||
int res = 0;
|
||||
evthread_debug_lock_mark_unlocked(mode, lock);
|
||||
if (_original_lock_fns.unlock)
|
||||
res = _original_lock_fns.unlock(mode, lock->lock);
|
||||
if (original_lock_fns_.unlock)
|
||||
res = original_lock_fns_.unlock(mode, lock->lock);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int
|
||||
debug_cond_wait(void *_cond, void *_lock, const struct timeval *tv)
|
||||
debug_cond_wait(void *cond_, void *lock_, const struct timeval *tv)
|
||||
{
|
||||
int r;
|
||||
struct debug_lock *lock = _lock;
|
||||
struct debug_lock *lock = lock_;
|
||||
EVUTIL_ASSERT(lock);
|
||||
EVLOCK_ASSERT_LOCKED(_lock);
|
||||
EVUTIL_ASSERT(DEBUG_LOCK_SIG == lock->signature);
|
||||
EVLOCK_ASSERT_LOCKED(lock_);
|
||||
evthread_debug_lock_mark_unlocked(0, lock);
|
||||
r = _original_cond_fns.wait_condition(_cond, lock->lock, tv);
|
||||
r = original_cond_fns_.wait_condition(cond_, lock->lock, tv);
|
||||
evthread_debug_lock_mark_locked(0, lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* misspelled version for backward compatibility */
|
||||
void
|
||||
evthread_enable_lock_debuging(void)
|
||||
{
|
||||
evthread_enable_lock_debugging();
|
||||
}
|
||||
|
||||
void
|
||||
evthread_enable_lock_debugging(void)
|
||||
{
|
||||
struct evthread_lock_callbacks cbs = {
|
||||
EVTHREAD_LOCK_API_VERSION,
|
||||
|
@ -274,30 +325,30 @@ evthread_enable_lock_debuging(void)
|
|||
debug_lock_lock,
|
||||
debug_lock_unlock
|
||||
};
|
||||
if (_evthread_lock_debugging_enabled)
|
||||
if (evthread_lock_debugging_enabled_)
|
||||
return;
|
||||
memcpy(&_original_lock_fns, &_evthread_lock_fns,
|
||||
memcpy(&original_lock_fns_, &evthread_lock_fns_,
|
||||
sizeof(struct evthread_lock_callbacks));
|
||||
memcpy(&_evthread_lock_fns, &cbs,
|
||||
memcpy(&evthread_lock_fns_, &cbs,
|
||||
sizeof(struct evthread_lock_callbacks));
|
||||
|
||||
memcpy(&_original_cond_fns, &_evthread_cond_fns,
|
||||
memcpy(&original_cond_fns_, &evthread_cond_fns_,
|
||||
sizeof(struct evthread_condition_callbacks));
|
||||
_evthread_cond_fns.wait_condition = debug_cond_wait;
|
||||
_evthread_lock_debugging_enabled = 1;
|
||||
evthread_cond_fns_.wait_condition = debug_cond_wait;
|
||||
evthread_lock_debugging_enabled_ = 1;
|
||||
|
||||
/* XXX return value should get checked. */
|
||||
event_global_setup_locks_(0);
|
||||
}
|
||||
|
||||
int
|
||||
_evthread_is_debug_lock_held(void *lock_)
|
||||
evthread_is_debug_lock_held_(void *lock_)
|
||||
{
|
||||
struct debug_lock *lock = lock_;
|
||||
if (! lock->count)
|
||||
return 0;
|
||||
if (_evthread_id_fn) {
|
||||
unsigned long me = _evthread_id_fn();
|
||||
if (evthread_id_fn_) {
|
||||
unsigned long me = evthread_id_fn_();
|
||||
if (lock->held_by != me)
|
||||
return 0;
|
||||
}
|
||||
|
@ -305,7 +356,7 @@ _evthread_is_debug_lock_held(void *lock_)
|
|||
}
|
||||
|
||||
void *
|
||||
_evthread_debug_get_real_lock(void *lock_)
|
||||
evthread_debug_get_real_lock_(void *lock_)
|
||||
{
|
||||
struct debug_lock *lock = lock_;
|
||||
return lock->lock;
|
||||
|
@ -320,23 +371,23 @@ evthread_setup_global_lock_(void *lock_, unsigned locktype, int enable_locks)
|
|||
3) we're turning on locking; debugging is not on.
|
||||
4) we're turning on locking; debugging is on. */
|
||||
|
||||
if (!enable_locks && _original_lock_fns.alloc == NULL) {
|
||||
if (!enable_locks && original_lock_fns_.alloc == NULL) {
|
||||
/* Case 1: allocate a debug lock. */
|
||||
EVUTIL_ASSERT(lock_ == NULL);
|
||||
return debug_lock_alloc(locktype);
|
||||
} else if (!enable_locks && _original_lock_fns.alloc != NULL) {
|
||||
} else if (!enable_locks && original_lock_fns_.alloc != NULL) {
|
||||
/* Case 2: wrap the lock in a debug lock. */
|
||||
struct debug_lock *lock;
|
||||
EVUTIL_ASSERT(lock_ != NULL);
|
||||
|
||||
if (!(locktype & EVTHREAD_LOCKTYPE_RECURSIVE)) {
|
||||
/* We can't wrap it: We need a recursive lock */
|
||||
_original_lock_fns.free(lock_, locktype);
|
||||
original_lock_fns_.free(lock_, locktype);
|
||||
return debug_lock_alloc(locktype);
|
||||
}
|
||||
lock = mm_malloc(sizeof(struct debug_lock));
|
||||
if (!lock) {
|
||||
_original_lock_fns.free(lock_, locktype);
|
||||
original_lock_fns_.free(lock_, locktype);
|
||||
return NULL;
|
||||
}
|
||||
lock->lock = lock_;
|
||||
|
@ -344,23 +395,24 @@ evthread_setup_global_lock_(void *lock_, unsigned locktype, int enable_locks)
|
|||
lock->count = 0;
|
||||
lock->held_by = 0;
|
||||
return lock;
|
||||
} else if (enable_locks && ! _evthread_lock_debugging_enabled) {
|
||||
} else if (enable_locks && ! evthread_lock_debugging_enabled_) {
|
||||
/* Case 3: allocate a regular lock */
|
||||
EVUTIL_ASSERT(lock_ == NULL);
|
||||
return _evthread_lock_fns.alloc(locktype);
|
||||
return evthread_lock_fns_.alloc(locktype);
|
||||
} else {
|
||||
/* Case 4: Fill in a debug lock with a real lock */
|
||||
struct debug_lock *lock = lock_;
|
||||
struct debug_lock *lock = lock_ ? lock_ : debug_lock_alloc(locktype);
|
||||
EVUTIL_ASSERT(enable_locks &&
|
||||
_evthread_lock_debugging_enabled);
|
||||
evthread_lock_debugging_enabled_);
|
||||
EVUTIL_ASSERT(lock->locktype == locktype);
|
||||
EVUTIL_ASSERT(lock->lock == NULL);
|
||||
lock->lock = _original_lock_fns.alloc(
|
||||
locktype|EVTHREAD_LOCKTYPE_RECURSIVE);
|
||||
if (!lock->lock) {
|
||||
lock->count = -200;
|
||||
mm_free(lock);
|
||||
return NULL;
|
||||
lock->lock = original_lock_fns_.alloc(
|
||||
locktype|EVTHREAD_LOCKTYPE_RECURSIVE);
|
||||
if (!lock->lock) {
|
||||
lock->count = -200;
|
||||
mm_free(lock);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return lock;
|
||||
}
|
||||
|
@ -369,76 +421,88 @@ evthread_setup_global_lock_(void *lock_, unsigned locktype, int enable_locks)
|
|||
|
||||
#ifndef EVTHREAD_EXPOSE_STRUCTS
|
||||
unsigned long
|
||||
_evthreadimpl_get_id()
|
||||
evthreadimpl_get_id_()
|
||||
{
|
||||
return _evthread_id_fn ? _evthread_id_fn() : 1;
|
||||
return evthread_id_fn_ ? evthread_id_fn_() : 1;
|
||||
}
|
||||
void *
|
||||
_evthreadimpl_lock_alloc(unsigned locktype)
|
||||
evthreadimpl_lock_alloc_(unsigned locktype)
|
||||
{
|
||||
return _evthread_lock_fns.alloc ?
|
||||
_evthread_lock_fns.alloc(locktype) : NULL;
|
||||
#ifndef EVENT__DISABLE_DEBUG_MODE
|
||||
if (event_debug_mode_on_) {
|
||||
event_debug_created_threadable_ctx_ = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return evthread_lock_fns_.alloc ?
|
||||
evthread_lock_fns_.alloc(locktype) : NULL;
|
||||
}
|
||||
void
|
||||
_evthreadimpl_lock_free(void *lock, unsigned locktype)
|
||||
evthreadimpl_lock_free_(void *lock, unsigned locktype)
|
||||
{
|
||||
if (_evthread_lock_fns.free)
|
||||
_evthread_lock_fns.free(lock, locktype);
|
||||
if (evthread_lock_fns_.free)
|
||||
evthread_lock_fns_.free(lock, locktype);
|
||||
}
|
||||
int
|
||||
_evthreadimpl_lock_lock(unsigned mode, void *lock)
|
||||
evthreadimpl_lock_lock_(unsigned mode, void *lock)
|
||||
{
|
||||
if (_evthread_lock_fns.lock)
|
||||
return _evthread_lock_fns.lock(mode, lock);
|
||||
if (evthread_lock_fns_.lock)
|
||||
return evthread_lock_fns_.lock(mode, lock);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
int
|
||||
_evthreadimpl_lock_unlock(unsigned mode, void *lock)
|
||||
evthreadimpl_lock_unlock_(unsigned mode, void *lock)
|
||||
{
|
||||
if (_evthread_lock_fns.unlock)
|
||||
return _evthread_lock_fns.unlock(mode, lock);
|
||||
if (evthread_lock_fns_.unlock)
|
||||
return evthread_lock_fns_.unlock(mode, lock);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
void *
|
||||
_evthreadimpl_cond_alloc(unsigned condtype)
|
||||
evthreadimpl_cond_alloc_(unsigned condtype)
|
||||
{
|
||||
return _evthread_cond_fns.alloc_condition ?
|
||||
_evthread_cond_fns.alloc_condition(condtype) : NULL;
|
||||
#ifndef EVENT__DISABLE_DEBUG_MODE
|
||||
if (event_debug_mode_on_) {
|
||||
event_debug_created_threadable_ctx_ = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return evthread_cond_fns_.alloc_condition ?
|
||||
evthread_cond_fns_.alloc_condition(condtype) : NULL;
|
||||
}
|
||||
void
|
||||
_evthreadimpl_cond_free(void *cond)
|
||||
evthreadimpl_cond_free_(void *cond)
|
||||
{
|
||||
if (_evthread_cond_fns.free_condition)
|
||||
_evthread_cond_fns.free_condition(cond);
|
||||
if (evthread_cond_fns_.free_condition)
|
||||
evthread_cond_fns_.free_condition(cond);
|
||||
}
|
||||
int
|
||||
_evthreadimpl_cond_signal(void *cond, int broadcast)
|
||||
evthreadimpl_cond_signal_(void *cond, int broadcast)
|
||||
{
|
||||
if (_evthread_cond_fns.signal_condition)
|
||||
return _evthread_cond_fns.signal_condition(cond, broadcast);
|
||||
if (evthread_cond_fns_.signal_condition)
|
||||
return evthread_cond_fns_.signal_condition(cond, broadcast);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
int
|
||||
_evthreadimpl_cond_wait(void *cond, void *lock, const struct timeval *tv)
|
||||
evthreadimpl_cond_wait_(void *cond, void *lock, const struct timeval *tv)
|
||||
{
|
||||
if (_evthread_cond_fns.wait_condition)
|
||||
return _evthread_cond_fns.wait_condition(cond, lock, tv);
|
||||
if (evthread_cond_fns_.wait_condition)
|
||||
return evthread_cond_fns_.wait_condition(cond, lock, tv);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
int
|
||||
_evthreadimpl_is_lock_debugging_enabled(void)
|
||||
evthreadimpl_is_lock_debugging_enabled_(void)
|
||||
{
|
||||
return _evthread_lock_debugging_enabled;
|
||||
return evthread_lock_debugging_enabled_;
|
||||
}
|
||||
|
||||
int
|
||||
_evthreadimpl_locking_enabled(void)
|
||||
evthreadimpl_locking_enabled_(void)
|
||||
{
|
||||
return _evthread_lock_fns.lock != NULL;
|
||||
return evthread_lock_fns_.lock != NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -24,9 +24,11 @@
|
|||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "event2/event-config.h"
|
||||
#include "evconfig-private.h"
|
||||
|
||||
/* With glibc we need to define this to get PTHREAD_MUTEX_RECURSIVE. */
|
||||
#define _GNU_SOURCE
|
||||
/* With glibc we need to define _GNU_SOURCE to get PTHREAD_MUTEX_RECURSIVE.
|
||||
* This comes from evconfig-private.h
|
||||
*/
|
||||
#include <pthread.h>
|
||||
|
||||
struct event_base;
|
||||
|
@ -56,17 +58,17 @@ evthread_posix_lock_alloc(unsigned locktype)
|
|||
}
|
||||
|
||||
static void
|
||||
evthread_posix_lock_free(void *_lock, unsigned locktype)
|
||||
evthread_posix_lock_free(void *lock_, unsigned locktype)
|
||||
{
|
||||
pthread_mutex_t *lock = _lock;
|
||||
pthread_mutex_t *lock = lock_;
|
||||
pthread_mutex_destroy(lock);
|
||||
mm_free(lock);
|
||||
}
|
||||
|
||||
static int
|
||||
evthread_posix_lock(unsigned mode, void *_lock)
|
||||
evthread_posix_lock(unsigned mode, void *lock_)
|
||||
{
|
||||
pthread_mutex_t *lock = _lock;
|
||||
pthread_mutex_t *lock = lock_;
|
||||
if (mode & EVTHREAD_TRY)
|
||||
return pthread_mutex_trylock(lock);
|
||||
else
|
||||
|
@ -74,9 +76,9 @@ evthread_posix_lock(unsigned mode, void *_lock)
|
|||
}
|
||||
|
||||
static int
|
||||
evthread_posix_unlock(unsigned mode, void *_lock)
|
||||
evthread_posix_unlock(unsigned mode, void *lock_)
|
||||
{
|
||||
pthread_mutex_t *lock = _lock;
|
||||
pthread_mutex_t *lock = lock_;
|
||||
return pthread_mutex_unlock(lock);
|
||||
}
|
||||
|
||||
|
@ -85,13 +87,13 @@ evthread_posix_get_id(void)
|
|||
{
|
||||
union {
|
||||
pthread_t thr;
|
||||
#if _EVENT_SIZEOF_PTHREAD_T > _EVENT_SIZEOF_LONG
|
||||
#if EVENT__SIZEOF_PTHREAD_T > EVENT__SIZEOF_LONG
|
||||
ev_uint64_t id;
|
||||
#else
|
||||
unsigned long id;
|
||||
#endif
|
||||
} r;
|
||||
#if _EVENT_SIZEOF_PTHREAD_T < _EVENT_SIZEOF_LONG
|
||||
#if EVENT__SIZEOF_PTHREAD_T < EVENT__SIZEOF_LONG
|
||||
memset(&r, 0, sizeof(r));
|
||||
#endif
|
||||
r.thr = pthread_self();
|
||||
|
@ -112,17 +114,17 @@ evthread_posix_cond_alloc(unsigned condflags)
|
|||
}
|
||||
|
||||
static void
|
||||
evthread_posix_cond_free(void *_cond)
|
||||
evthread_posix_cond_free(void *cond_)
|
||||
{
|
||||
pthread_cond_t *cond = _cond;
|
||||
pthread_cond_t *cond = cond_;
|
||||
pthread_cond_destroy(cond);
|
||||
mm_free(cond);
|
||||
}
|
||||
|
||||
static int
|
||||
evthread_posix_cond_signal(void *_cond, int broadcast)
|
||||
evthread_posix_cond_signal(void *cond_, int broadcast)
|
||||
{
|
||||
pthread_cond_t *cond = _cond;
|
||||
pthread_cond_t *cond = cond_;
|
||||
int r;
|
||||
if (broadcast)
|
||||
r = pthread_cond_broadcast(cond);
|
||||
|
@ -132,11 +134,11 @@ evthread_posix_cond_signal(void *_cond, int broadcast)
|
|||
}
|
||||
|
||||
static int
|
||||
evthread_posix_cond_wait(void *_cond, void *_lock, const struct timeval *tv)
|
||||
evthread_posix_cond_wait(void *cond_, void *lock_, const struct timeval *tv)
|
||||
{
|
||||
int r;
|
||||
pthread_cond_t *cond = _cond;
|
||||
pthread_mutex_t *lock = _lock;
|
||||
pthread_cond_t *cond = cond_;
|
||||
pthread_mutex_t *lock = lock_;
|
||||
|
||||
if (tv) {
|
||||
struct timeval now, abstime;
|
||||
|
|
|
@ -24,8 +24,9 @@
|
|||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "event2/event-config.h"
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#ifndef _WIN32_WINNT
|
||||
/* Minimum required for InitializeCriticalSectionAndSpinCount */
|
||||
#define _WIN32_WINNT 0x0403
|
||||
|
@ -42,6 +43,7 @@ struct event_base;
|
|||
|
||||
#include "mm-internal.h"
|
||||
#include "evthread-internal.h"
|
||||
#include "time-internal.h"
|
||||
|
||||
#define SPIN_COUNT 2000
|
||||
|
||||
|
@ -59,17 +61,17 @@ evthread_win32_lock_create(unsigned locktype)
|
|||
}
|
||||
|
||||
static void
|
||||
evthread_win32_lock_free(void *_lock, unsigned locktype)
|
||||
evthread_win32_lock_free(void *lock_, unsigned locktype)
|
||||
{
|
||||
CRITICAL_SECTION *lock = _lock;
|
||||
CRITICAL_SECTION *lock = lock_;
|
||||
DeleteCriticalSection(lock);
|
||||
mm_free(lock);
|
||||
}
|
||||
|
||||
static int
|
||||
evthread_win32_lock(unsigned mode, void *_lock)
|
||||
evthread_win32_lock(unsigned mode, void *lock_)
|
||||
{
|
||||
CRITICAL_SECTION *lock = _lock;
|
||||
CRITICAL_SECTION *lock = lock_;
|
||||
if ((mode & EVTHREAD_TRY)) {
|
||||
return ! TryEnterCriticalSection(lock);
|
||||
} else {
|
||||
|
@ -79,9 +81,9 @@ evthread_win32_lock(unsigned mode, void *_lock)
|
|||
}
|
||||
|
||||
static int
|
||||
evthread_win32_unlock(unsigned mode, void *_lock)
|
||||
evthread_win32_unlock(unsigned mode, void *lock_)
|
||||
{
|
||||
CRITICAL_SECTION *lock = _lock;
|
||||
CRITICAL_SECTION *lock = lock_;
|
||||
LeaveCriticalSection(lock);
|
||||
return 0;
|
||||
}
|
||||
|
@ -133,17 +135,17 @@ evthread_win32_condvar_alloc(unsigned condflags)
|
|||
}
|
||||
|
||||
static void
|
||||
evthread_win32_condvar_free(void *_cond)
|
||||
evthread_win32_condvar_free(void *cond_)
|
||||
{
|
||||
CONDITION_VARIABLE *cond = _cond;
|
||||
CONDITION_VARIABLE *cond = cond_;
|
||||
/* There doesn't _seem_ to be a cleaup fn here... */
|
||||
mm_free(cond);
|
||||
}
|
||||
|
||||
static int
|
||||
evthread_win32_condvar_signal(void *_cond, int broadcast)
|
||||
evthread_win32_condvar_signal(void *cond, int broadcast)
|
||||
{
|
||||
CONDITION_VARIABLE *cond = _cond;
|
||||
CONDITION_VARIABLE *cond = cond_;
|
||||
if (broadcast)
|
||||
WakeAllConditionVariable_fn(cond);
|
||||
else
|
||||
|
@ -152,15 +154,15 @@ evthread_win32_condvar_signal(void *_cond, int broadcast)
|
|||
}
|
||||
|
||||
static int
|
||||
evthread_win32_condvar_wait(void *_cond, void *_lock, const struct timeval *tv)
|
||||
evthread_win32_condvar_wait(void *cond_, void *lock_, const struct timeval *tv)
|
||||
{
|
||||
CONDITION_VARIABLE *cond = _cond;
|
||||
CRITICAL_SECTION *lock = _lock;
|
||||
CONDITION_VARIABLE *cond = cond_;
|
||||
CRITICAL_SECTION *lock = lock_;
|
||||
DWORD ms, err;
|
||||
BOOL result;
|
||||
|
||||
if (tv)
|
||||
ms = evutil_tv_to_msec(tv);
|
||||
ms = evutil_tv_to_msec_(tv);
|
||||
else
|
||||
ms = INFINITE;
|
||||
result = SleepConditionVariableCS_fn(cond, lock, ms);
|
||||
|
@ -204,18 +206,18 @@ evthread_win32_cond_alloc(unsigned flags)
|
|||
}
|
||||
|
||||
static void
|
||||
evthread_win32_cond_free(void *_cond)
|
||||
evthread_win32_cond_free(void *cond_)
|
||||
{
|
||||
struct evthread_win32_cond *cond = _cond;
|
||||
struct evthread_win32_cond *cond = cond_;
|
||||
DeleteCriticalSection(&cond->lock);
|
||||
CloseHandle(cond->event);
|
||||
mm_free(cond);
|
||||
}
|
||||
|
||||
static int
|
||||
evthread_win32_cond_signal(void *_cond, int broadcast)
|
||||
evthread_win32_cond_signal(void *cond_, int broadcast)
|
||||
{
|
||||
struct evthread_win32_cond *cond = _cond;
|
||||
struct evthread_win32_cond *cond = cond_;
|
||||
EnterCriticalSection(&cond->lock);
|
||||
if (broadcast)
|
||||
cond->n_to_wake = cond->n_waiting;
|
||||
|
@ -228,16 +230,16 @@ evthread_win32_cond_signal(void *_cond, int broadcast)
|
|||
}
|
||||
|
||||
static int
|
||||
evthread_win32_cond_wait(void *_cond, void *_lock, const struct timeval *tv)
|
||||
evthread_win32_cond_wait(void *cond_, void *lock_, const struct timeval *tv)
|
||||
{
|
||||
struct evthread_win32_cond *cond = _cond;
|
||||
CRITICAL_SECTION *lock = _lock;
|
||||
struct evthread_win32_cond *cond = cond_;
|
||||
CRITICAL_SECTION *lock = lock_;
|
||||
int generation_at_start;
|
||||
int waiting = 1;
|
||||
int result = -1;
|
||||
DWORD ms = INFINITE, ms_orig = INFINITE, startTime, endTime;
|
||||
if (tv)
|
||||
ms_orig = ms = evutil_tv_to_msec(tv);
|
||||
ms_orig = ms = evutil_tv_to_msec_(tv);
|
||||
|
||||
EnterCriticalSection(&cond->lock);
|
||||
++cond->n_waiting;
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -33,13 +33,14 @@
|
|||
*/
|
||||
|
||||
#include "event2/event-config.h"
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "util-internal.h"
|
||||
#include "evthread-internal.h"
|
||||
|
||||
#ifdef _EVENT_HAVE_ARC4RANDOM
|
||||
#ifdef EVENT__HAVE_ARC4RANDOM
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
int
|
||||
|
@ -55,22 +56,28 @@ evutil_secure_rng_init(void)
|
|||
(void) arc4random();
|
||||
return 0;
|
||||
}
|
||||
#ifndef EVENT__DISABLE_THREAD_SUPPORT
|
||||
int
|
||||
evutil_secure_rng_global_setup_locks_(const int enable_locks)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
static void
|
||||
evutil_free_secure_rng_globals_locks(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
ev_arc4random_buf(void *buf, size_t n)
|
||||
{
|
||||
#if defined(_EVENT_HAVE_ARC4RANDOM_BUF) && !defined(__APPLE__)
|
||||
#if defined(EVENT__HAVE_ARC4RANDOM_BUF) && !defined(__APPLE__)
|
||||
arc4random_buf(buf, n);
|
||||
return;
|
||||
#else
|
||||
unsigned char *b = buf;
|
||||
|
||||
#if defined(_EVENT_HAVE_ARC4RANDOM_BUF)
|
||||
#if defined(EVENT__HAVE_ARC4RANDOM_BUF)
|
||||
/* OSX 10.7 introducd arc4random_buf, so if you build your program
|
||||
* there, you'll get surprised when older versions of OSX fail to run.
|
||||
* To solve this, we can check whether the function pointer is set,
|
||||
|
@ -81,7 +88,8 @@ ev_arc4random_buf(void *buf, size_t n)
|
|||
void (*tptr)(void *,size_t) =
|
||||
(void (*)(void*,size_t))arc4random_buf;
|
||||
if (tptr != NULL) {
|
||||
return arc4random_buf(buf, n);
|
||||
arc4random_buf(buf, n);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -106,15 +114,15 @@ ev_arc4random_buf(void *buf, size_t n)
|
|||
#endif
|
||||
}
|
||||
|
||||
#else /* !_EVENT_HAVE_ARC4RANDOM { */
|
||||
#else /* !EVENT__HAVE_ARC4RANDOM { */
|
||||
|
||||
#ifdef _EVENT_ssize_t
|
||||
#define ssize_t _EVENT_SSIZE_t
|
||||
#ifdef EVENT__ssize_t
|
||||
#define ssize_t EVENT__ssize_t
|
||||
#endif
|
||||
#define ARC4RANDOM_EXPORT static
|
||||
#define _ARC4_LOCK() EVLOCK_LOCK(arc4rand_lock, 0)
|
||||
#define _ARC4_UNLOCK() EVLOCK_UNLOCK(arc4rand_lock, 0)
|
||||
#ifndef _EVENT_DISABLE_THREAD_SUPPORT
|
||||
#define ARC4_LOCK_() EVLOCK_LOCK(arc4rand_lock, 0)
|
||||
#define ARC4_UNLOCK_() EVLOCK_UNLOCK(arc4rand_lock, 0)
|
||||
#ifndef EVENT__DISABLE_THREAD_SUPPORT
|
||||
static void *arc4rand_lock;
|
||||
#endif
|
||||
|
||||
|
@ -125,7 +133,7 @@ static void *arc4rand_lock;
|
|||
|
||||
#include "./arc4random.c"
|
||||
|
||||
#ifndef _EVENT_DISABLE_THREAD_SUPPORT
|
||||
#ifndef EVENT__DISABLE_THREAD_SUPPORT
|
||||
int
|
||||
evutil_secure_rng_global_setup_locks_(const int enable_locks)
|
||||
{
|
||||
|
@ -134,13 +142,25 @@ evutil_secure_rng_global_setup_locks_(const int enable_locks)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
evutil_free_secure_rng_globals_locks(void)
|
||||
{
|
||||
#ifndef EVENT__DISABLE_THREAD_SUPPORT
|
||||
if (arc4rand_lock != NULL) {
|
||||
EVTHREAD_FREE_LOCK(arc4rand_lock, 0);
|
||||
arc4rand_lock = NULL;
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
evutil_secure_rng_set_urandom_device_file(char *fname)
|
||||
{
|
||||
#ifdef TRY_SEED_URANDOM
|
||||
_ARC4_LOCK();
|
||||
ARC4_LOCK_();
|
||||
arc4random_urandom_filename = fname;
|
||||
_ARC4_UNLOCK();
|
||||
ARC4_UNLOCK_();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
@ -150,11 +170,11 @@ evutil_secure_rng_init(void)
|
|||
{
|
||||
int val;
|
||||
|
||||
_ARC4_LOCK();
|
||||
ARC4_LOCK_();
|
||||
if (!arc4_seeded_ok)
|
||||
arc4_stir();
|
||||
val = arc4_seeded_ok ? 0 : -1;
|
||||
_ARC4_UNLOCK();
|
||||
ARC4_UNLOCK_();
|
||||
return val;
|
||||
}
|
||||
|
||||
|
@ -164,7 +184,7 @@ ev_arc4random_buf(void *buf, size_t n)
|
|||
arc4random_buf(buf, n);
|
||||
}
|
||||
|
||||
#endif /* } !_EVENT_HAVE_ARC4RANDOM */
|
||||
#endif /* } !EVENT__HAVE_ARC4RANDOM */
|
||||
|
||||
void
|
||||
evutil_secure_rng_get_bytes(void *buf, size_t n)
|
||||
|
@ -180,3 +200,9 @@ evutil_secure_rng_add_bytes(const char *buf, size_t n)
|
|||
n>(size_t)INT_MAX ? INT_MAX : (int)n);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
evutil_free_secure_rng_globals_(void)
|
||||
{
|
||||
evutil_free_secure_rng_globals_locks();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,576 @@
|
|||
/*
|
||||
* Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "event2/event-config.h"
|
||||
#include "evconfig-private.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef EVENT__HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#ifndef EVENT__HAVE_GETTIMEOFDAY
|
||||
#include <sys/timeb.h>
|
||||
#endif
|
||||
#if !defined(EVENT__HAVE_NANOSLEEP) && !defined(EVENT_HAVE_USLEEP) && \
|
||||
!defined(_WIN32)
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
|
||||
/** evutil_usleep_() */
|
||||
#if defined(_WIN32)
|
||||
#elif defined(EVENT__HAVE_NANOSLEEP)
|
||||
#elif defined(EVENT__HAVE_USLEEP)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "event2/util.h"
|
||||
#include "util-internal.h"
|
||||
#include "log-internal.h"
|
||||
#include "mm-internal.h"
|
||||
|
||||
#ifndef EVENT__HAVE_GETTIMEOFDAY
|
||||
/* No gettimeofday; this must be windows. */
|
||||
int
|
||||
evutil_gettimeofday(struct timeval *tv, struct timezone *tz)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
#define U64_LITERAL(n) n##ui64
|
||||
#else
|
||||
#define U64_LITERAL(n) n##llu
|
||||
#endif
|
||||
|
||||
/* Conversion logic taken from Tor, which in turn took it
|
||||
* from Perl. GetSystemTimeAsFileTime returns its value as
|
||||
* an unaligned (!) 64-bit value containing the number of
|
||||
* 100-nanosecond intervals since 1 January 1601 UTC. */
|
||||
#define EPOCH_BIAS U64_LITERAL(116444736000000000)
|
||||
#define UNITS_PER_SEC U64_LITERAL(10000000)
|
||||
#define USEC_PER_SEC U64_LITERAL(1000000)
|
||||
#define UNITS_PER_USEC U64_LITERAL(10)
|
||||
union {
|
||||
FILETIME ft_ft;
|
||||
ev_uint64_t ft_64;
|
||||
} ft;
|
||||
|
||||
if (tv == NULL)
|
||||
return -1;
|
||||
|
||||
GetSystemTimeAsFileTime(&ft.ft_ft);
|
||||
|
||||
if (EVUTIL_UNLIKELY(ft.ft_64 < EPOCH_BIAS)) {
|
||||
/* Time before the unix epoch. */
|
||||
return -1;
|
||||
}
|
||||
ft.ft_64 -= EPOCH_BIAS;
|
||||
tv->tv_sec = (long) (ft.ft_64 / UNITS_PER_SEC);
|
||||
tv->tv_usec = (long) ((ft.ft_64 / UNITS_PER_USEC) % USEC_PER_SEC);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define MAX_SECONDS_IN_MSEC_LONG \
|
||||
(((LONG_MAX) - 999) / 1000)
|
||||
|
||||
long
|
||||
evutil_tv_to_msec_(const struct timeval *tv)
|
||||
{
|
||||
if (tv->tv_usec > 1000000 || tv->tv_sec > MAX_SECONDS_IN_MSEC_LONG)
|
||||
return -1;
|
||||
|
||||
return (tv->tv_sec * 1000) + ((tv->tv_usec + 999) / 1000);
|
||||
}
|
||||
|
||||
/*
|
||||
Replacement for usleep on platforms that don't have one. Not guaranteed to
|
||||
be any more finegrained than 1 msec.
|
||||
*/
|
||||
void
|
||||
evutil_usleep_(const struct timeval *tv)
|
||||
{
|
||||
if (!tv)
|
||||
return;
|
||||
#if defined(_WIN32)
|
||||
{
|
||||
long msec = evutil_tv_to_msec_(tv);
|
||||
Sleep((DWORD)msec);
|
||||
}
|
||||
#elif defined(EVENT__HAVE_NANOSLEEP)
|
||||
{
|
||||
struct timespec ts;
|
||||
ts.tv_sec = tv->tv_sec;
|
||||
ts.tv_nsec = tv->tv_usec*1000;
|
||||
nanosleep(&ts, NULL);
|
||||
}
|
||||
#elif defined(EVENT__HAVE_USLEEP)
|
||||
/* Some systems don't like to usleep more than 999999 usec */
|
||||
sleep(tv->tv_sec);
|
||||
usleep(tv->tv_usec);
|
||||
#else
|
||||
select(0, NULL, NULL, NULL, tv);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
evutil_date_rfc1123(char *date, const size_t datelen, const struct tm *tm)
|
||||
{
|
||||
static const char *DAYS[] =
|
||||
{ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
|
||||
static const char *MONTHS[] =
|
||||
{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
||||
|
||||
time_t t = time(NULL);
|
||||
|
||||
#ifndef _WIN32
|
||||
struct tm sys;
|
||||
#endif
|
||||
|
||||
/* If `tm` is null, set system's current time. */
|
||||
if (tm == NULL) {
|
||||
#ifdef _WIN32
|
||||
/** TODO: detect _gmtime64()/_gmtime64_s() */
|
||||
tm = gmtime(&t);
|
||||
#else
|
||||
gmtime_r(&t, &sys);
|
||||
tm = &sys;
|
||||
#endif
|
||||
}
|
||||
|
||||
return evutil_snprintf(
|
||||
date, datelen, "%s, %02d %s %4d %02d:%02d:%02d GMT",
|
||||
DAYS[tm->tm_wday], tm->tm_mday, MONTHS[tm->tm_mon],
|
||||
1900 + tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
}
|
||||
|
||||
/*
|
||||
This function assumes it's called repeatedly with a
|
||||
not-actually-so-monotonic time source whose outputs are in 'tv'. It
|
||||
implements a trivial ratcheting mechanism so that the values never go
|
||||
backwards.
|
||||
*/
|
||||
static void
|
||||
adjust_monotonic_time(struct evutil_monotonic_timer *base,
|
||||
struct timeval *tv)
|
||||
{
|
||||
evutil_timeradd(tv, &base->adjust_monotonic_clock, tv);
|
||||
|
||||
if (evutil_timercmp(tv, &base->last_time, <)) {
|
||||
/* Guess it wasn't monotonic after all. */
|
||||
struct timeval adjust;
|
||||
evutil_timersub(&base->last_time, tv, &adjust);
|
||||
evutil_timeradd(&adjust, &base->adjust_monotonic_clock,
|
||||
&base->adjust_monotonic_clock);
|
||||
*tv = base->last_time;
|
||||
}
|
||||
base->last_time = *tv;
|
||||
}
|
||||
|
||||
/*
|
||||
Allocate a new struct evutil_monotonic_timer
|
||||
*/
|
||||
struct evutil_monotonic_timer *
|
||||
evutil_monotonic_timer_new(void)
|
||||
{
|
||||
struct evutil_monotonic_timer *p = NULL;
|
||||
|
||||
p = mm_malloc(sizeof(*p));
|
||||
if (!p) goto done;
|
||||
|
||||
memset(p, 0, sizeof(*p));
|
||||
|
||||
done:
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
Free a struct evutil_monotonic_timer
|
||||
*/
|
||||
void
|
||||
evutil_monotonic_timer_free(struct evutil_monotonic_timer *timer)
|
||||
{
|
||||
if (timer) {
|
||||
mm_free(timer);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Set up a struct evutil_monotonic_timer for initial use
|
||||
*/
|
||||
int
|
||||
evutil_configure_monotonic_time(struct evutil_monotonic_timer *timer,
|
||||
int flags)
|
||||
{
|
||||
return evutil_configure_monotonic_time_(timer, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
Query the current monotonic time
|
||||
*/
|
||||
int
|
||||
evutil_gettime_monotonic(struct evutil_monotonic_timer *timer,
|
||||
struct timeval *tp)
|
||||
{
|
||||
return evutil_gettime_monotonic_(timer, tp);
|
||||
}
|
||||
|
||||
|
||||
#if defined(HAVE_POSIX_MONOTONIC)
|
||||
/* =====
|
||||
The POSIX clock_gettime() interface provides a few ways to get at a
|
||||
monotonic clock. CLOCK_MONOTONIC is most widely supported. Linux also
|
||||
provides a CLOCK_MONOTONIC_COARSE with accuracy of about 1-4 msec.
|
||||
|
||||
On all platforms I'm aware of, CLOCK_MONOTONIC really is monotonic.
|
||||
Platforms don't agree about whether it should jump on a sleep/resume.
|
||||
*/
|
||||
|
||||
int
|
||||
evutil_configure_monotonic_time_(struct evutil_monotonic_timer *base,
|
||||
int flags)
|
||||
{
|
||||
/* CLOCK_MONOTONIC exists on FreeBSD, Linux, and Solaris. You need to
|
||||
* check for it at runtime, because some older kernel versions won't
|
||||
* have it working. */
|
||||
#ifdef CLOCK_MONOTONIC_COARSE
|
||||
const int precise = flags & EV_MONOT_PRECISE;
|
||||
#endif
|
||||
const int fallback = flags & EV_MONOT_FALLBACK;
|
||||
struct timespec ts;
|
||||
|
||||
#ifdef CLOCK_MONOTONIC_COARSE
|
||||
if (CLOCK_MONOTONIC_COARSE < 0) {
|
||||
/* Technically speaking, nothing keeps CLOCK_* from being
|
||||
* negative (as far as I know). This check and the one below
|
||||
* make sure that it's safe for us to use -1 as an "unset"
|
||||
* value. */
|
||||
event_errx(1,"I didn't expect CLOCK_MONOTONIC_COARSE to be < 0");
|
||||
}
|
||||
if (! precise && ! fallback) {
|
||||
if (clock_gettime(CLOCK_MONOTONIC_COARSE, &ts) == 0) {
|
||||
base->monotonic_clock = CLOCK_MONOTONIC_COARSE;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!fallback && clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
|
||||
base->monotonic_clock = CLOCK_MONOTONIC;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (CLOCK_MONOTONIC < 0) {
|
||||
event_errx(1,"I didn't expect CLOCK_MONOTONIC to be < 0");
|
||||
}
|
||||
|
||||
base->monotonic_clock = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
evutil_gettime_monotonic_(struct evutil_monotonic_timer *base,
|
||||
struct timeval *tp)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
if (base->monotonic_clock < 0) {
|
||||
if (evutil_gettimeofday(tp, NULL) < 0)
|
||||
return -1;
|
||||
adjust_monotonic_time(base, tp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (clock_gettime(base->monotonic_clock, &ts) == -1)
|
||||
return -1;
|
||||
tp->tv_sec = ts.tv_sec;
|
||||
tp->tv_usec = ts.tv_nsec / 1000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_MACH_MONOTONIC)
|
||||
/* ======
|
||||
Apple is a little late to the POSIX party. And why not? Instead of
|
||||
clock_gettime(), they provide mach_absolute_time(). Its units are not
|
||||
fixed; we need to use mach_timebase_info() to get the right functions to
|
||||
convert its units into nanoseconds.
|
||||
|
||||
To all appearances, mach_absolute_time() seems to be honest-to-goodness
|
||||
monotonic. Whether it stops during sleep or not is unspecified in
|
||||
principle, and dependent on CPU architecture in practice.
|
||||
*/
|
||||
|
||||
int
|
||||
evutil_configure_monotonic_time_(struct evutil_monotonic_timer *base,
|
||||
int flags)
|
||||
{
|
||||
const int fallback = flags & EV_MONOT_FALLBACK;
|
||||
struct mach_timebase_info mi;
|
||||
memset(base, 0, sizeof(*base));
|
||||
/* OSX has mach_absolute_time() */
|
||||
if (!fallback &&
|
||||
mach_timebase_info(&mi) == 0 &&
|
||||
mach_absolute_time() != 0) {
|
||||
/* mach_timebase_info tells us how to convert
|
||||
* mach_absolute_time() into nanoseconds, but we
|
||||
* want to use microseconds instead. */
|
||||
mi.denom *= 1000;
|
||||
memcpy(&base->mach_timebase_units, &mi, sizeof(mi));
|
||||
} else {
|
||||
base->mach_timebase_units.numer = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
evutil_gettime_monotonic_(struct evutil_monotonic_timer *base,
|
||||
struct timeval *tp)
|
||||
{
|
||||
ev_uint64_t abstime, usec;
|
||||
if (base->mach_timebase_units.numer == 0) {
|
||||
if (evutil_gettimeofday(tp, NULL) < 0)
|
||||
return -1;
|
||||
adjust_monotonic_time(base, tp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
abstime = mach_absolute_time();
|
||||
usec = (abstime * base->mach_timebase_units.numer)
|
||||
/ (base->mach_timebase_units.denom);
|
||||
tp->tv_sec = usec / 1000000;
|
||||
tp->tv_usec = usec % 1000000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_WIN32_MONOTONIC)
|
||||
/* =====
|
||||
Turn we now to Windows. Want monontonic time on Windows?
|
||||
|
||||
Windows has QueryPerformanceCounter(), which gives time most high-
|
||||
resolution time. It's a pity it's not so monotonic in practice; it's
|
||||
also got some fun bugs, especially: with older Windowses, under
|
||||
virtualizations, with funny hardware, on multiprocessor systems, and so
|
||||
on. PEP418 [1] has a nice roundup of the issues here.
|
||||
|
||||
There's GetTickCount64() on Vista and later, which gives a number of 1-msec
|
||||
ticks since startup. The accuracy here might be as bad as 10-20 msec, I
|
||||
hear. There's an undocumented function (NtSetTimerResolution) that
|
||||
allegedly increases the accuracy. Good luck!
|
||||
|
||||
There's also GetTickCount(), which is only 32 bits, but seems to be
|
||||
supported on pre-Vista versions of Windows. Apparently, you can coax
|
||||
another 14 bits out of it, giving you 2231 years before rollover.
|
||||
|
||||
The less said about timeGetTime() the better.
|
||||
|
||||
"We don't care. We don't have to. We're the Phone Company."
|
||||
-- Lily Tomlin, SNL
|
||||
|
||||
Our strategy, if precise timers are turned off, is to just use the best
|
||||
GetTickCount equivalent available. If we've been asked for precise timing,
|
||||
then we mostly[2] assume that GetTickCount is monotonic, and correct
|
||||
GetPerformanceCounter to approximate it.
|
||||
|
||||
[1] http://www.python.org/dev/peps/pep-0418
|
||||
[2] Of course, we feed the Windows stuff into adjust_monotonic_time()
|
||||
anyway, just in case it isn't.
|
||||
|
||||
*/
|
||||
/*
|
||||
Parts of our logic in the win32 timer code here are closely based on
|
||||
BitTorrent's libUTP library. That code is subject to the following
|
||||
license:
|
||||
|
||||
Copyright (c) 2010 BitTorrent, 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.
|
||||
*/
|
||||
|
||||
static ev_uint64_t
|
||||
evutil_GetTickCount_(struct evutil_monotonic_timer *base)
|
||||
{
|
||||
if (base->GetTickCount64_fn) {
|
||||
/* Let's just use GetTickCount64 if we can. */
|
||||
return base->GetTickCount64_fn();
|
||||
} else if (base->GetTickCount_fn) {
|
||||
/* Greg Hazel assures me that this works, that BitTorrent has
|
||||
* done it for years, and this it won't turn around and
|
||||
* bite us. He says they found it on some game programmers'
|
||||
* forum some time around 2007.
|
||||
*/
|
||||
ev_uint64_t v = base->GetTickCount_fn();
|
||||
return (DWORD)v | ((v >> 18) & 0xFFFFFFFF00000000);
|
||||
} else {
|
||||
/* Here's the fallback implementation. We have to use
|
||||
* GetTickCount() with its given signature, so we only get
|
||||
* 32 bits worth of milliseconds, which will roll ove every
|
||||
* 49 days or so. */
|
||||
DWORD ticks = GetTickCount();
|
||||
if (ticks < base->last_tick_count) {
|
||||
base->adjust_tick_count += ((ev_uint64_t)1) << 32;
|
||||
}
|
||||
base->last_tick_count = ticks;
|
||||
return ticks + base->adjust_tick_count;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
evutil_configure_monotonic_time_(struct evutil_monotonic_timer *base,
|
||||
int flags)
|
||||
{
|
||||
const int precise = flags & EV_MONOT_PRECISE;
|
||||
const int fallback = flags & EV_MONOT_FALLBACK;
|
||||
HANDLE h;
|
||||
memset(base, 0, sizeof(*base));
|
||||
|
||||
h = evutil_load_windows_system_library_(TEXT("kernel32.dll"));
|
||||
if (h != NULL && !fallback) {
|
||||
base->GetTickCount64_fn = (ev_GetTickCount_func)GetProcAddress(h, "GetTickCount64");
|
||||
base->GetTickCount_fn = (ev_GetTickCount_func)GetProcAddress(h, "GetTickCount");
|
||||
}
|
||||
|
||||
base->first_tick = base->last_tick_count = evutil_GetTickCount_(base);
|
||||
if (precise && !fallback) {
|
||||
LARGE_INTEGER freq;
|
||||
if (QueryPerformanceFrequency(&freq)) {
|
||||
LARGE_INTEGER counter;
|
||||
QueryPerformanceCounter(&counter);
|
||||
base->first_counter = counter.QuadPart;
|
||||
base->usec_per_count = 1.0e6 / freq.QuadPart;
|
||||
base->use_performance_counter = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline ev_int64_t
|
||||
abs64(ev_int64_t i)
|
||||
{
|
||||
return i < 0 ? -i : i;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
evutil_gettime_monotonic_(struct evutil_monotonic_timer *base,
|
||||
struct timeval *tp)
|
||||
{
|
||||
ev_uint64_t ticks = evutil_GetTickCount_(base);
|
||||
if (base->use_performance_counter) {
|
||||
/* Here's a trick we took from BitTorrent's libutp, at Greg
|
||||
* Hazel's recommendation. We use QueryPerformanceCounter for
|
||||
* our high-resolution timer, but use GetTickCount*() to keep
|
||||
* it sane, and adjust_monotonic_time() to keep it monotonic.
|
||||
*/
|
||||
LARGE_INTEGER counter;
|
||||
ev_int64_t counter_elapsed, counter_usec_elapsed, ticks_elapsed;
|
||||
QueryPerformanceCounter(&counter);
|
||||
counter_elapsed = (ev_int64_t)
|
||||
(counter.QuadPart - base->first_counter);
|
||||
ticks_elapsed = ticks - base->first_tick;
|
||||
/* TODO: This may upset VC6. If you need this to work with
|
||||
* VC6, please supply an appropriate patch. */
|
||||
counter_usec_elapsed = (ev_int64_t)
|
||||
(counter_elapsed * base->usec_per_count);
|
||||
|
||||
if (abs64(ticks_elapsed*1000 - counter_usec_elapsed) > 1000000) {
|
||||
/* It appears that the QueryPerformanceCounter()
|
||||
* result is more than 1 second away from
|
||||
* GetTickCount() result. Let's adjust it to be as
|
||||
* accurate as we can; adjust_monotnonic_time() below
|
||||
* will keep it monotonic. */
|
||||
counter_usec_elapsed = ticks_elapsed * 1000;
|
||||
base->first_counter = (ev_uint64_t) (counter.QuadPart - counter_usec_elapsed / base->usec_per_count);
|
||||
}
|
||||
tp->tv_sec = (time_t) (counter_usec_elapsed / 1000000);
|
||||
tp->tv_usec = counter_usec_elapsed % 1000000;
|
||||
|
||||
} else {
|
||||
/* We're just using GetTickCount(). */
|
||||
tp->tv_sec = (time_t) (ticks / 1000);
|
||||
tp->tv_usec = (ticks % 1000) * 1000;
|
||||
}
|
||||
adjust_monotonic_time(base, tp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_FALLBACK_MONOTONIC)
|
||||
/* =====
|
||||
And if none of the other options work, let's just use gettimeofday(), and
|
||||
ratchet it forward so that it acts like a monotonic timer, whether it
|
||||
wants to or not.
|
||||
*/
|
||||
|
||||
int
|
||||
evutil_configure_monotonic_time_(struct evutil_monotonic_timer *base,
|
||||
int precise)
|
||||
{
|
||||
memset(base, 0, sizeof(*base));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
evutil_gettime_monotonic_(struct evutil_monotonic_timer *base,
|
||||
struct timeval *tp)
|
||||
{
|
||||
if (evutil_gettimeofday(tp, NULL) < 0)
|
||||
return -1;
|
||||
adjust_monotonic_time(base, tp);
|
||||
return 0;
|
||||
|
||||
}
|
||||
#endif
|
|
@ -1,12 +1,12 @@
|
|||
/* Based on work Copyright 2002 Christopher Clark */
|
||||
/* Copyright 2002 Christopher Clark */
|
||||
/* Copyright 2005-2012 Nick Mathewson */
|
||||
/* Copyright 2009-2012 Niels Provos and Nick Mathewson */
|
||||
/* See license at end. */
|
||||
|
||||
/* Based on ideas by Christopher Clark and interfaces from Niels Provos. */
|
||||
|
||||
#ifndef _EVENT_HT_H
|
||||
#define _EVENT_HT_H
|
||||
#ifndef HT_INTERNAL_H_INCLUDED_
|
||||
#define HT_INTERNAL_H_INCLUDED_
|
||||
|
||||
#define HT_HEAD(name, type) \
|
||||
struct name { \
|
||||
|
@ -25,16 +25,16 @@
|
|||
#define HT_INITIALIZER() \
|
||||
{ NULL, 0, 0, 0, -1 }
|
||||
|
||||
#ifdef HT_CACHE_HASH_VALUES
|
||||
#ifdef HT_NO_CACHE_HASH_VALUES
|
||||
#define HT_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *hte_next; \
|
||||
unsigned hte_hash; \
|
||||
}
|
||||
#else
|
||||
#define HT_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *hte_next; \
|
||||
unsigned hte_hash; \
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -45,6 +45,10 @@
|
|||
#define HT_SIZE(head) \
|
||||
((head)->hth_n_entries)
|
||||
|
||||
/* Return memory usage for a hashtable (not counting the entries themselves) */
|
||||
#define HT_MEM_USAGE(head) \
|
||||
(sizeof(*head) + (head)->hth_table_length * sizeof(void*))
|
||||
|
||||
#define HT_FIND(name, head, elm) name##_HT_FIND((head), (elm))
|
||||
#define HT_INSERT(name, head, elm) name##_HT_INSERT((head), (elm))
|
||||
#define HT_REPLACE(name, head, elm) name##_HT_REPLACE((head), (elm))
|
||||
|
@ -56,7 +60,7 @@
|
|||
#define HT_INIT(name, head) name##_HT_INIT(head)
|
||||
/* Helper: */
|
||||
static inline unsigned
|
||||
ht_improve_hash(unsigned h)
|
||||
ht_improve_hash_(unsigned h)
|
||||
{
|
||||
/* Aim to protect against poor hash functions by adding logic here
|
||||
* - logic taken from java 1.4 hashtable source */
|
||||
|
@ -70,7 +74,7 @@ ht_improve_hash(unsigned h)
|
|||
#if 0
|
||||
/** Basic string hash function, from Java standard String.hashCode(). */
|
||||
static inline unsigned
|
||||
ht_string_hash(const char *s)
|
||||
ht_string_hash_(const char *s)
|
||||
{
|
||||
unsigned h = 0;
|
||||
int m = 1;
|
||||
|
@ -84,7 +88,7 @@ ht_string_hash(const char *s)
|
|||
|
||||
/** Basic string hash function, from Python's str.__hash__() */
|
||||
static inline unsigned
|
||||
ht_string_hash(const char *s)
|
||||
ht_string_hash_(const char *s)
|
||||
{
|
||||
unsigned h;
|
||||
const unsigned char *cp = (const unsigned char *)s;
|
||||
|
@ -97,25 +101,25 @@ ht_string_hash(const char *s)
|
|||
return h;
|
||||
}
|
||||
|
||||
#ifdef HT_CACHE_HASH_VALUES
|
||||
#define _HT_SET_HASH(elm, field, hashfn) \
|
||||
#ifndef HT_NO_CACHE_HASH_VALUES
|
||||
#define HT_SET_HASH_(elm, field, hashfn) \
|
||||
do { (elm)->field.hte_hash = hashfn(elm); } while (0)
|
||||
#define _HT_SET_HASHVAL(elm, field, val) \
|
||||
#define HT_SET_HASHVAL_(elm, field, val) \
|
||||
do { (elm)->field.hte_hash = (val); } while (0)
|
||||
#define _HT_ELT_HASH(elm, field, hashfn) \
|
||||
#define HT_ELT_HASH_(elm, field, hashfn) \
|
||||
((elm)->field.hte_hash)
|
||||
#else
|
||||
#define _HT_SET_HASH(elm, field, hashfn) \
|
||||
#define HT_SET_HASH_(elm, field, hashfn) \
|
||||
((void)0)
|
||||
#define _HT_ELT_HASH(elm, field, hashfn) \
|
||||
#define HT_ELT_HASH_(elm, field, hashfn) \
|
||||
(hashfn(elm))
|
||||
#define _HT_SET_HASHVAL(elm, field, val) \
|
||||
#define HT_SET_HASHVAL_(elm, field, val) \
|
||||
((void)0)
|
||||
#endif
|
||||
|
||||
/* Helper: alias for the bucket containing 'elm'. */
|
||||
#define _HT_BUCKET(head, field, elm, hashfn) \
|
||||
((head)->hth_table[_HT_ELT_HASH(elm,field,hashfn) % head->hth_table_length])
|
||||
#define HT_BUCKET_(head, field, elm, hashfn) \
|
||||
((head)->hth_table[HT_ELT_HASH_(elm,field,hashfn) % head->hth_table_length])
|
||||
|
||||
#define HT_FOREACH(x, name, head) \
|
||||
for ((x) = HT_START(name, head); \
|
||||
|
@ -125,7 +129,7 @@ ht_string_hash(const char *s)
|
|||
#define HT_PROTOTYPE(name, type, field, hashfn, eqfn) \
|
||||
int name##_HT_GROW(struct name *ht, unsigned min_capacity); \
|
||||
void name##_HT_CLEAR(struct name *ht); \
|
||||
int _##name##_HT_REP_IS_BAD(const struct name *ht); \
|
||||
int name##_HT_REP_IS_BAD_(const struct name *ht); \
|
||||
static inline void \
|
||||
name##_HT_INIT(struct name *head) { \
|
||||
head->hth_table_length = 0; \
|
||||
|
@ -137,12 +141,12 @@ ht_string_hash(const char *s)
|
|||
/* Helper: returns a pointer to the right location in the table \
|
||||
* 'head' to find or insert the element 'elm'. */ \
|
||||
static inline struct type ** \
|
||||
_##name##_HT_FIND_P(struct name *head, struct type *elm) \
|
||||
name##_HT_FIND_P_(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type **p; \
|
||||
if (!head->hth_table) \
|
||||
return NULL; \
|
||||
p = &_HT_BUCKET(head, field, elm, hashfn); \
|
||||
p = &HT_BUCKET_(head, field, elm, hashfn); \
|
||||
while (*p) { \
|
||||
if (eqfn(*p, elm)) \
|
||||
return p; \
|
||||
|
@ -157,8 +161,8 @@ ht_string_hash(const char *s)
|
|||
{ \
|
||||
struct type **p; \
|
||||
struct name *h = (struct name *) head; \
|
||||
_HT_SET_HASH(elm, field, hashfn); \
|
||||
p = _##name##_HT_FIND_P(h, elm); \
|
||||
HT_SET_HASH_(elm, field, hashfn); \
|
||||
p = name##_HT_FIND_P_(h, elm); \
|
||||
return p ? *p : NULL; \
|
||||
} \
|
||||
/* Insert the element 'elm' into the table 'head'. Do not call this \
|
||||
|
@ -170,8 +174,8 @@ ht_string_hash(const char *s)
|
|||
if (!head->hth_table || head->hth_n_entries >= head->hth_load_limit) \
|
||||
name##_HT_GROW(head, head->hth_n_entries+1); \
|
||||
++head->hth_n_entries; \
|
||||
_HT_SET_HASH(elm, field, hashfn); \
|
||||
p = &_HT_BUCKET(head, field, elm, hashfn); \
|
||||
HT_SET_HASH_(elm, field, hashfn); \
|
||||
p = &HT_BUCKET_(head, field, elm, hashfn); \
|
||||
elm->field.hte_next = *p; \
|
||||
*p = elm; \
|
||||
} \
|
||||
|
@ -184,8 +188,8 @@ ht_string_hash(const char *s)
|
|||
struct type **p, *r; \
|
||||
if (!head->hth_table || head->hth_n_entries >= head->hth_load_limit) \
|
||||
name##_HT_GROW(head, head->hth_n_entries+1); \
|
||||
_HT_SET_HASH(elm, field, hashfn); \
|
||||
p = _##name##_HT_FIND_P(head, elm); \
|
||||
HT_SET_HASH_(elm, field, hashfn); \
|
||||
p = name##_HT_FIND_P_(head, elm); \
|
||||
r = *p; \
|
||||
*p = elm; \
|
||||
if (r && (r!=elm)) { \
|
||||
|
@ -203,8 +207,8 @@ ht_string_hash(const char *s)
|
|||
name##_HT_REMOVE(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type **p, *r; \
|
||||
_HT_SET_HASH(elm, field, hashfn); \
|
||||
p = _##name##_HT_FIND_P(head,elm); \
|
||||
HT_SET_HASH_(elm, field, hashfn); \
|
||||
p = name##_HT_FIND_P_(head,elm); \
|
||||
if (!p || !*p) \
|
||||
return NULL; \
|
||||
r = *p; \
|
||||
|
@ -265,7 +269,7 @@ ht_string_hash(const char *s)
|
|||
if ((*elm)->field.hte_next) { \
|
||||
return &(*elm)->field.hte_next; \
|
||||
} else { \
|
||||
unsigned b = (_HT_ELT_HASH(*elm, field, hashfn) % head->hth_table_length)+1; \
|
||||
unsigned b = (HT_ELT_HASH_(*elm, field, hashfn) % head->hth_table_length)+1; \
|
||||
while (b < head->hth_table_length) { \
|
||||
if (head->hth_table[b]) \
|
||||
return &head->hth_table[b]; \
|
||||
|
@ -277,7 +281,7 @@ ht_string_hash(const char *s)
|
|||
static inline struct type ** \
|
||||
name##_HT_NEXT_RMV(struct name *head, struct type **elm) \
|
||||
{ \
|
||||
unsigned h = _HT_ELT_HASH(*elm, field, hashfn); \
|
||||
unsigned h = HT_ELT_HASH_(*elm, field, hashfn); \
|
||||
*elm = (*elm)->field.hte_next; \
|
||||
--head->hth_n_entries; \
|
||||
if (*elm) { \
|
||||
|
@ -334,7 +338,7 @@ ht_string_hash(const char *s)
|
|||
elm = head->hth_table[b]; \
|
||||
while (elm) { \
|
||||
next = elm->field.hte_next; \
|
||||
b2 = _HT_ELT_HASH(elm, field, hashfn) % new_len; \
|
||||
b2 = HT_ELT_HASH_(elm, field, hashfn) % new_len; \
|
||||
elm->field.hte_next = new_table[b2]; \
|
||||
new_table[b2] = elm; \
|
||||
elm = next; \
|
||||
|
@ -352,7 +356,7 @@ ht_string_hash(const char *s)
|
|||
for (b=0; b < head->hth_table_length; ++b) { \
|
||||
struct type *e, **pE; \
|
||||
for (pE = &new_table[b], e = *pE; e != NULL; e = *pE) { \
|
||||
b2 = _HT_ELT_HASH(e, field, hashfn) % new_len; \
|
||||
b2 = HT_ELT_HASH_(e, field, hashfn) % new_len; \
|
||||
if (b2 == b) { \
|
||||
pE = &e->field.hte_next; \
|
||||
} else { \
|
||||
|
@ -376,13 +380,12 @@ ht_string_hash(const char *s)
|
|||
{ \
|
||||
if (head->hth_table) \
|
||||
freefn(head->hth_table); \
|
||||
head->hth_table_length = 0; \
|
||||
name##_HT_INIT(head); \
|
||||
} \
|
||||
/* Debugging helper: return false iff the representation of 'head' is \
|
||||
* internally consistent. */ \
|
||||
int \
|
||||
_##name##_HT_REP_IS_BAD(const struct name *head) \
|
||||
name##_HT_REP_IS_BAD_(const struct name *head) \
|
||||
{ \
|
||||
unsigned n, i; \
|
||||
struct type *elm; \
|
||||
|
@ -404,9 +407,9 @@ ht_string_hash(const char *s)
|
|||
return 5; \
|
||||
for (n = i = 0; i < head->hth_table_length; ++i) { \
|
||||
for (elm = head->hth_table[i]; elm; elm = elm->field.hte_next) { \
|
||||
if (_HT_ELT_HASH(elm, field, hashfn) != hashfn(elm)) \
|
||||
if (HT_ELT_HASH_(elm, field, hashfn) != hashfn(elm)) \
|
||||
return 1000 + i; \
|
||||
if ((_HT_ELT_HASH(elm, field, hashfn) % head->hth_table_length) != i) \
|
||||
if ((HT_ELT_HASH_(elm, field, hashfn) % head->hth_table_length) != i) \
|
||||
return 10000 + i; \
|
||||
++n; \
|
||||
} \
|
||||
|
@ -419,24 +422,24 @@ ht_string_hash(const char *s)
|
|||
/** Implements an over-optimized "find and insert if absent" block;
|
||||
* not meant for direct usage by typical code, or usage outside the critical
|
||||
* path.*/
|
||||
#define _HT_FIND_OR_INSERT(name, field, hashfn, head, eltype, elm, var, y, n) \
|
||||
#define HT_FIND_OR_INSERT_(name, field, hashfn, head, eltype, elm, var, y, n) \
|
||||
{ \
|
||||
struct name *_##var##_head = head; \
|
||||
struct eltype **var; \
|
||||
if (!_##var##_head->hth_table || \
|
||||
_##var##_head->hth_n_entries >= _##var##_head->hth_load_limit) \
|
||||
name##_HT_GROW(_##var##_head, _##var##_head->hth_n_entries+1); \
|
||||
_HT_SET_HASH((elm), field, hashfn); \
|
||||
var = _##name##_HT_FIND_P(_##var##_head, (elm)); \
|
||||
struct name *var##_head_ = head; \
|
||||
struct eltype **var; \
|
||||
if (!var##_head_->hth_table || \
|
||||
var##_head_->hth_n_entries >= var##_head_->hth_load_limit) \
|
||||
name##_HT_GROW(var##_head_, var##_head_->hth_n_entries+1); \
|
||||
HT_SET_HASH_((elm), field, hashfn); \
|
||||
var = name##_HT_FIND_P_(var##_head_, (elm)); \
|
||||
if (*var) { \
|
||||
y; \
|
||||
} else { \
|
||||
n; \
|
||||
} \
|
||||
}
|
||||
#define _HT_FOI_INSERT(field, head, elm, newent, var) \
|
||||
#define HT_FOI_INSERT_(field, head, elm, newent, var) \
|
||||
{ \
|
||||
_HT_SET_HASHVAL(newent, field, (elm)->field.hte_hash); \
|
||||
HT_SET_HASHVAL_(newent, field, (elm)->field.hte_hash); \
|
||||
newent->field.hte_next = NULL; \
|
||||
*var = newent; \
|
||||
++((head)->hth_n_entries); \
|
||||
|
@ -444,7 +447,7 @@ ht_string_hash(const char *s)
|
|||
|
||||
/*
|
||||
* Copyright 2005, Nick Mathewson. Implementation logic is adapted from code
|
||||
* by Cristopher Clark, retrofit to allow drop-in memory management, and to
|
||||
* by Christopher Clark, retrofit to allow drop-in memory management, and to
|
||||
* use the same interface as Niels Provos's tree.h. This is probably still
|
||||
* a derived work, so the original license below still applies.
|
||||
*
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче