1
1

Update internal libevent to upstream (v1.4.2-rc + OMPI changes).

Greatly reduce the number of "foo" -> "opal_foo" symbol renames in the
libevent source, and instead greatly expand the event_rename.h file
that uses preprocessor macros to make all public symbols be
"opal_foo".

This commit was SVN r17923.
Этот коммит содержится в:
Jeff Squyres 2008-03-23 12:33:04 +00:00
родитель dee561d29e
Коммит 314ab2c6e7
48 изменённых файлов: 5819 добавлений и 2561 удалений

Просмотреть файл

@ -305,6 +305,15 @@ main()
fi fi
fi fi
haveeventports=no
AC_CHECK_FUNCS(port_create, [haveeventports=yes], )
if test "x$haveeventports" = "xyes" ; then
AC_DEFINE(HAVE_EVENT_PORTS, 1,
[Define if your system supports event ports])
sources="evport.c $sources"
needsignal=yes
fi
if test "x$needsignal" = "xyes" ; then if test "x$needsignal" = "xyes" ; then
# OMPI: don't use AC_LIBOBJ # OMPI: don't use AC_LIBOBJ
sources="signal.c $sources" sources="signal.c $sources"

Просмотреть файл

@ -36,3 +36,8 @@ snapc=full
# #
pml_wrapper=crcpw pml_wrapper=crcpw
crcp=coord crcp=coord
#
# Temporary fix to force the event engine to use poll to behave well with BLCR
#
opal_event_include=poll

Просмотреть файл

@ -9,6 +9,7 @@
# University of Stuttgart. All rights reserved. # University of Stuttgart. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California. # Copyright (c) 2004-2005 The Regents of the University of California.
# All rights reserved. # All rights reserved.
# Copyright (c) 2008 Cisco Systems, Inc. All rights reserved.
# $COPYRIGHT$ # $COPYRIGHT$
# #
# Additional copyrights may follow # Additional copyrights may follow
@ -29,7 +30,7 @@ AM_CPPFLAGS = \
SUBDIRS = compat SUBDIRS = compat
EXTRA_DIST = event.h event-internal.h evsignal.h event.3 \ EXTRA_DIST = event.h event-internal.h evsignal.h event.3 \
kqueue.c epoll_sub.c epoll.c select.c rtsig.c poll.c signal.c \ kqueue.c epoll_sub.c epoll.c select.c poll.c signal.c \
devpoll.c log.h\ devpoll.c log.h\
WIN32-Code/config.h WIN32-Code/misc.c \ WIN32-Code/config.h WIN32-Code/misc.c \
WIN32-Code/misc.h WIN32-Code/win32.c WIN32-Code/misc.h WIN32-Code/win32.c
@ -56,9 +57,9 @@ noinst_LTLIBRARIES = libevent.la
objects = $(OMPI_LIBEVENT_SOURCES:.c=.lo) objects = $(OMPI_LIBEVENT_SOURCES:.c=.lo)
# OMPI: Changed to libevent_la_* # OMPI: Changed to libevent_la_*
headers = event.h event_rename.h headers = event.h event_rename.h evutil.h min_heap.h
libevent_la_SOURCES = event.c buffer.c evbuffer.c log.c $(headers) libevent_la_SOURCES = event.c log.c evutil.c $(headers)
libevent_la_LIBADD = $(objects) libevent_la_LIBADD = $(objects)
libevent_la_DEPENDENCIES = $(objects) libevent_la_DEPENDENCIES = $(objects)

Просмотреть файл

@ -2,6 +2,10 @@ To build libevent, type
$ ./configure && make $ ./configure && make
(If you got libevent from the subversion repository, you will
first need to run the included "autogen.sh" script in order to
generate the configure script.)
Install as root via Install as root via
# make install # make install
@ -12,18 +16,42 @@ $ make verify
Before, reporting any problems, please run the regression tests. Before, reporting any problems, please run the regression tests.
To enable the low-level tracing build the library as:
CFLAGS=-DUSE_DEBUG ./configure [...]
Acknowledgements: Acknowledgements:
----------------- -----------------
The following people have helped with suggestions, ideas, code or The following people have helped with suggestions, ideas, code or
fixing bugs: fixing bugs:
Nick Mathewson Alejo
Andrew Danforth Weston Andros Adamson
Shie Erlich
Mike Davis
William Ahern William Ahern
Stas Bekman
Andrew Danforth
Mike Davis
Shie Erlich
Alexander von Gernler Alexander von Gernler
Artur Grabowski Artur Grabowski
Aaron Hopkins
Claudio Jeker
Scott Lamb
Adam Langley
Philip Lewis
David Libenzi
Nick Mathewson
Andrey Matveev
Richard Nyberg
Jon Oberheide
Phil Oleson
Dave Pacheco
Tassilo von Parseval
Pierre Phaneuf
Jon Poland
Bert JW Regeer
Dug Song
Taral
If I have forgotten your name, please contact me. If I have forgotten your name, please contact me.

Просмотреть файл

@ -1,236 +1,243 @@
/* config.h.in. Generated automatically from configure.in by autoheader. */ /* config.h. Generated by configure. */
/* Define if kqueue works correctly with pipes */ /* config.h.in. Generated from configure.in by autoheader. */
#undef HAVE_WORKING_KQUEUE
/* Define to `unsigned long long' if <sys/types.h> doesn't define. */ /* Define if clock_gettime is available in libc */
#undef u_int64_t /* #undef DNS_USE_CPU_CLOCK_FOR_ID */
/* Define to `unsigned int' if <sys/types.h> doesn't define. */ /* Define if no secure id variant is available */
#undef u_int32_t #define DNS_USE_FTIME_FOR_ID 1
/* Define to `unsigned short' if <sys/types.h> doesn't define. */ /* Define if no secure id variant is available */
#undef u_int16_t /* #define DNS_USE_GETTIMEOFDAY_FOR_ID 1 */
/* Define to `unsigned char' if <sys/types.h> doesn't define. */ /* Define to 1 if you have the `clock_gettime' function. */
#undef u_int8_t /* #undef HAVE_CLOCK_GETTIME */
/* Define if timeradd is defined in <sys/time.h> */
#undef HAVE_TIMERADD
#ifndef HAVE_TIMERADD
#undef timersub
#define timeradd(tvp, uvp, vvp) \
do { \
(vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \
(vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \
if ((vvp)->tv_usec >= 1000000) { \
(vvp)->tv_sec++; \
(vvp)->tv_usec -= 1000000; \
} \
} while (0)
#define timersub(tvp, uvp, vvp) \
do { \
(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
(vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
if ((vvp)->tv_usec < 0) { \
(vvp)->tv_sec--; \
(vvp)->tv_usec += 1000000; \
} \
} while (0)
#endif /* !HAVE_TIMERADD */
#undef HAVE_TIMERCLEAR
#ifndef HAVE_TIMERCLEAR
#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0
#endif
#define HAVE_TIMERCMP
#ifndef HAVE_TIMERCMP
#undef timercmp
#define timercmp(tvp, uvp, cmp) \
(((tvp)->tv_sec == (uvp)->tv_sec) ? \
((tvp)->tv_usec cmp (uvp)->tv_usec) : \
((tvp)->tv_sec cmp (uvp)->tv_sec))
#endif
#undef HAVE_TIMERISSET
#ifndef HAVE_TIMERISSET
#undef timerisset
#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
#endif
/* Define if TAILQ_FOREACH is defined in <sys/queue.h> */
#define HAVE_TAILQFOREACH
#ifndef HAVE_TAILQFOREACH
#define TAILQ_FIRST(head) ((head)->tqh_first)
#define TAILQ_END(head) NULL
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
#define TAILQ_FOREACH(var, head, field) \
for((var) = TAILQ_FIRST(head); \
(var) != TAILQ_END(head); \
(var) = TAILQ_NEXT(var, field))
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
(elm)->field.tqe_next = (listelm); \
*(listelm)->field.tqe_prev = (elm); \
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
} while (0)
#endif /* TAILQ_FOREACH */
/* Define if /dev/poll is available */ /* Define if /dev/poll is available */
#undef HAVE_DEVPOLL /* #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 */ /* Define if your system supports the epoll system calls */
#undef HAVE_EPOLL /* #undef HAVE_EPOLL */
/* Define if you have the `epoll_ctl' function. */ /* Define to 1 if you have the `epoll_ctl' function. */
#undef HAVE_EPOLL_CTL /* #undef HAVE_EPOLL_CTL */
/* Define if you have the `err' function. */ /* Define if your system supports event ports */
#undef HAVE_ERR /* #undef HAVE_EVENT_PORTS */
/* Define if you have the `fcntl' function. */ /* Define to 1 if you have the `fcntl' function. */
#undef HAVE_FCNTL /* #undef HAVE_FCNTL */
/* Define if you have the <fcntl.h> header file. */ /* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H #define HAVE_FCNTL_H 1
/* Define if you have the `gettimeofday' function. */ /* Define to 1 if you have the `getaddrinfo' function. */
#define HAVE_GETTIMEOFDAY 1 /* #undef HAVE_GETADDRINFO */
/* Define if you have the <inttypes.h> header file. */ /* Define to 1 if you have the `getnameinfo' function. */
/* #undef HAVE_INTTYPES_H */ /* #undef HAVE_GETNAMEINFO */
/* Define if you have the `kqueue' function. */ /* Define to 1 if you have the `gettimeofday' function. */
#undef HAVE_KQUEUE /* #define HAVE_GETTIMEOFDAY 1 */
/* Define if you have the `socket' library (-lsocket). */ /* Define to 1 if you have the `inet_ntop' function. */
#undef HAVE_LIBSOCKET /* #undef HAVE_INET_NTOP */
/* Define if you have the <memory.h> header file. */ /* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `kqueue' function. */
/* #undef HAVE_KQUEUE */
/* Define to 1 if you have the `nsl' library (-lnsl). */
/* #undef HAVE_LIBNSL */
/* Define to 1 if you have the `resolv' library (-lresolv). */
/* #undef HAVE_LIBRESOLV */
/* Define to 1 if you have the `rt' library (-lrt). */
/* #undef HAVE_LIBRT */
/* Define to 1 if you have the `socket' library (-lsocket). */
/* #undef HAVE_LIBSOCKET */
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1 #define HAVE_MEMORY_H 1
/* Define if you have the `poll' function. */ /* Define to 1 if you have the <netinet/in6.h> header file. */
#undef HAVE_POLL /* #undef HAVE_NETINET_IN6_H */
/* Define if you have the <poll.h> header file. */ /* Define to 1 if you have the `poll' function. */
#undef HAVE_POLL_H /* #undef HAVE_POLL */
/* Define if your system supports POSIX realtime signals */ /* Define to 1 if you have the <poll.h> header file. */
#undef HAVE_RTSIG /* #undef HAVE_POLL_H */
/* Define if you have the `select' function. */ /* Define to 1 if you have the `port_create' function. */
#undef HAVE_SELECT /* #undef HAVE_PORT_CREATE */
/* Define to 1 if you have the <port.h> header file. */
/* #undef HAVE_PORT_H */
/* Define to 1 if you have the `select' function. */
/* #undef HAVE_SELECT */
/* Define if F_SETFD is defined in <fcntl.h> */ /* Define if F_SETFD is defined in <fcntl.h> */
#undef HAVE_SETFD /* #undef HAVE_SETFD */
/* Define if you have the <signal.h> header file. */ /* Define to 1 if you have the `sigaction' function. */
#undef HAVE_SIGNAL_H /* #undef HAVE_SIGACTION */
/* Define if you have the `sigtimedwait' function. */ /* Define to 1 if you have the `signal' function. */
#undef HAVE_SIGTIMEDWAIT #define HAVE_SIGNAL 1
/* Define if you have the <stdarg.h> header file. */ /* Define to 1 if you have the <signal.h> header file. */
#define HAVE_SIGNAL_H 1
/* Define to 1 if you have the <stdarg.h> header file. */
#define HAVE_STDARG_H 1 #define HAVE_STDARG_H 1
/* Define if you have the <stdint.h> header file. */ /* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H /* #define HAVE_STDINT_H 1 */
/* Define if you have the <stdlib.h> header file. */ /* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1 #define HAVE_STDLIB_H 1
/* Define if you have the <strings.h> header file. */ /* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H #define HAVE_STRINGS_H 1
/* Define if you have the <string.h> header file. */ /* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1 #define HAVE_STRING_H 1
/* Define if you have the <sys/devpoll.h> header file. */ /* Define to 1 if you have the `strlcpy' function. */
#undef HAVE_SYS_DEVPOLL_H /* #undef HAVE_STRLCPY */
/* Define if you have the <sys/epoll.h> header file. */ /* Define to 1 if you have the `strsep' function. */
#undef HAVE_SYS_EPOLL_H /* #undef HAVE_STRSEP */
/* Define if you have the <sys/event.h> header file. */ /* Define to 1 if you have the `strtok_r' function. */
#undef HAVE_SYS_EVENT_H /* #undef HAVE_STRTOK_R */
/* Define if you have the <sys/ioctl.h> header file. */ /* Define to 1 if the system has the type `struct in6_addr'. */
#undef HAVE_SYS_IOCTL_H #define HAVE_STRUCT_IN6_ADDR 1
/* Define if you have the <sys/queue.h> header file. */ /* Define to 1 if you have the <sys/devpoll.h> header file. */
#undef HAVE_SYS_QUEUE_H /* #undef HAVE_SYS_DEVPOLL_H */
/* Define if you have the <sys/stat.h> header file. */ /* Define to 1 if you have the <sys/epoll.h> header file. */
#define HAVE_SYS_STAT_H 1 /* #undef HAVE_SYS_EPOLL_H */
/* Define if you have the <sys/time.h> header file. */ /* Define to 1 if you have the <sys/event.h> header file. */
#undef HAVE_SYS_TIME_H /* #undef HAVE_SYS_EVENT_H */
/* Define if you have the <sys/types.h> header file. */ /* Define to 1 if you have the <sys/ioctl.h> header file. */
#define HAVE_SYS_TYPES_H 1 /* #undef HAVE_SYS_IOCTL_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/socket.h> header file. */
/* #undef HAVE_SYS_SOCKET_H */
/* Define to 1 if you have the <sys/stat.h> header file. */
/* #define HAVE_SYS_STAT_H 1 */
/* Define to 1 if you have the <sys/time.h> header file. */
/* #define HAVE_SYS_TIME_H 1 */
/* Define to 1 if you have the <sys/types.h> header file. */
/* #define HAVE_SYS_TYPES_H 1 */
/* Define if TAILQ_FOREACH is defined in <sys/queue.h> */ /* Define if TAILQ_FOREACH is defined in <sys/queue.h> */
#undef HAVE_TAILQFOREACH /* #undef HAVE_TAILQFOREACH */
/* Define if timeradd is defined in <sys/time.h> */ /* Define if timeradd is defined in <sys/time.h> */
#undef HAVE_TIMERADD /* #undef HAVE_TIMERADD */
/* Define if you have the <unistd.h> header file. */ /* Define if timerclear is defined in <sys/time.h> */
#undef HAVE_UNISTD_H /* #define HAVE_TIMERCLEAR 1 */
/* Define if you have the `vasprintf' function. */ /* Define if timercmp is defined in <sys/time.h> */
#undef HAVE_VASPRINTF #define HAVE_TIMERCMP 1
/* Define if timerisset is defined in <sys/time.h> */
#define HAVE_TIMERISSET 1
/* Define to 1 if you have the <unistd.h> header file. */
/* #define HAVE_UNISTD_H 1 */
/* Define to 1 if you have the `vasprintf' function. */
/* #undef HAVE_VASPRINTF */
/* Define if kqueue works correctly with pipes */ /* Define if kqueue works correctly with pipes */
#undef HAVE_WORKING_KQUEUE /* #undef HAVE_WORKING_KQUEUE */
/* Define if realtime signals work on pipes */
#undef HAVE_WORKING_RTSIG
/* Name of package */ /* Name of package */
#define PACKAGE "libevent" #define PACKAGE "libevent"
/* Define if you have the ANSI C header files. */ /* Define to the address where bug reports for this package should be sent. */
#undef STDC_HEADERS #define PACKAGE_BUGREPORT ""
/* Define if you can safely include both <sys/time.h> and <time.h>. */ /* Define to the full name of this package. */
#undef TIME_WITH_SYS_TIME #define PACKAGE_NAME ""
/* Define to the full name and version of this package. */
#define PACKAGE_STRING ""
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME ""
/* Define to the version of this package. */
#define PACKAGE_VERSION ""
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1
/* Version number of package */ /* Version number of package */
#define VERSION "1.0b" #define VERSION "1.3.99-trunk"
/* Define to appropriate substitue if compiler doesnt have __func__ */
#if defined(_MSC_VER) && _MSC_VER < 1300
#define __func__ "??"
#else
#define __func__ __FUNCTION__
#endif
/* Define to empty if `const' does not conform to ANSI C. */ /* Define to empty if `const' does not conform to ANSI C. */
#undef const /* #undef const */
/* Define as `__inline' if that's what the C compiler calls it, or to nothing /* Define to `__inline__' or `__inline' if that's what the C compiler
if it is not supported. */ calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#define inline __inline #define inline __inline
#endif
/* Define to `int' if <sys/types.h> does not define. */ /* Define to `int' if <sys/types.h> does not define. */
#undef pid_t /* #undef pid_t */
/* Define to `unsigned' if <sys/types.h> does not define. */ /* Define to `unsigned' if <sys/types.h> does not define. */
#undef size_t /* #undef size_t */
/* Define to unsigned int if you dont have it */ /* Define to unsigned int if you dont have it */
#undef socklen_t #define socklen_t unsigned int
/* Define to `unsigned short' if <sys/types.h> does not define. */ /* Define to `unsigned short' if <sys/types.h> does not define. */
#undef u_int16_t #define uint16_t unsigned short
/* Define to `unsigned int' if <sys/types.h> does not define. */ /* Define to `unsigned int' if <sys/types.h> does not define. */
#undef u_int32_t #define uint32_t unsigned int
/* Define to `unsigned long long' if <sys/types.h> does not define. */ /* Define to `unsigned long long' if <sys/types.h> does not define. */
/* #undef u_int64_t */ #define uint64_t __uint64_t
/* Define to `unsigned char' if <sys/types.h> does not define. */ /* Define to `unsigned char' if <sys/types.h> does not define. */
/* #undef u_int8_t */ #define uint8_t unsigned char
int win_read(int, void *, unsigned int);
int win_write(int, void *, unsigned int);
int socketpair(int d, int type, int protocol, int *sv);
#if !defined(__func__)
#define __func__ __FILE__
#endif /* !defined(__func__) */

Просмотреть файл

@ -1,10 +1,15 @@
#include "opal_config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <windows.h> #include <windows.h>
#include <sys/timeb.h> #include <sys/timeb.h>
#include <time.h> #include <time.h>
#ifdef __GNUC__
/*our prototypes for timeval and timezone are in here, just in case the above
headers don't have them*/
#include "misc.h"
#endif
/**************************************************************************** /****************************************************************************
* *
* Function: gettimeofday(struct timeval *, struct timezone *) * Function: gettimeofday(struct timeval *, struct timezone *)
@ -18,25 +23,26 @@
* *
****************************************************************************/ ****************************************************************************/
#if 0 #ifndef HAVE_GETTIMEOFDAY
int gettimeofday(struct timeval *tv, struct timezone *tz) { int gettimeofday(struct timeval *tv, struct timezone *tz) {
struct _timeb tb; struct _timeb tb;
if(tv == NULL) if(tv == NULL)
return -1; return -1;
_ftime(&tb); _ftime(&tb);
tv->tv_sec = (long)tb.time; tv->tv_sec = (long) tb.time;
tv->tv_usec = ((int) tb.millitm) * 1000; tv->tv_usec = ((int) tb.millitm) * 1000;
return 0; return 0;
} }
#endif #endif
#if 0
int int
win_read(int fd, void *buf, unsigned int length) win_read(int fd, void *buf, unsigned int length)
{ {
DWORD dwBytesRead; DWORD dwBytesRead;
int res = ReadFile((HANDLE)fd, buf, length, &dwBytesRead, NULL); int res = ReadFile((HANDLE) fd, buf, length, &dwBytesRead, NULL);
if (res == 0) { if (res == 0) {
DWORD error = GetLastError(); DWORD error = GetLastError();
if (error == ERROR_NO_DATA) if (error == ERROR_NO_DATA)
@ -84,3 +90,4 @@ socketpair(int d, int type, int protocol, int *sv)
return (0); return (0);
} }
#endif

Просмотреть файл

@ -1,23 +1,11 @@
#ifndef MISC_H #ifndef MISC_H
#define MISC_H #define MISC_H
#include "opal/event/event.h" struct timezone;
struct timeval;
#if defined(c_plusplus) || defined(__cplusplus)
extern "C" {
#endif
#ifndef HAVE_GETTIMEOFDAY
int gettimeofday(struct timeval *,struct timezone *); int gettimeofday(struct timeval *,struct timezone *);
OPAL_DECLSPEC extern void *win32_init (void);
OPAL_DECLSPEC extern int win32_insert(struct win32op *win32op, struct opal_event *ev);
OPAL_DECLSPEC extern int win32_del(struct win32op *win32op, struct opal_event *ev);
OPAL_DECLSPEC extern int win32_dispatch(struct event_base *base, struct win32op *win32op,
struct timeval *tv);
OPAL_DECLSPEC extern int win32_recalc (struct event_base *base, void *, int);
#if defined(c_plusplus) || defined(__cplusplus)
}
#endif #endif
#endif #endif

Просмотреть файл

@ -675,3 +675,680 @@ name##_RB_MINMAX(struct name *head, int val) \
(x) = name##_RB_NEXT(x)) (x) = name##_RB_NEXT(x))
#endif /* _SYS_TREE_H_ */ #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_ */

Просмотреть файл

@ -1,7 +1,6 @@
/* /*
* Copyright 2000-2002 Niels Provos <provos@citi.umich.edu> * Copyright 2000-2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2003 Michael A. Davis <mike@datanerds.net> * Copyright 2003 Michael A. Davis <mike@datanerds.net>
* Copyright 2006 George Bosilca <bosilca@cs.utk.edu>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -26,35 +25,37 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "opal_config.h" #ifdef _MSC_VER
#include "config.h" #include "./config.h"
#else
/* Avoid the windows/msvc thing. */
#include "../config.h"
#endif
#include <winsock2.h> #include <winsock2.h>
#include <windows.h> #include <windows.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/queue.h> #include <sys/queue.h>
#include <sys/tree.h>
#if defined(HAVE_SIGNAL_H)
#include <signal.h> #include <signal.h>
#endif /* defined(HAVE_SIGNAL_H) */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <assert.h> #include <assert.h>
#include "opal/event/event_rename.h" #define RB_AUGMENT(x) (void)(x)
#include "./tree.h"
#include "opal/event/log.h" #include "opal/event/log.h"
#include "opal/event/event.h" #include "opal/event/event.h"
#include "opal/event/event-internal.h" #include "opal/event/event-internal.h"
#include "opal/event/WIN32-Code/misc.h"
#define XFREE(ptr) do { if (ptr) free(ptr); } while(0) #define XFREE(ptr) do { if (ptr) free(ptr); } while(0)
extern struct opal_event_list opal_timequeue; extern struct event_list timequeue;
extern struct opal_event_list opal_addqueue; extern struct event_list addqueue;
extern struct opal_event_list opal_signalqueue; #if 0
extern struct event_list signalqueue;
#endif
struct win_fd_set { struct win_fd_set {
u_int fd_count; u_int fd_count;
@ -66,9 +67,32 @@ volatile sig_atomic_t signal_caught = 0;
/* MSDN says this is required to handle SIGFPE */ /* MSDN says this is required to handle SIGFPE */
volatile double SIGFPE_REQ = 0.0f; volatile double SIGFPE_REQ = 0.0f;
void signal_handler(int sig); #if 0
static void signal_handler(int sig);
void signal_process(void); void signal_process(void);
int signal_recalc(void); int signal_recalc(void);
#endif
struct event_entry {
RB_ENTRY(event_entry) node;
SOCKET sock;
int read_pos;
int write_pos;
struct event *read_event;
struct event *write_event;
};
static int
compare(struct event_entry *a, struct event_entry *b)
{
if (a->sock < b->sock)
return -1;
else if (a->sock > b->sock)
return 1;
else
return 0;
}
struct win32op { struct win32op {
int fd_setsz; int fd_setsz;
@ -77,375 +101,349 @@ struct win32op {
struct win_fd_set *readset_out; struct win_fd_set *readset_out;
struct win_fd_set *writeset_out; struct win_fd_set *writeset_out;
struct win_fd_set *exset_out; struct win_fd_set *exset_out;
int n_events; RB_HEAD(event_map, event_entry) event_root;
int n_events_alloc;
opal_event_t **events;
}; };
const struct opal_eventop opal_win32ops = { RB_PROTOTYPE(event_map, event_entry, node, compare);
RB_GENERATE(event_map, event_entry, node, compare);
void *win32_init (struct event_base *);
int win32_insert (void *, struct event *);
int win32_del (void *, struct event *);
int win32_dispatch (struct event_base *base, void *, struct timeval *);
void win32_dealloc (struct event_base *, void *);
struct eventop win32ops = {
"win32", "win32",
win32_init, win32_init,
(int (*)(void *, struct opal_event *))win32_insert, win32_insert,
(int (*)(void *, struct opal_event *))win32_del, win32_del,
(int (*)(struct event_base *, void *, int))win32_recalc, win32_dispatch,
(int (*)(struct event_base *, void *, struct timeval *))win32_dispatch win32_dealloc,
0
}; };
#define FD_SET_ALLOC_SIZE(n) ((sizeof(struct win_fd_set) + ((n)-1)*sizeof(SOCKET))) #define FD_SET_ALLOC_SIZE(n) ((sizeof(struct win_fd_set) + ((n)-1)*sizeof(SOCKET)))
static int
realloc_fd_sets(struct win32op *op, size_t new_size)
{
size_t size;
assert(new_size >= op->readset_in->fd_count &&
new_size >= op->writeset_in->fd_count);
assert(new_size >= 1);
size = FD_SET_ALLOC_SIZE(new_size);
if (!(op->readset_in = realloc(op->readset_in, size)))
return (-1);
if (!(op->writeset_in = realloc(op->writeset_in, size)))
return (-1);
if (!(op->readset_out = realloc(op->readset_out, size)))
return (-1);
if (!(op->exset_out = realloc(op->exset_out, size)))
return (-1);
if (!(op->writeset_out = realloc(op->writeset_out, size)))
return (-1);
op->fd_setsz = new_size;
return (0);
}
static int
timeval_to_ms(struct timeval *tv)
{
return ((tv->tv_sec * 1000) + (tv->tv_usec / 1000));
}
static struct event_entry*
get_event_entry(struct win32op *op, SOCKET s, int create)
{
struct event_entry key, *val;
key.sock = s;
val = RB_FIND(event_map, &op->event_root, &key);
if (val || !create)
return val;
if (!(val = calloc(1, sizeof(struct event_entry)))) {
event_warn("%s: calloc", __func__);
return NULL;
}
val->sock = s;
val->read_pos = val->write_pos = -1;
RB_INSERT(event_map, &op->event_root, val);
return val;
}
static int
do_fd_set(struct win32op *op, struct event_entry *ent, int read)
{
SOCKET s = ent->sock;
struct win_fd_set *set = read ? op->readset_in : op->writeset_in;
if (read) {
if (ent->read_pos >= 0)
return (0);
} else {
if (ent->write_pos >= 0)
return (0);
}
if (set->fd_count == op->fd_setsz) {
if (realloc_fd_sets(op, op->fd_setsz*2))
return (-1);
/* set pointer will have changed and needs reiniting! */
set = read ? op->readset_in : op->writeset_in;
}
set->fd_array[set->fd_count] = s;
if (read)
ent->read_pos = set->fd_count;
else
ent->write_pos = set->fd_count;
return (set->fd_count++);
}
static int
do_fd_clear(struct win32op *op, struct event_entry *ent, int read)
{
int i;
struct win_fd_set *set = read ? op->readset_in : op->writeset_in;
if (read) {
i = ent->read_pos;
ent->read_pos = -1;
} else {
i = ent->write_pos;
ent->write_pos = -1;
}
if (i < 0)
return (0);
if (--set->fd_count != i) {
struct event_entry *ent2;
SOCKET s2;
s2 = set->fd_array[i] = set->fd_array[set->fd_count];
ent2 = get_event_entry(op, s2, 0);
if (!ent) /* This indicates a bug. */
return (0);
if (read)
ent2->read_pos = i;
else
ent2->write_pos = i;
}
return (0);
}
#define NEVENT 64 #define NEVENT 64
void * void *
win32_init(void) win32_init(struct event_base *_base)
{ {
struct win32op *winop; struct win32op *winop;
size_t size; size_t size;
if (!(winop = (struct win32op*)calloc(1, sizeof(struct win32op)))) if (!(winop = calloc(1, sizeof(struct win32op))))
return NULL; return NULL;
winop->fd_setsz = NEVENT; winop->fd_setsz = NEVENT;
size = FD_SET_ALLOC_SIZE(NEVENT); size = FD_SET_ALLOC_SIZE(NEVENT);
if (!(winop->readset_in = (struct win_fd_set*)malloc(size))) if (!(winop->readset_in = malloc(size)))
goto err; goto err;
if (!(winop->writeset_in = (struct win_fd_set*)malloc(size))) if (!(winop->writeset_in = malloc(size)))
goto err; goto err;
if (!(winop->readset_out = (struct win_fd_set*)malloc(size))) if (!(winop->readset_out = malloc(size)))
goto err; goto err;
if (!(winop->writeset_out = (struct win_fd_set*)malloc(size))) if (!(winop->writeset_out = malloc(size)))
goto err; goto err;
if (!(winop->exset_out = (struct win_fd_set*)malloc(size))) if (!(winop->exset_out = malloc(size)))
goto err;
winop->n_events = 0;
winop->n_events_alloc = NEVENT;
if (!(winop->events = (opal_event_t**)malloc(NEVENT*sizeof(opal_event_t*))))
goto err; goto err;
RB_INIT(&winop->event_root);
winop->readset_in->fd_count = winop->writeset_in->fd_count = 0; winop->readset_in->fd_count = winop->writeset_in->fd_count = 0;
winop->readset_out->fd_count = winop->writeset_out->fd_count winop->readset_out->fd_count = winop->writeset_out->fd_count
= winop->exset_out->fd_count = 0; = winop->exset_out->fd_count = 0;
evsignal_init(_base);
return (winop); return (winop);
err: err:
XFREE(winop->readset_in); XFREE(winop->readset_in);
XFREE(winop->writeset_in); XFREE(winop->writeset_in);
XFREE(winop->readset_out); XFREE(winop->readset_out);
XFREE(winop->writeset_out); XFREE(winop->writeset_out);
XFREE(winop->exset_out); XFREE(winop->exset_out);
XFREE(winop->events); XFREE(winop);
XFREE(winop); return (NULL);
return (NULL);
} }
int int
win32_recalc(struct event_base *base, void *arg, int max) win32_insert(void *op, struct event *ev)
{ {
return 0/*(signal_recalc())*/; struct win32op *win32op = op;
} struct event_entry *ent;
static bool win32_is_fd_a_socket( int fd ) if (ev->ev_events & EV_SIGNAL) {
{ return (evsignal_add(ev));
int error;
u_long value = 123456;
if( SOCKET_ERROR == WSAHtonl( fd, value, &value ) ) {
error = WSAGetLastError();
return false;
}
return true;
}
void CALLBACK win32_socket_event_callback( void* lpParameter, BOOLEAN TimerOrWaitFired )
{
opal_event_t* master = (opal_event_t*)lpParameter;
WSANETWORKEVENTS network_events;
int got, error;
opal_event_t* next;
assert( FALSE == TimerOrWaitFired );
/* The handle will be automatically reset */
if( SOCKET_ERROR == WSAEnumNetworkEvents( master->ev_fd, master->base_handle, &network_events ) ) {
error = WSAGetLastError();
return;
}
do {
got = 0;
next = master->ev_similar;
if( network_events.lNetworkEvents & (FD_READ | FD_ACCEPT) ) {
if( master->ev_events & OPAL_EV_READ ) {
network_events.lNetworkEvents &= ~(FD_READ | FD_ACCEPT);
got |= OPAL_EV_READ;
}
}
if( master->ev_events & OPAL_EV_WRITE ) {
got |= OPAL_EV_WRITE;
if( 0 == WSASetEvent(master->base_handle) ) {
int error = WSAGetLastError();
}
}
if( got ) {
if (!(master->ev_events & OPAL_EV_PERSIST)) {
opal_event_del(master);
}
(*master->ev_callback)((int)master->ev_fd, got, master->ev_arg);
/*opal_event_active( ev, got, 1 );*/
}
master = next;
} while( master != ((opal_event_t*)lpParameter) );
}
void CALLBACK win32_file_event_callback( void* lpParameter, BOOLEAN TimerOrWaitFired )
{
opal_event_t* ev = (opal_event_t*)lpParameter;
int got = 0;
assert( FALSE == TimerOrWaitFired );
if( ev->ev_events & OPAL_EV_READ ) {
got |= OPAL_EV_READ;
} }
if( ev->ev_events & OPAL_EV_WRITE ) { if (!(ev->ev_events & (EV_READ|EV_WRITE)))
got |= OPAL_EV_WRITE;
}
if (!(ev->ev_events & OPAL_EV_PERSIST)) {
opal_event_del(ev);
}
if( got ) {
/*(*ev->ev_callback)((int)ev->ev_fd, got, ev->ev_arg);*/
opal_event_active( ev, got, 1 );
}
}
static int win32_recompute_event( opal_event_t* master )
{
long flags = FD_CLOSE;
opal_event_t* temp;
int error;
if( INVALID_HANDLE_VALUE == master->base_handle ) {
master->base_handle = WSACreateEvent();
if( INVALID_HANDLE_VALUE == master->base_handle ) {
return 0;
}
}
/* Compute the flags we're looking at */
temp = master;
do {
if( temp->ev_events & OPAL_EV_READ ) flags |= FD_READ | FD_ACCEPT;
if( temp->ev_events & OPAL_EV_WRITE ) flags |= FD_WRITE | FD_CONNECT;
temp = temp->ev_similar;
} while( temp != master );
if( SOCKET_ERROR == WSAEventSelect( master->ev_fd, master->base_handle, flags ) ) {
error = WSAGetLastError();
WSACloseEvent( master->base_handle );
master->base_handle = INVALID_HANDLE_VALUE;
return 0;
}
if( INVALID_HANDLE_VALUE == master->registered_handle ) {
if( 0 == RegisterWaitForSingleObject( &master->registered_handle, master->base_handle, win32_socket_event_callback,
(void*)master, INFINITE, WT_EXECUTEINWAITTHREAD ) ) {
error = GetLastError();
WSACloseEvent( master->base_handle );
master->base_handle = INVALID_HANDLE_VALUE;
master->registered_handle = INVALID_HANDLE_VALUE;
return 0;
}
}
if( flags & FD_WRITE ) {
if( 0 == WSASetEvent(master->base_handle) ) {
error = WSAGetLastError();
}
}
return 1;
}
int
win32_insert(struct win32op *win32op, opal_event_t *ev)
{
int i;
opal_event_t* master = NULL;
if (ev->ev_events & OPAL_EV_SIGNAL) {
if (ev->ev_events & (OPAL_EV_READ|OPAL_EV_WRITE))
event_errx(1, "%s: EV_SIGNAL incompatible use",
__func__);
if( signal(OPAL_EVENT_SIGNAL(ev), signal_handler) == SIG_ERR)
return (-1);
return (0); return (0);
ent = get_event_entry(win32op, ev->ev_fd, 1);
if (!ent)
return (-1); /* out of memory */
event_debug(("%s: adding event for %d", __func__, (int)ev->ev_fd));
if (ev->ev_events & EV_READ) {
if (do_fd_set(win32op, ent, 1)<0)
return (-1);
ent->read_event = ev;
} }
if (ev->ev_events & EV_WRITE) {
/** if (do_fd_set(win32op, ent, 0)<0)
* Find a place for the current event. return (-1);
*/ ent->write_event = ev;
for( i = 0; i < win32op->n_events; ++i ) {
if( win32op->events[i]->ev_fd != ev->ev_fd ) continue;
master = win32op->events[i];
if( master == ev ) {
event_debug( ("%s: Event for %d already inserted.",
__func__, (int)ev->ev_fd));
return (0);
}
if( master->ev_events & ev->ev_events ) {
event_debug( ("%d Event for %d already have a similar event posted.",
__func__, (int)ev->ev_fd) );
}
ev->ev_similar = master->ev_similar;
master->ev_similar = ev;
break;
} }
if( NULL == master ) {
event_debug(("%s: adding event for %d", __func__, (int)ev->ev_fd));
if (win32op->n_events_alloc == win32op->n_events) {
size_t sz;
win32op->n_events_alloc *= 2;
sz = sizeof(opal_event_t*) * win32op->n_events_alloc;
if (!(win32op->events = (opal_event_t**)realloc(win32op->events, sz)))
return (-1);
}
win32op->events[win32op->n_events++] = ev;
ev->ev_similar = ev;
master = ev;
}
ev->base_handle = INVALID_HANDLE_VALUE;
ev->registered_handle = INVALID_HANDLE_VALUE;
/**
* Decide if we have a socket or a normal file descriptor. If it's a socket
* create a WSA event otherwise a normal file event will be what we need.
*/
if( win32_is_fd_a_socket(ev->ev_fd) ) {
win32_recompute_event( master );
} else {
/*
if( ev->ev_events & OPAL_EV_READ ) flags |= FD_READ;
if( ev->ev_events & OPAL_EV_WRITE ) flags |= FD_WRITE;
ev->base_handle = (HANDLE)_get_osfhandle( ev->ev_fd );
if( INVALID_HANDLE_VALUE == ev->base_handle ) {
int error = errno;
}
if( 0 == RegisterWaitForSingleObject( &ev->registered_handle, ev->base_handle, win32_file_event_callback,
(void*)ev, INFINITE, WT_EXECUTEINWAITTHREAD ) ) {
error = GetLastError();
}*/
}
return (0); return (0);
} }
int int
win32_del(struct win32op *win32op, opal_event_t *ev) win32_del(void *op, struct event *ev)
{ {
int i, error; struct win32op *win32op = op;
opal_event_t *master = NULL, *temp; struct event_entry *ent;
if (ev->ev_events & OPAL_EV_SIGNAL) if (ev->ev_events & EV_SIGNAL)
return (signal(OPAL_EVENT_SIGNAL(ev), SIG_IGN) != SIG_ERR); return (evsignal_del(ev));
for( i = 0; i < win32op->n_events; ++i ) { if (!(ent = get_event_entry(win32op, ev->ev_fd, 0)))
if( win32op->events[i]->ev_fd != ev->ev_fd ) continue;
master = win32op->events[i];
break;
}
if( NULL == master ) {
event_debug(("%s: Unable to remove non-inserted event for %d",
__func__, ev->ev_fd));
return (-1); return (-1);
}
event_debug(("%s: Removing event for %d", __func__, ev->ev_fd)); event_debug(("%s: Removing event for %d", __func__, ev->ev_fd));
if (ev == ent->read_event) {
/** do_fd_clear(win32op, ent, 1);
* Remove the current event and recompute the registered event ent->read_event = NULL;
* based on the opal events pending on the same master. }
*/ if (ev == ent->write_event) {
if( master == ev ) { do_fd_clear(win32op, ent, 0);
/* Disable all pending events */ ent->write_event = NULL;
if( INVALID_HANDLE_VALUE != ev->registered_handle ) { }
if( 0 == UnregisterWait(ev->registered_handle) ) { if (!ent->read_event && !ent->write_event) {
error = GetLastError(); RB_REMOVE(event_map, &win32op->event_root, ent);
} free(ent);
ev->registered_handle = INVALID_HANDLE_VALUE; }
}
if( ev->ev_similar == ev ) {
/* Only one event in the queue. Remove everything. */
if( INVALID_HANDLE_VALUE != ev->base_handle ) { /* socket */
/* Now detach the base event from the socket. */
if( SOCKET_ERROR == WSAEventSelect( ev->ev_fd, ev->base_handle, 0) ) {
error = WSAGetLastError();
}
/* Finally, destroy the event handle. */
if( 0 == WSACloseEvent(ev->base_handle) ) {
error = WSAGetLastError();
}
ev->base_handle = INVALID_HANDLE_VALUE;
}
if (i != --win32op->n_events) {
win32op->events[i] = win32op->events[win32op->n_events];
}
return 0;
}
master = ev->ev_similar;
master->base_handle = ev->base_handle;
master->registered_handle = ev->registered_handle;
win32op->events[i] = master;
temp = master;
while( temp->ev_similar != ev ) {
temp = temp->ev_similar;
}
temp->ev_similar = master;
} else {
temp = master;
while( temp->ev_similar != ev ) {
temp = temp->ev_similar;
}
temp->ev_similar = ev->ev_similar;
}
win32_recompute_event( master );
return 0; return 0;
} }
int static void
win32_dispatch( struct event_base *base, struct win32op *win32op, fd_set_copy(struct win_fd_set *out, const struct win_fd_set *in)
struct timeval *tv )
{ {
DWORD milisec; out->fd_count = in->fd_count;
memcpy(out->fd_array, in->fd_array, in->fd_count * (sizeof(SOCKET)));
/*milisec = tv->tv_sec * 1000;
if( tv->tv_usec > 1000 ) {
milisec += tv->tv_usec / 1000;
}*/
milisec = tv->tv_sec; /* BLAH BLAH REMOVE ME */
SleepEx( milisec, TRUE );
if( 0 != signal_caught ) {
signal_process();
signal_recalc();
}
return 0;
} }
/*
static void dump_fd_set(struct win_fd_set *s)
{
unsigned int i;
printf("[ ");
for(i=0;i<s->fd_count;++i)
printf("%d ",(int)s->fd_array[i]);
printf("]\n");
}
*/
static void signal_handler(int sig) int
win32_dispatch(struct event_base *base, void *op,
struct timeval *tv)
{
struct win32op *win32op = op;
int res = 0;
int i;
int fd_count;
fd_set_copy(win32op->readset_out, win32op->readset_in);
fd_set_copy(win32op->exset_out, win32op->readset_in);
fd_set_copy(win32op->writeset_out, win32op->writeset_in);
fd_count =
(win32op->readset_out->fd_count > win32op->writeset_out->fd_count) ?
win32op->readset_out->fd_count : win32op->writeset_out->fd_count;
if (!fd_count) {
/* Windows doesn't like you to call select() with no sockets */
Sleep(timeval_to_ms(tv));
evsignal_process(base);
return (0);
}
res = select(fd_count,
(struct fd_set*)win32op->readset_out,
(struct fd_set*)win32op->writeset_out,
(struct fd_set*)win32op->exset_out, tv);
event_debug(("%s: select returned %d", __func__, res));
if(res <= 0) {
evsignal_process(base);
return res;
} else if (base->sig.evsignal_caught) {
evsignal_process(base);
}
for (i=0; i<win32op->readset_out->fd_count; ++i) {
struct event_entry *ent;
SOCKET s = win32op->readset_out->fd_array[i];
if ((ent = get_event_entry(win32op, s, 0)) && ent->read_event)
event_active(ent->read_event, EV_READ, 1);
}
for (i=0; i<win32op->exset_out->fd_count; ++i) {
struct event_entry *ent;
SOCKET s = win32op->exset_out->fd_array[i];
if ((ent = get_event_entry(win32op, s, 0)) && ent->read_event)
event_active(ent->read_event, EV_READ, 1);
}
for (i=0; i<win32op->writeset_out->fd_count; ++i) {
struct event_entry *ent;
SOCKET s = win32op->writeset_out->fd_array[i];
if ((ent = get_event_entry(win32op, s, 0)) && ent->write_event)
event_active(ent->write_event, EV_WRITE, 1);
}
#if 0
if (signal_recalc() == -1)
return (-1);
#endif
return (0);
}
void
win32_dealloc(struct event_base *_base, void *arg)
{
struct win32op *win32op = arg;
evsignal_dealloc(_base);
if (win32op->readset_in)
free(win32op->readset_in);
if (win32op->writeset_in)
free(win32op->writeset_in);
if (win32op->readset_out)
free(win32op->readset_out);
if (win32op->writeset_out)
free(win32op->writeset_out);
if (win32op->exset_out)
free(win32op->exset_out);
/* XXXXX free the tree. */
memset(win32op, 0, sizeof(win32op));
free(win32op);
}
#if 0
static void
signal_handler(int sig)
{ {
evsigcaught[sig]++; evsigcaught[sig]++;
signal_caught = 1; signal_caught = 1;
} }
int signal_recalc(void) int
signal_recalc(void)
{ {
opal_event_t *ev; struct event *ev;
/* Reinstall our signal handler. */ /* Reinstall our signal handler. */
TAILQ_FOREACH(ev, &opal_signalqueue, ev_signal_next) { TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) {
if( signal(OPAL_EVENT_SIGNAL(ev), signal_handler) == SIG_ERR) if((int)signal(EVENT_SIGNAL(ev), signal_handler) == -1)
return (-1); return (-1);
} }
return (0); return (0);
@ -454,18 +452,20 @@ int signal_recalc(void)
void void
signal_process(void) signal_process(void)
{ {
opal_event_t *ev; struct event *ev;
short ncalls; short ncalls;
TAILQ_FOREACH(ev, &opal_signalqueue, ev_signal_next) { TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) {
ncalls = evsigcaught[OPAL_EVENT_SIGNAL(ev)]; ncalls = evsigcaught[EVENT_SIGNAL(ev)];
if (ncalls) { if (ncalls) {
if (!(ev->ev_events & OPAL_EV_PERSIST)) if (!(ev->ev_events & EV_PERSIST))
opal_event_del(ev); event_del(ev);
opal_event_active(ev, OPAL_EV_SIGNAL, ncalls); event_active(ev, EV_SIGNAL, ncalls);
} }
} }
memset(evsigcaught, 0, sizeof(evsigcaught)); memset(evsigcaught, 0, sizeof(evsigcaught));
signal_caught = 0; signal_caught = 0;
} }
#endif

Просмотреть файл

@ -27,6 +27,11 @@
#include "opal_config.h" #include "opal_config.h"
#ifdef WIN32
#include <winsock2.h>
#include <windows.h>
#endif
#ifdef HAVE_VASPRINTF #ifdef HAVE_VASPRINTF
/* If we have vasprintf, we need to define this before we include stdio.h. */ /* If we have vasprintf, we need to define this before we include stdio.h. */
#ifndef _GNU_SOURCE #ifndef _GNU_SOURCE
@ -44,6 +49,7 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#endif #endif
#include <assert.h>
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -57,6 +63,7 @@
#include "event.h" #include "event.h"
struct evbuffer * struct evbuffer *
evbuffer_new(void) evbuffer_new(void)
{ {
@ -106,7 +113,7 @@ evbuffer_add_buffer(struct evbuffer *outbuf, struct evbuffer *inbuf)
/* /*
* Optimization comes with a price; we need to notify the * Optimization comes with a price; we need to notify the
* buffer if necessary of the changes. oldoff is the amount * buffer if necessary of the changes. oldoff is the amount
* of data that we tranfered from inbuf to outbuf * of data that we transfered from inbuf to outbuf
*/ */
if (inbuf->off != oldoff && inbuf->cb != NULL) if (inbuf->off != oldoff && inbuf->cb != NULL)
(*inbuf->cb)(inbuf, oldoff, inbuf->off, inbuf->cbarg); (*inbuf->cb)(inbuf, oldoff, inbuf->off, inbuf->cbarg);
@ -132,20 +139,33 @@ evbuffer_add_vprintf(struct evbuffer *buf, const char *fmt, va_list ap)
size_t space; size_t space;
size_t oldoff = buf->off; size_t oldoff = buf->off;
int sz; int sz;
va_list aq;
/* make sure that at least some space is available */
evbuffer_expand(buf, 64);
for (;;) { for (;;) {
buffer = (char*) buf->buffer + buf->off; size_t used = buf->misalign + buf->off;
space = buf->totallen - buf->misalign - buf->off; buffer = (char *)buf->buffer + buf->off;
assert(buf->totallen >= used);
space = buf->totallen - used;
#ifndef va_copy
#define va_copy(dst, src) memcpy(&(dst), &(src), sizeof(va_list))
#endif
va_copy(aq, ap);
#ifdef WIN32 #ifdef WIN32
sz = vsnprintf(buffer, space - 1, fmt, ap); sz = vsnprintf(buffer, space - 1, fmt, aq);
buffer[space - 1] = '\0'; buffer[space - 1] = '\0';
#else #else
sz = vsnprintf(buffer, space, fmt, ap); sz = vsnprintf(buffer, space, fmt, aq);
#endif #endif
if (sz == -1)
va_end(aq);
if (sz < 0)
return (-1); return (-1);
if ((size_t) sz < space) { if (sz < space) {
buf->off += sz; buf->off += sz;
if (buf->cb != NULL) if (buf->cb != NULL)
(*buf->cb)(buf, oldoff, buf->off, buf->cbarg); (*buf->cb)(buf, oldoff, buf->off, buf->cbarg);
@ -194,17 +214,17 @@ evbuffer_remove(struct evbuffer *buf, void *data, size_t datlen)
char * char *
evbuffer_readline(struct evbuffer *buffer) evbuffer_readline(struct evbuffer *buffer)
{ {
u_char *data = OPAL_EVBUFFER_DATA(buffer); u_char *data = EVBUFFER_DATA(buffer);
size_t len = OPAL_EVBUFFER_LENGTH(buffer); size_t len = EVBUFFER_LENGTH(buffer);
char *line; char *line;
u_int i; unsigned int i;
for (i = 0; i < (u_int) len; i++) { for (i = 0; i < len; i++) {
if (data[i] == '\r' || data[i] == '\n') if (data[i] == '\r' || data[i] == '\n')
break; break;
} }
if (i == (u_int) len) if (i == len)
return (NULL); return (NULL);
if ((line = malloc(i + 1)) == NULL) { if ((line = malloc(i + 1)) == NULL) {
@ -220,7 +240,7 @@ evbuffer_readline(struct evbuffer *buffer)
* Some protocols terminate a line with '\r\n', so check for * Some protocols terminate a line with '\r\n', so check for
* that, too. * that, too.
*/ */
if ( i < (u_int) len - 1 ) { if ( i < len - 1 ) {
char fch = data[i], sch = data[i+1]; char fch = data[i], sch = data[i+1];
/* Drain one more character if needed */ /* Drain one more character if needed */
@ -235,7 +255,7 @@ evbuffer_readline(struct evbuffer *buffer)
/* Adds data to an event buffer */ /* Adds data to an event buffer */
static inline void static void
evbuffer_align(struct evbuffer *buf) evbuffer_align(struct evbuffer *buf)
{ {
memmove(buf->orig_buffer, buf->buffer, buf->off); memmove(buf->orig_buffer, buf->buffer, buf->off);
@ -282,7 +302,7 @@ evbuffer_expand(struct evbuffer *buf, size_t datlen)
} }
int int
evbuffer_add(struct evbuffer *buf, void *data, size_t datlen) evbuffer_add(struct evbuffer *buf, const void *data, size_t datlen)
{ {
size_t need = buf->misalign + buf->off + datlen; size_t need = buf->misalign + buf->off + datlen;
size_t oldoff = buf->off; size_t oldoff = buf->off;
@ -337,12 +357,14 @@ evbuffer_read(struct evbuffer *buf, int fd, int howmuch)
u_char *p; u_char *p;
size_t oldoff = buf->off; size_t oldoff = buf->off;
int n = EVBUFFER_MAX_READ; int n = EVBUFFER_MAX_READ;
#ifdef WIN32
DWORD dwBytesRead;
#endif
#ifdef FIONREAD #if defined(FIONREAD)
#ifdef WIN32
long lng = n;
if (ioctlsocket(fd, FIONREAD, &lng) == -1 || (n=lng) == 0) {
#else
if (ioctl(fd, FIONREAD, &n) == -1 || n == 0) { if (ioctl(fd, FIONREAD, &n) == -1 || n == 0) {
#endif
n = EVBUFFER_MAX_READ; n = EVBUFFER_MAX_READ;
} else if (n > EVBUFFER_MAX_READ && n > howmuch) { } else if (n > EVBUFFER_MAX_READ && n > howmuch) {
/* /*
@ -352,7 +374,7 @@ evbuffer_read(struct evbuffer *buf, int fd, int howmuch)
* about it. If the reader does not tell us how much * about it. If the reader does not tell us how much
* data we should read, we artifically limit it. * data we should read, we artifically limit it.
*/ */
if ((size_t) n > buf->totallen << 2) if (n > buf->totallen << 2)
n = buf->totallen << 2; n = buf->totallen << 2;
if (n < EVBUFFER_MAX_READ) if (n < EVBUFFER_MAX_READ)
n = EVBUFFER_MAX_READ; n = EVBUFFER_MAX_READ;
@ -370,18 +392,13 @@ evbuffer_read(struct evbuffer *buf, int fd, int howmuch)
#ifndef WIN32 #ifndef WIN32
n = read(fd, p, howmuch); n = read(fd, p, howmuch);
#else
n = recv(fd, p, howmuch, 0);
#endif
if (n == -1) if (n == -1)
return (-1); return (-1);
if (n == 0) if (n == 0)
return (0); return (0);
#else
n = ReadFile((HANDLE)fd, p, howmuch, &dwBytesRead, NULL);
if (n == 0)
return (-1);
if (dwBytesRead == 0)
return (0);
n = dwBytesRead;
#endif
buf->off += n; buf->off += n;
@ -396,24 +413,16 @@ int
evbuffer_write(struct evbuffer *buffer, int fd) evbuffer_write(struct evbuffer *buffer, int fd)
{ {
int n; int n;
#ifdef WIN32
DWORD dwBytesWritten;
#endif
#ifndef WIN32 #ifndef WIN32
n = write(fd, buffer->buffer, buffer->off); n = write(fd, buffer->buffer, buffer->off);
#else
n = send(fd, buffer->buffer, buffer->off, 0);
#endif
if (n == -1) if (n == -1)
return (-1); return (-1);
if (n == 0) if (n == 0)
return (0); return (0);
#else
n = WriteFile((HANDLE)fd, buffer->buffer, buffer->off, &dwBytesWritten, NULL);
if (n == 0)
return (-1);
if (dwBytesWritten == 0)
return (0);
n = dwBytesWritten;
#endif
evbuffer_drain(buffer, n); evbuffer_drain(buffer, n);
return (n); return (n);
@ -422,16 +431,16 @@ evbuffer_write(struct evbuffer *buffer, int fd)
u_char * u_char *
evbuffer_find(struct evbuffer *buffer, const u_char *what, size_t len) evbuffer_find(struct evbuffer *buffer, const u_char *what, size_t len)
{ {
size_t remain = buffer->off; u_char *search = buffer->buffer, *end = search + buffer->off;
u_char *search = buffer->buffer;
u_char *p; u_char *p;
while ((p = memchr(search, *what, remain)) != NULL && remain >= len) { while (search < end &&
(p = memchr(search, *what, end - search)) != NULL) {
if (p + len > end)
break;
if (memcmp(p, what, len) == 0) if (memcmp(p, what, len) == 0)
return (p); return (p);
search = p + 1; search = p + 1;
remain = buffer->off - (size_t)(search - buffer->buffer);
} }
return (NULL); return (NULL);

Просмотреть файл

@ -9,6 +9,7 @@
# University of Stuttgart. All rights reserved. # University of Stuttgart. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California. # Copyright (c) 2004-2005 The Regents of the University of California.
# All rights reserved. # All rights reserved.
# Copyright (c) 2008 Cisco Systems, Inc. All rights reserved.
# $COPYRIGHT$ # $COPYRIGHT$
# #
# Additional copyrights may follow # Additional copyrights may follow
@ -18,4 +19,4 @@
noinst_HEADERS = queue.h _time.h _timeradd.h tree.h noinst_HEADERS = queue.h _time.h _timeradd.h

Просмотреть файл

@ -32,13 +32,10 @@
* @(#)time.h 8.2 (Berkeley) 7/10/94 * @(#)time.h 8.2 (Berkeley) 7/10/94
*/ */
#ifndef OMPI_TIME_H
#ifndef _SYS_TIME_H_ #ifndef _SYS_TIME_H_
#define _SYS_TIME_H_ #define _SYS_TIME_H_
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h> #include <sys/types.h>
#endif
/* /*
* Structure returned by gettimeofday(2) system call, * Structure returned by gettimeofday(2) system call,
@ -85,7 +82,24 @@ struct timezone {
(((tvp)->tv_sec == (uvp)->tv_sec) ? \ (((tvp)->tv_sec == (uvp)->tv_sec) ? \
((tvp)->tv_usec cmp (uvp)->tv_usec) : \ ((tvp)->tv_usec cmp (uvp)->tv_usec) : \
((tvp)->tv_sec cmp (uvp)->tv_sec)) ((tvp)->tv_sec cmp (uvp)->tv_sec))
#include <sys/_timeradd.h> #define timeradd(tvp, uvp, vvp) \
do { \
(vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \
(vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \
if ((vvp)->tv_usec >= 1000000) { \
(vvp)->tv_sec++; \
(vvp)->tv_usec -= 1000000; \
} \
} while (0)
#define timersub(tvp, uvp, vvp) \
do { \
(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
(vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
if ((vvp)->tv_usec < 0) { \
(vvp)->tv_sec--; \
(vvp)->tv_usec += 1000000; \
} \
} while (0)
/* Operations on timespecs. */ /* Operations on timespecs. */
#define timespecclear(tsp) (tsp)->tv_sec = (tsp)->tv_nsec = 0 #define timespecclear(tsp) (tsp)->tv_sec = (tsp)->tv_nsec = 0
@ -147,4 +161,3 @@ struct clockinfo {
/* --- stuff got cut here - niels --- */ /* --- stuff got cut here - niels --- */
#endif /* !_SYS_TIME_H_ */ #endif /* !_SYS_TIME_H_ */
#endif /* !OMPI_TIME_H */

Просмотреть файл

@ -45,6 +45,7 @@
#include <assert.h> #include <assert.h>
#include "event.h" #include "event.h"
#include "event-internal.h"
#include "evsignal.h" #include "evsignal.h"
#include "log.h" #include "log.h"
@ -54,12 +55,13 @@ extern opal_mutex_t opal_event_lock;
extern volatile sig_atomic_t opal_evsignal_caught; extern volatile sig_atomic_t opal_evsignal_caught;
/* due to limitations in the devpoll interface, we need to keep track of /* due to limitations in the devpoll interface, we need to keep track of
* all file descriptors outself. * all file descriptors outself.
*/ */
struct evdevpoll { struct evdevpoll {
struct opal_event *evread; struct event *evread;
struct opal_event *evwrite; struct event *evwrite;
}; };
struct devpollop { struct devpollop {
@ -68,24 +70,24 @@ struct devpollop {
struct pollfd *events; struct pollfd *events;
int nevents; int nevents;
int dpfd; int dpfd;
sigset_t evsigmask;
struct pollfd *changes; struct pollfd *changes;
int nchanges; int nchanges;
}; };
static void *devpoll_init (void); static void *devpoll_init (struct event_base *);
static int devpoll_add (void *, struct opal_event *); static int devpoll_add (void *, struct event *);
static int devpoll_del (void *, struct opal_event *); static int devpoll_del (void *, struct event *);
static int devpoll_recalc (struct event_base *, void *, int);
static int devpoll_dispatch (struct event_base *, void *, struct timeval *); static int devpoll_dispatch (struct event_base *, void *, struct timeval *);
static void devpoll_dealloc (struct event_base *, void *);
struct opal_eventop devpollops = { struct eventop devpollops = {
"devpoll", "devpoll",
devpoll_init, devpoll_init,
devpoll_add, devpoll_add,
devpoll_del, devpoll_del,
devpoll_recalc, devpoll_dispatch,
devpoll_dispatch devpoll_dealloc,
1 /* need reinit */
}; };
#define NEVENT 32000 #define NEVENT 32000
@ -126,8 +128,8 @@ devpoll_queue(struct devpollop *devpollop, int fd, int events) {
return(0); return(0);
} }
void * static void *
devpoll_init(void) devpoll_init(struct event_base *base)
{ {
int dpfd, nfiles = NEVENT; int dpfd, nfiles = NEVENT;
struct rlimit rl; struct rlimit rl;
@ -180,12 +182,12 @@ devpoll_init(void)
return (NULL); return (NULL);
} }
opal_evsignal_init(&devpollop->evsigmask); evsignal_init(base);
return (devpollop); return (devpollop);
} }
int static int
devpoll_recalc(struct event_base *base, void *arg, int max) devpoll_recalc(struct event_base *base, void *arg, int max)
{ {
struct devpollop *devpollop = arg; struct devpollop *devpollop = arg;
@ -209,42 +211,37 @@ devpoll_recalc(struct event_base *base, void *arg, int max)
devpollop->nfds = nfds; devpollop->nfds = nfds;
} }
return (opal_evsignal_recalc(&devpollop->evsigmask)); return (0);
} }
int static int
devpoll_dispatch(struct event_base *base, void *arg, struct timeval *tv) devpoll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
{ {
struct devpollop *devpollop = arg; struct devpollop *devpollop = arg;
struct pollfd *events = devpollop->events; struct pollfd *events = devpollop->events;
struct dvpoll dvp; struct dvpoll dvp;
struct evdevpoll *evdp; struct evdevpoll *evdp;
int i, res, timeout; int i, res, timeout = -1;
if (opal_evsignal_deliver(&devpollop->evsigmask) == -1)
return (-1);
if (devpollop->nchanges) if (devpollop->nchanges)
devpoll_commit(devpollop); devpoll_commit(devpollop);
timeout = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000; if (tv != NULL)
timeout = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
dvp.dp_fds = devpollop->events; dvp.dp_fds = devpollop->events;
dvp.dp_nfds = devpollop->nevents; dvp.dp_nfds = devpollop->nevents;
dvp.dp_timeout = timeout; dvp.dp_timeout = timeout;
/* we should release the lock if we're going to enter the /* we should release the lock if we're going to enter the
kernel in a multi-threaded application. However, if we're kernel in a multi-threaded application. However, if we're
single threaded, there's really no advantage to releasing single threaded, there's really no advantage to releasing
the lock and it just takes up time we could spend doing the lock and it just takes up time we could spend doing
something else. */ something else. */
OPAL_THREAD_UNLOCK(&opal_event_lock); OPAL_THREAD_UNLOCK(&opal_event_lock);
res = ioctl(devpollop->dpfd, DP_POLL, &dvp); res = ioctl(devpollop->dpfd, DP_POLL, &dvp);
OPAL_THREAD_LOCK(&opal_event_lock); OPAL_THREAD_LOCK(&opal_event_lock);
if (opal_evsignal_recalc(&devpollop->evsigmask) == -1)
return (-1);
if (res == -1) { if (res == -1) {
if (errno != EINTR) { if (errno != EINTR) {
@ -252,17 +249,18 @@ devpoll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
return (-1); return (-1);
} }
opal_evsignal_process(); evsignal_process(base);
return (0); return (0);
} else if (opal_evsignal_caught) } else if (base->sig.evsignal_caught) {
opal_evsignal_process(); evsignal_process(base);
}
event_debug(("%s: devpoll_wait reports %d", __func__, res)); event_debug(("%s: devpoll_wait reports %d", __func__, res));
for (i = 0; i < res; i++) { for (i = 0; i < res; i++) {
int which = 0; int which = 0;
int what = events[i].revents; int what = events[i].revents;
struct opal_event *evread = NULL, *evwrite = NULL; struct event *evread = NULL, *evwrite = NULL;
assert(events[i].fd < devpollop->nfds); assert(events[i].fd < devpollop->nfds);
evdp = &devpollop->fds[events[i].fd]; evdp = &devpollop->fds[events[i].fd];
@ -286,30 +284,30 @@ devpoll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
continue; continue;
if (evread != NULL && !(evread->ev_events & OPAL_EV_PERSIST)) if (evread != NULL && !(evread->ev_events & OPAL_EV_PERSIST))
opal_event_del_i(evread); event_del(evread);
if (evwrite != NULL && evwrite != evread && if (evwrite != NULL && evwrite != evread &&
!(evwrite->ev_events & OPAL_EV_PERSIST)) !(evwrite->ev_events & OPAL_EV_PERSIST))
opal_event_del_i(evwrite); event_del(evwrite);
if (evread != NULL) if (evread != NULL)
opal_event_active_i(evread, OPAL_EV_READ, 1); event_active(evread, OPAL_EV_READ, 1);
if (evwrite != NULL) if (evwrite != NULL)
opal_event_active_i(evwrite, OPAL_EV_WRITE, 1); event_active(evwrite, OPAL_EV_WRITE, 1);
} }
return (0); return (0);
} }
int static int
devpoll_add(void *arg, struct opal_event *ev) devpoll_add(void *arg, struct event *ev)
{ {
struct devpollop *devpollop = arg; struct devpollop *devpollop = arg;
struct evdevpoll *evdp; struct evdevpoll *evdp;
int fd, events; int fd, events;
if (ev->ev_events & OPAL_EV_SIGNAL) if (ev->ev_events & OPAL_EV_SIGNAL)
return (opal_evsignal_add(&devpollop->evsigmask, ev)); return (evsignal_add(ev));
fd = ev->ev_fd; fd = ev->ev_fd;
if (fd >= devpollop->nfds) { if (fd >= devpollop->nfds) {
@ -355,8 +353,8 @@ devpoll_add(void *arg, struct opal_event *ev)
return (0); return (0);
} }
int static int
devpoll_del(void *arg, struct opal_event *ev) devpoll_del(void *arg, struct event *ev)
{ {
struct devpollop *devpollop = arg; struct devpollop *devpollop = arg;
struct evdevpoll *evdp; struct evdevpoll *evdp;
@ -364,7 +362,7 @@ devpoll_del(void *arg, struct opal_event *ev)
int needwritedelete = 1, needreaddelete = 1; int needwritedelete = 1, needreaddelete = 1;
if (ev->ev_events & OPAL_EV_SIGNAL) if (ev->ev_events & OPAL_EV_SIGNAL)
return (opal_evsignal_del(&devpollop->evsigmask, ev)); return (evsignal_del(ev));
fd = ev->ev_fd; fd = ev->ev_fd;
if (fd >= devpollop->nfds) if (fd >= devpollop->nfds)
@ -411,3 +409,22 @@ devpoll_del(void *arg, struct opal_event *ev)
return (0); return (0);
} }
static void
devpoll_dealloc(struct event_base *base, void *arg)
{
struct devpollop *devpollop = arg;
evsignal_dealloc(base);
if (devpollop->fds)
free(devpollop->fds);
if (devpollop->events)
free(devpollop->events);
if (devpollop->changes)
free(devpollop->changes);
if (devpollop->dpfd >= 0)
close(devpollop->dpfd);
memset(devpollop, 0, sizeof(struct devpollop));
free(devpollop);
}

Просмотреть файл

@ -25,7 +25,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "opal_config.h" #include "opal_config.h"
#ifdef HAVE_STDINT_H #ifdef HAVE_STDINT_H
#include <stdint.h> #include <stdint.h>
#endif #endif
@ -55,6 +54,7 @@
#endif #endif
#include "event.h" #include "event.h"
#include "event-internal.h"
#include "evsignal.h" #include "evsignal.h"
#include "log.h" #include "log.h"
@ -67,8 +67,8 @@ extern opal_mutex_t opal_event_lock;
* all file descriptors outself. * all file descriptors outself.
*/ */
struct evepoll { struct evepoll {
struct opal_event *evread; struct event *evread;
struct opal_event *evwrite; struct event *evwrite;
}; };
struct epollop { struct epollop {
@ -77,22 +77,22 @@ struct epollop {
struct epoll_event *events; struct epoll_event *events;
int nevents; int nevents;
int epfd; int epfd;
sigset_t evsigmask;
}; };
static void *epoll_init (void); static void *epoll_init (struct event_base *);
static int epoll_add (void *, struct opal_event *); static int epoll_add (void *, struct event *);
static int epoll_del (void *, struct opal_event *); static int epoll_del (void *, struct event *);
static int epoll_recalc (struct event_base *, void *, int);
static int epoll_dispatch (struct event_base *, void *, struct timeval *); static int epoll_dispatch (struct event_base *, void *, struct timeval *);
static void epoll_dealloc (struct event_base *, void *);
struct opal_eventop opal_epollops = { struct eventop epollops = {
"epoll", "epoll",
epoll_init, epoll_init,
epoll_add, epoll_add,
epoll_del, epoll_del,
epoll_recalc, epoll_dispatch,
epoll_dispatch epoll_dealloc,
1 /* need reinit */
}; };
#ifdef HAVE_SETFD #ifdef HAVE_SETFD
@ -107,7 +107,7 @@ struct opal_eventop opal_epollops = {
#define NEVENT 32000 #define NEVENT 32000
static void * static void *
epoll_init(void) epoll_init(struct event_base *base)
{ {
int epfd, nfiles = NEVENT; int epfd, nfiles = NEVENT;
struct rlimit rl; struct rlimit rl;
@ -157,8 +157,9 @@ epoll_init(void)
} }
epollop->nfds = nfiles; epollop->nfds = nfiles;
opal_evsignal_init(&epollop->evsigmask); #if OPAL_EVENT_USE_SIGNALS
evsignal_init(base);
#endif
return (epollop); return (epollop);
} }
@ -166,6 +167,7 @@ static int
epoll_recalc(struct event_base *base, void *arg, int max) epoll_recalc(struct event_base *base, void *arg, int max)
{ {
struct epollop *epollop = arg; struct epollop *epollop = arg;
if (max > epollop->nfds) { if (max > epollop->nfds) {
struct evepoll *fds; struct evepoll *fds;
int nfds; int nfds;
@ -185,81 +187,72 @@ epoll_recalc(struct event_base *base, void *arg, int max)
epollop->nfds = nfds; epollop->nfds = nfds;
} }
return (opal_evsignal_recalc(&epollop->evsigmask)); return (0);
} }
int static int
epoll_dispatch(struct event_base *base, void *arg, struct timeval *tv) epoll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
{ {
struct epollop *epollop = arg; struct epollop *epollop = arg;
struct epoll_event *events = epollop->events; struct epoll_event *events = epollop->events;
struct evepoll *evep; struct evepoll *evep;
int i, res, timeout; int i, res, timeout = -1;
if (opal_evsignal_deliver(&epollop->evsigmask) == -1) if (tv != NULL)
return (-1); timeout = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
timeout = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
/* we should release the lock if we're going to enter the /* we should release the lock if we're going to enter the
kernel in a multi-threaded application. However, if we're kernel in a multi-threaded application. However, if we're
single threaded, there's really no advantage to releasing single threaded, there's really no advantage to releasing
the lock and it just takes up time we could spend doing the lock and it just takes up time we could spend doing
something else. */ something else. */
OPAL_THREAD_UNLOCK(&opal_event_lock); OPAL_THREAD_UNLOCK(&opal_event_lock);
res = epoll_wait(epollop->epfd, events, epollop->nevents, timeout); res = epoll_wait(epollop->epfd, events, epollop->nevents, timeout);
OPAL_THREAD_LOCK(&opal_event_lock); OPAL_THREAD_LOCK(&opal_event_lock);
if (opal_evsignal_recalc(&epollop->evsigmask) == -1)
return (-1);
if (res == -1) { if (res == -1) {
if (errno != EINTR) { if (errno != EINTR) {
event_warn("epoll_wait"); event_warn("epoll_wait");
return (-1); return (-1);
} }
#if OPAL_EVENT_USE_SIGNALS
opal_evsignal_process(); evsignal_process(base);
#endif
return (0); return (0);
} else if (opal_evsignal_caught) } else if (base->sig.evsignal_caught) {
opal_evsignal_process(); #if OPAL_EVENT_USE_SIGNALS
evsignal_process(base);
#endif
}
event_debug(("%s: epoll_wait reports %d", __func__, res)); event_debug(("%s: epoll_wait reports %d", __func__, res));
for (i = 0; i < res; i++) { for (i = 0; i < res; i++) {
int which = 0;
int what = events[i].events; int what = events[i].events;
struct opal_event *evread = NULL, *evwrite = NULL; struct event *evread = NULL, *evwrite = NULL;
evep = (struct evepoll *)events[i].data.ptr; evep = (struct evepoll *)events[i].data.ptr;
if (what & EPOLLHUP) if (what & (EPOLLHUP|EPOLLERR)) {
what |= EPOLLIN | EPOLLOUT;
else if (what & EPOLLERR)
what |= EPOLLIN | EPOLLOUT;
if (what & EPOLLIN) {
evread = evep->evread; evread = evep->evread;
which |= OPAL_EV_READ;
}
if (what & EPOLLOUT) {
evwrite = evep->evwrite; evwrite = evep->evwrite;
which |= OPAL_EV_WRITE; } else {
if (what & EPOLLIN) {
evread = evep->evread;
}
if (what & EPOLLOUT) {
evwrite = evep->evwrite;
}
} }
if (!which) if (!(evread||evwrite))
continue; continue;
if (evread != NULL && !(evread->ev_events & OPAL_EV_PERSIST))
opal_event_del_i(evread);
if (evwrite != NULL && evwrite != evread &&
!(evwrite->ev_events & OPAL_EV_PERSIST))
opal_event_del_i(evwrite);
if (evread != NULL) if (evread != NULL)
opal_event_active_i(evread, OPAL_EV_READ, 1); event_active(evread, EV_READ, 1);
if (evwrite != NULL) if (evwrite != NULL)
opal_event_active_i(evwrite, OPAL_EV_WRITE, 1); event_active(evwrite, EV_WRITE, 1);
} }
return (0); return (0);
@ -267,15 +260,17 @@ epoll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
static int static int
epoll_add(void *arg, struct opal_event *ev) epoll_add(void *arg, struct event *ev)
{ {
struct epollop *epollop = arg; struct epollop *epollop = arg;
struct epoll_event epev = {0, {0}}; struct epoll_event epev = {0, {0}};
struct evepoll *evep; struct evepoll *evep;
int fd, op, events; int fd, op, events;
if (ev->ev_events & OPAL_EV_SIGNAL) #if OPAL_EVENT_USE_SIGNALS
return (opal_evsignal_add(&epollop->evsigmask, ev)); if (ev->ev_events & EV_SIGNAL)
return (evsignal_add(ev));
#endif
fd = ev->ev_fd; fd = ev->ev_fd;
if (fd >= epollop->nfds) { if (fd >= epollop->nfds) {
@ -295,9 +290,9 @@ epoll_add(void *arg, struct opal_event *ev)
op = EPOLL_CTL_MOD; op = EPOLL_CTL_MOD;
} }
if (ev->ev_events & OPAL_EV_READ) if (ev->ev_events & EV_READ)
events |= EPOLLIN; events |= EPOLLIN;
if (ev->ev_events & OPAL_EV_WRITE) if (ev->ev_events & EV_WRITE)
events |= EPOLLOUT; events |= EPOLLOUT;
epev.data.ptr = evep; epev.data.ptr = evep;
@ -306,16 +301,16 @@ epoll_add(void *arg, struct opal_event *ev)
return (-1); return (-1);
/* Update events responsible */ /* Update events responsible */
if (ev->ev_events & OPAL_EV_READ) if (ev->ev_events & EV_READ)
evep->evread = ev; evep->evread = ev;
if (ev->ev_events & OPAL_EV_WRITE) if (ev->ev_events & EV_WRITE)
evep->evwrite = ev; evep->evwrite = ev;
return (0); return (0);
} }
static int static int
epoll_del(void *arg, struct opal_event *ev) epoll_del(void *arg, struct event *ev)
{ {
struct epollop *epollop = arg; struct epollop *epollop = arg;
struct epoll_event epev = {0, {0}}; struct epoll_event epev = {0, {0}};
@ -323,8 +318,10 @@ epoll_del(void *arg, struct opal_event *ev)
int fd, events, op; int fd, events, op;
int needwritedelete = 1, needreaddelete = 1; int needwritedelete = 1, needreaddelete = 1;
if (ev->ev_events & OPAL_EV_SIGNAL) #if OPAL_EVENT_USE_SIGNALS
return (opal_evsignal_del(&epollop->evsigmask, ev)); if (ev->ev_events & EV_SIGNAL)
return (evsignal_del(ev));
#endif
fd = ev->ev_fd; fd = ev->ev_fd;
if (fd >= epollop->nfds) if (fd >= epollop->nfds)
@ -334,9 +331,9 @@ epoll_del(void *arg, struct opal_event *ev)
op = EPOLL_CTL_DEL; op = EPOLL_CTL_DEL;
events = 0; events = 0;
if (ev->ev_events & OPAL_EV_READ) if (ev->ev_events & EV_READ)
events |= EPOLLIN; events |= EPOLLIN;
if (ev->ev_events & OPAL_EV_WRITE) if (ev->ev_events & EV_WRITE)
events |= EPOLLOUT; events |= EPOLLOUT;
if ((events & (EPOLLIN|EPOLLOUT)) != (EPOLLIN|EPOLLOUT)) { if ((events & (EPOLLIN|EPOLLOUT)) != (EPOLLIN|EPOLLOUT)) {
@ -364,3 +361,20 @@ epoll_del(void *arg, struct opal_event *ev)
return (0); return (0);
} }
static void
epoll_dealloc(struct event_base *base, void *arg)
{
struct epollop *epollop = arg;
evsignal_dealloc(base);
if (epollop->fds)
free(epollop->fds);
if (epollop->events)
free(epollop->events);
if (epollop->epfd >= 0)
close(epollop->epfd);
memset(epollop, 0, sizeof(struct epollop));
free(epollop);
}

Просмотреть файл

@ -25,6 +25,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "opal_config.h" #include "opal_config.h"
#ifdef HAVE_STDINT_H #ifdef HAVE_STDINT_H
#include <stdint.h> #include <stdint.h>
#endif #endif

Просмотреть файл

@ -24,11 +24,14 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "opal_config.h" #include "opal_config.h"
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_SYS_TIME_H #ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif #endif
@ -41,20 +44,25 @@
#include <stdarg.h> #include <stdarg.h>
#endif #endif
#ifdef WIN32
#include <winsock2.h>
#endif
#include "evutil.h"
#include "event.h" #include "event.h"
/* prototypes */ /* prototypes */
void bufferevent_setwatermark(struct bufferevent *, short, size_t, size_t); static void bufferevent_setwatermark(struct bufferevent *, short, size_t, size_t);
static void bufferevent_read_pressure_cb(struct evbuffer *, size_t, size_t, void *); static void bufferevent_read_pressure_cb(struct evbuffer *, size_t, size_t, void *);
static int static int
bufferevent_add(struct opal_event *ev, int timeout) bufferevent_add(struct event *ev, int timeout)
{ {
struct timeval tv, *ptv = NULL; struct timeval tv, *ptv = NULL;
if (timeout) { if (timeout) {
timerclear(&tv); evutil_timerclear(&tv);
tv.tv_sec = timeout; tv.tv_sec = timeout;
ptv = &tv; ptv = &tv;
} }
@ -72,13 +80,13 @@ bufferevent_read_pressure_cb(struct evbuffer *buf, size_t old, size_t now,
void *arg) { void *arg) {
struct bufferevent *bufev = arg; struct bufferevent *bufev = arg;
/* /*
* If we are below the watermak then reschedule reading if it's * If we are below the watermark then reschedule reading if it's
* still enabled. * still enabled.
*/ */
if (bufev->wm_read.high == 0 || now < bufev->wm_read.high) { if (bufev->wm_read.high == 0 || now < bufev->wm_read.high) {
evbuffer_setcb(buf, NULL, NULL); evbuffer_setcb(buf, NULL, NULL);
if (bufev->enabled & OPAL_EV_READ) if (bufev->enabled & EV_READ)
bufferevent_add(&bufev->ev_read, bufev->timeout_read); bufferevent_add(&bufev->ev_read, bufev->timeout_read);
} }
} }
@ -88,23 +96,31 @@ bufferevent_readcb(int fd, short event, void *arg)
{ {
struct bufferevent *bufev = arg; struct bufferevent *bufev = arg;
int res = 0; int res = 0;
short what = OPAL_EVBUFFER_READ; short what = EVBUFFER_READ;
size_t len; size_t len;
int howmuch = -1;
if (event == OPAL_EV_TIMEOUT) { if (event == EV_TIMEOUT) {
what |= OPAL_EVBUFFER_TIMEOUT; what |= EVBUFFER_TIMEOUT;
goto error; goto error;
} }
res = evbuffer_read(bufev->input, fd, -1); /*
* If we have a high watermark configured then we don't want to
* read more data than would make us reach the watermark.
*/
if (bufev->wm_read.high != 0)
howmuch = bufev->wm_read.high;
res = evbuffer_read(bufev->input, fd, howmuch);
if (res == -1) { if (res == -1) {
if (errno == EAGAIN || errno == EINTR) if (errno == EAGAIN || errno == EINTR)
goto reschedule; goto reschedule;
/* error case */ /* error case */
what |= OPAL_EVBUFFER_ERROR; what |= EVBUFFER_ERROR;
} else if (res == 0) { } else if (res == 0) {
/* eof case */ /* eof case */
what |= OPAL_EVBUFFER_EOF; what |= EVBUFFER_EOF;
} }
if (res <= 0) if (res <= 0)
@ -113,7 +129,7 @@ bufferevent_readcb(int fd, short event, void *arg)
bufferevent_add(&bufev->ev_read, bufev->timeout_read); bufferevent_add(&bufev->ev_read, bufev->timeout_read);
/* See if this callbacks meets the water marks */ /* See if this callbacks meets the water marks */
len = OPAL_EVBUFFER_LENGTH(bufev->input); len = EVBUFFER_LENGTH(bufev->input);
if (bufev->wm_read.low != 0 && len < bufev->wm_read.low) if (bufev->wm_read.low != 0 && len < bufev->wm_read.low)
return; return;
if (bufev->wm_read.high != 0 && len > bufev->wm_read.high) { if (bufev->wm_read.high != 0 && len > bufev->wm_read.high) {
@ -126,7 +142,8 @@ bufferevent_readcb(int fd, short event, void *arg)
} }
/* Invoke the user callback - must always be called last */ /* Invoke the user callback - must always be called last */
(*bufev->readcb)(bufev, bufev->cbarg); if (bufev->readcb != NULL)
(*bufev->readcb)(bufev, bufev->cbarg);
return; return;
reschedule: reschedule:
@ -142,44 +159,53 @@ bufferevent_writecb(int fd, short event, void *arg)
{ {
struct bufferevent *bufev = arg; struct bufferevent *bufev = arg;
int res = 0; int res = 0;
short what = OPAL_EVBUFFER_WRITE; short what = EVBUFFER_WRITE;
if (event == OPAL_EV_TIMEOUT) { if (event == EV_TIMEOUT) {
what |= OPAL_EVBUFFER_TIMEOUT; what |= EVBUFFER_TIMEOUT;
goto error; goto error;
} }
if (OPAL_EVBUFFER_LENGTH(bufev->output)) { if (EVBUFFER_LENGTH(bufev->output)) {
res = evbuffer_write(bufev->output, fd); res = evbuffer_write(bufev->output, fd);
if (res == -1) { if (res == -1) {
#ifndef WIN32
/*todo. evbuffer uses WriteFile when WIN32 is set. WIN32 system calls do not
*set errno. thus this error checking is not portable*/
if (errno == EAGAIN || if (errno == EAGAIN ||
errno == EINTR || errno == EINTR ||
errno == EINPROGRESS) errno == EINPROGRESS)
goto reschedule; goto reschedule;
/* error case */ /* error case */
what |= OPAL_EVBUFFER_ERROR; what |= EVBUFFER_ERROR;
#else
goto reschedule;
#endif
} else if (res == 0) { } else if (res == 0) {
/* eof case */ /* eof case */
what |= OPAL_EVBUFFER_EOF; what |= EVBUFFER_EOF;
} }
if (res <= 0) if (res <= 0)
goto error; goto error;
} }
if (OPAL_EVBUFFER_LENGTH(bufev->output) != 0) if (EVBUFFER_LENGTH(bufev->output) != 0)
bufferevent_add(&bufev->ev_write, bufev->timeout_write); bufferevent_add(&bufev->ev_write, bufev->timeout_write);
/* /*
* Invoke the user callback if our buffer is drained or below the * Invoke the user callback if our buffer is drained or below the
* low watermark. * low watermark.
*/ */
if (OPAL_EVBUFFER_LENGTH(bufev->output) <= bufev->wm_write.low) if (bufev->writecb != NULL &&
EVBUFFER_LENGTH(bufev->output) <= bufev->wm_write.low)
(*bufev->writecb)(bufev, bufev->cbarg); (*bufev->writecb)(bufev, bufev->cbarg);
return; return;
reschedule: reschedule:
if (OPAL_EVBUFFER_LENGTH(bufev->output) != 0) if (EVBUFFER_LENGTH(bufev->output) != 0)
bufferevent_add(&bufev->ev_write, bufev->timeout_write); bufferevent_add(&bufev->ev_write, bufev->timeout_write);
return; return;
@ -193,6 +219,9 @@ bufferevent_writecb(int fd, short event, void *arg)
* The read callback is invoked whenever we read new data. * The read callback is invoked whenever we read new data.
* The write callback is invoked whenever the output buffer is drained. * The write callback is invoked whenever the output buffer is drained.
* The error callback is invoked on a write/read error or on EOF. * The error callback is invoked on a write/read error or on EOF.
*
* Both read and write callbacks maybe NULL. The error callback is not
* allowed to be NULL and have to be provided always.
*/ */
struct bufferevent * struct bufferevent *
@ -215,8 +244,8 @@ bufferevent_new(int fd, evbuffercb readcb, evbuffercb writecb,
return (NULL); return (NULL);
} }
opal_event_set(&bufev->ev_read, fd, OPAL_EV_READ, bufferevent_readcb, bufev); event_set(&bufev->ev_read, fd, EV_READ, bufferevent_readcb, bufev);
opal_event_set(&bufev->ev_write, fd, OPAL_EV_WRITE, bufferevent_writecb, bufev); event_set(&bufev->ev_write, fd, EV_WRITE, bufferevent_writecb, bufev);
bufev->readcb = readcb; bufev->readcb = readcb;
bufev->writecb = writecb; bufev->writecb = writecb;
@ -224,7 +253,12 @@ bufferevent_new(int fd, evbuffercb readcb, evbuffercb writecb,
bufev->cbarg = cbarg; bufev->cbarg = cbarg;
bufev->enabled = OPAL_EV_READ | OPAL_EV_WRITE; /*
* Set to EV_WRITE so that using bufferevent_write is going to
* trigger a callback. Reading needs to be explicitly enabled
* because otherwise no data will be available.
*/
bufev->enabled = EV_WRITE;
return (bufev); return (bufev);
} }
@ -232,9 +266,9 @@ bufferevent_new(int fd, evbuffercb readcb, evbuffercb writecb,
int int
bufferevent_priority_set(struct bufferevent *bufev, int priority) bufferevent_priority_set(struct bufferevent *bufev, int priority)
{ {
if (opal_event_priority_set(&bufev->ev_read, priority) == -1) if (event_priority_set(&bufev->ev_read, priority) == -1)
return (-1); return (-1);
if (opal_event_priority_set(&bufev->ev_write, priority) == -1) if (event_priority_set(&bufev->ev_write, priority) == -1)
return (-1); return (-1);
return (0); return (0);
@ -245,8 +279,8 @@ bufferevent_priority_set(struct bufferevent *bufev, int priority)
void void
bufferevent_free(struct bufferevent *bufev) bufferevent_free(struct bufferevent *bufev)
{ {
opal_event_del(&bufev->ev_read); event_del(&bufev->ev_read);
opal_event_del(&bufev->ev_write); event_del(&bufev->ev_write);
evbuffer_free(bufev->input); evbuffer_free(bufev->input);
evbuffer_free(bufev->output); evbuffer_free(bufev->output);
@ -260,7 +294,7 @@ bufferevent_free(struct bufferevent *bufev)
*/ */
int int
bufferevent_write(struct bufferevent *bufev, void *data, size_t size) bufferevent_write(struct bufferevent *bufev, const void *data, size_t size)
{ {
int res; int res;
@ -270,7 +304,7 @@ bufferevent_write(struct bufferevent *bufev, void *data, size_t size)
return (res); return (res);
/* If everything is okay, we need to schedule a write */ /* If everything is okay, we need to schedule a write */
if (size > 0 && (bufev->enabled & OPAL_EV_WRITE)) if (size > 0 && (bufev->enabled & EV_WRITE))
bufferevent_add(&bufev->ev_write, bufev->timeout_write); bufferevent_add(&bufev->ev_write, bufev->timeout_write);
return (res); return (res);
@ -308,11 +342,11 @@ bufferevent_read(struct bufferevent *bufev, void *data, size_t size)
int int
bufferevent_enable(struct bufferevent *bufev, short event) bufferevent_enable(struct bufferevent *bufev, short event)
{ {
if (event & OPAL_EV_READ) { if (event & EV_READ) {
if (bufferevent_add(&bufev->ev_read, bufev->timeout_read) == -1) if (bufferevent_add(&bufev->ev_read, bufev->timeout_read) == -1)
return (-1); return (-1);
} }
if (event & OPAL_EV_WRITE) { if (event & EV_WRITE) {
if (bufferevent_add(&bufev->ev_write, bufev->timeout_write) == -1) if (bufferevent_add(&bufev->ev_write, bufev->timeout_write) == -1)
return (-1); return (-1);
} }
@ -324,12 +358,12 @@ bufferevent_enable(struct bufferevent *bufev, short event)
int int
bufferevent_disable(struct bufferevent *bufev, short event) bufferevent_disable(struct bufferevent *bufev, short event)
{ {
if (event & OPAL_EV_READ) { if (event & EV_READ) {
if (opal_event_del(&bufev->ev_read) == -1) if (event_del(&bufev->ev_read) == -1)
return (-1); return (-1);
} }
if (event & OPAL_EV_WRITE) { if (event & EV_WRITE) {
if (opal_event_del(&bufev->ev_write) == -1) if (event_del(&bufev->ev_write) == -1)
return (-1); return (-1);
} }
@ -356,17 +390,30 @@ void
bufferevent_setwatermark(struct bufferevent *bufev, short events, bufferevent_setwatermark(struct bufferevent *bufev, short events,
size_t lowmark, size_t highmark) size_t lowmark, size_t highmark)
{ {
if (events & OPAL_EV_READ) { if (events & EV_READ) {
bufev->wm_read.low = lowmark; bufev->wm_read.low = lowmark;
bufev->wm_read.high = highmark; bufev->wm_read.high = highmark;
} }
if (events & OPAL_EV_WRITE) { if (events & EV_WRITE) {
bufev->wm_write.low = lowmark; bufev->wm_write.low = lowmark;
bufev->wm_write.high = highmark; bufev->wm_write.high = highmark;
} }
/* If the watermarks changed then see if we should call read again */ /* If the watermarks changed then see if we should call read again */
bufferevent_read_pressure_cb(bufev->input, bufferevent_read_pressure_cb(bufev->input,
0, OPAL_EVBUFFER_LENGTH(bufev->input), bufev); 0, EVBUFFER_LENGTH(bufev->input), bufev);
}
int
bufferevent_base_set(struct event_base *base, struct bufferevent *bufev)
{
int res;
res = event_base_set(base, &bufev->ev_read);
if (res == -1)
return (res);
res = event_base_set(base, &bufev->ev_write);
return (res);
} }

262
opal/event/event-config.h Обычный файл
Просмотреть файл

@ -0,0 +1,262 @@
/* event-config.h
* Generated by autoconf; post-processed by libevent.
* Do not edit this file.
* Do not rely on macros in this file existing in later versions.
*/
#ifndef _EVENT_CONFIG_H_
#define _EVENT_CONFIG_H_
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.in by autoheader. */
/* 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 to 1 if you have the `clock_gettime' function. */
/* #undef _EVENT_HAVE_CLOCK_GETTIME */
/* Define if /dev/poll is available */
/* #undef _EVENT_HAVE_DEVPOLL */
/* Define to 1 if you have the <dlfcn.h> header file. */
#define _EVENT_HAVE_DLFCN_H 1
/* Define if your system supports the epoll system calls */
/* #undef _EVENT_HAVE_EPOLL */
/* Define to 1 if you have the `epoll_ctl' function. */
/* #undef _EVENT_HAVE_EPOLL_CTL */
/* Define if your system supports event ports */
/* #undef _EVENT_HAVE_EVENT_PORTS */
/* Define to 1 if you have the `fcntl' function. */
#define _EVENT_HAVE_FCNTL 1
/* Define to 1 if you have the <fcntl.h> header file. */
#define _EVENT_HAVE_FCNTL_H 1
/* Define to 1 if you have the `getaddrinfo' function. */
#define _EVENT_HAVE_GETADDRINFO 1
/* Define to 1 if you have the `getnameinfo' function. */
#define _EVENT_HAVE_GETNAMEINFO 1
/* Define to 1 if you have the `gettimeofday' function. */
#define _EVENT_HAVE_GETTIMEOFDAY 1
/* Define to 1 if you have the `inet_ntop' function. */
#define _EVENT_HAVE_INET_NTOP 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define _EVENT_HAVE_INTTYPES_H 1
/* Define to 1 if you have the `kqueue' function. */
#define _EVENT_HAVE_KQUEUE 1
/* Define to 1 if you have the `nsl' library (-lnsl). */
/* #undef _EVENT_HAVE_LIBNSL */
/* Define to 1 if you have the `resolv' library (-lresolv). */
#define _EVENT_HAVE_LIBRESOLV 1
/* Define to 1 if you have the `rt' library (-lrt). */
/* #undef _EVENT_HAVE_LIBRT */
/* Define to 1 if you have the `socket' library (-lsocket). */
/* #undef _EVENT_HAVE_LIBSOCKET */
/* Define to 1 if you have the <memory.h> header file. */
#define _EVENT_HAVE_MEMORY_H 1
/* Define to 1 if you have the <netinet/in6.h> header file. */
/* #undef _EVENT_HAVE_NETINET_IN6_H */
/* Define to 1 if you have the `poll' function. */
#define _EVENT_HAVE_POLL 1
/* Define to 1 if you have the <poll.h> header file. */
#define _EVENT_HAVE_POLL_H 1
/* Define to 1 if you have the `port_create' function. */
/* #undef _EVENT_HAVE_PORT_CREATE */
/* Define to 1 if you have the <port.h> header file. */
/* #undef _EVENT_HAVE_PORT_H */
/* Define to 1 if you have the `select' function. */
#define _EVENT_HAVE_SELECT 1
/* Define if F_SETFD is defined in <fcntl.h> */
#define _EVENT_HAVE_SETFD 1
/* Define to 1 if you have the `sigaction' function. */
#define _EVENT_HAVE_SIGACTION 1
/* Define to 1 if you have the `signal' function. */
#define _EVENT_HAVE_SIGNAL 1
/* Define to 1 if you have the <signal.h> header file. */
#define _EVENT_HAVE_SIGNAL_H 1
/* Define to 1 if you have the <stdarg.h> header file. */
#define _EVENT_HAVE_STDARG_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define _EVENT_HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define _EVENT_HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define _EVENT_HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define _EVENT_HAVE_STRING_H 1
/* Define to 1 if you have the `strlcpy' function. */
#define _EVENT_HAVE_STRLCPY 1
/* Define to 1 if you have the `strsep' function. */
#define _EVENT_HAVE_STRSEP 1
/* Define to 1 if you have the `strtok_r' function. */
#define _EVENT_HAVE_STRTOK_R 1
/* Define to 1 if you have the `strtoll' function. */
#define _EVENT_HAVE_STRTOLL 1
/* Define to 1 if the system has the type `struct in6_addr'. */
#define _EVENT_HAVE_STRUCT_IN6_ADDR 1
/* Define to 1 if you have the <sys/devpoll.h> header file. */
/* #undef _EVENT_HAVE_SYS_DEVPOLL_H */
/* Define to 1 if you have the <sys/epoll.h> header file. */
/* #undef _EVENT_HAVE_SYS_EPOLL_H */
/* Define to 1 if you have the <sys/event.h> header file. */
#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 to 1 if you have the <sys/param.h> header file. */
#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 to 1 if you have the <sys/select.h> header file. */
#define _EVENT_HAVE_SYS_SELECT_H 1
/* Define to 1 if you have the <sys/socket.h> header file. */
#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 to 1 if you have the <sys/time.h> header file. */
#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 if TAILQ_FOREACH is defined in <sys/queue.h> */
#define _EVENT_HAVE_TAILQFOREACH 1
/* Define if timeradd is defined in <sys/time.h> */
#define _EVENT_HAVE_TIMERADD 1
/* Define if timerclear is defined in <sys/time.h> */
#define _EVENT_HAVE_TIMERCLEAR 1
/* Define if timercmp is defined in <sys/time.h> */
#define _EVENT_HAVE_TIMERCMP 1
/* Define if timerisset is defined in <sys/time.h> */
#define _EVENT_HAVE_TIMERISSET 1
/* Define to 1 if the system has the type `uint16_t'. */
#define _EVENT_HAVE_UINT16_T 1
/* Define to 1 if the system has the type `uint32_t'. */
#define _EVENT_HAVE_UINT32_T 1
/* Define to 1 if the system has the type `uint64_t'. */
#define _EVENT_HAVE_UINT64_T 1
/* Define to 1 if the system has the type `uint8_t'. */
#define _EVENT_HAVE_UINT8_T 1
/* Define to 1 if you have the <unistd.h> header file. */
#define _EVENT_HAVE_UNISTD_H 1
/* Define to 1 if you have the `vasprintf' function. */
#define _EVENT_HAVE_VASPRINTF 1
/* Define if kqueue works correctly with pipes */
#define _EVENT_HAVE_WORKING_KQUEUE 1
/* 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 to the version of this package. */
#define _EVENT_PACKAGE_VERSION ""
/* The size of `int', as computed by sizeof. */
#define _EVENT_SIZEOF_INT 4
/* The size of `long', as computed by sizeof. */
#define _EVENT_SIZEOF_LONG 4
/* The size of `long long', as computed by sizeof. */
#define _EVENT_SIZEOF_LONG_LONG 8
/* The size of `short', as computed by sizeof. */
#define _EVENT_SIZEOF_SHORT 2
/* Define to 1 if you have the ANSI C header files. */
#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
/* Version number of package */
#define _EVENT_VERSION "1.4.2-rc"
/* Define to appropriate substitue if compiler doesnt have __func__ */
/* #undef _EVENT___func__ */
/* Define to empty if `const' does not conform to ANSI C. */
/* #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 */
#endif
/* Define to `int' if <sys/types.h> does not define. */
/* #undef _EVENT_pid_t */
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef _EVENT_size_t */
/* Define to unsigned int if you dont have it */
/* #undef _EVENT_socklen_t */
#endif

Просмотреть файл

@ -31,24 +31,64 @@
extern "C" { extern "C" {
#endif #endif
#include "opal_config.h"
#include "min_heap.h"
#include "evsignal.h"
struct eventop {
const char *name;
void *(*init)(struct event_base *);
int (*add)(void *, struct event *);
int (*del)(void *, struct event *);
int (*dispatch)(struct event_base *, void *, struct timeval *);
void (*dealloc)(struct event_base *, void *);
/* set if we need to reinitialize the event base */
int need_reinit;
};
struct event_base { struct event_base {
const struct opal_eventop *evsel; const struct eventop *evsel;
void *evbase; void *evbase;
int event_count; /* counts number of total events */ int event_count; /* counts number of total events */
int event_count_active; /* counts number of active events */ int event_count_active; /* counts number of active events */
int event_gotterm; /* Set to terminate loop */ int event_gotterm; /* Set to terminate loop */
int event_break; /* Set to terminate loop immediately */
/* active event management */ /* active event management */
struct opal_event_list **activequeues; struct event_list **activequeues;
int nactivequeues; int nactivequeues;
struct opal_event_list eventqueue; /* signal handling info */
struct evsignal_info sig;
struct event_list eventqueue;
struct timeval event_tv; struct timeval event_tv;
RB_HEAD(opal_event_tree, opal_event) timetree; struct min_heap timeheap;
}; };
/* Internal use only: Functions that might be missing from <sys/queue.h> */
#ifndef HAVE_TAILQFOREACH
#define TAILQ_FIRST(head) ((head)->tqh_first)
#define TAILQ_END(head) NULL
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
#define TAILQ_FOREACH(var, head, field) \
for((var) = TAILQ_FIRST(head); \
(var) != TAILQ_END(head); \
(var) = TAILQ_NEXT(var, field))
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
(elm)->field.tqe_next = (listelm); \
*(listelm)->field.tqe_prev = (elm); \
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
} while (0)
#endif /* TAILQ_FOREACH */
int _evsignal_set_handler(struct event_base *base, int evsignal,
void (*fn)(int));
int _evsignal_restore_handler(struct event_base *base, int evsignal);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -2,6 +2,7 @@
* *
* Copyright (c) 2004-2006 The Regents of the University of California. * Copyright (c) 2004-2006 The Regents of the University of California.
* All rights reserved. * All rights reserved.
* Copyright (c) 2008 Cisco Systems, Inc. All rights reserved.
* $COPYRIGHT$ * $COPYRIGHT$
* *
* Additional copyrights may follow * Additional copyrights may follow
@ -13,8 +14,8 @@
/* buffer.c */ /* buffer.c */
#define evbuffer_add opal_evbuffer_add #define evbuffer_add opal_evbuffer_add
#define evbuffer_add_buffer opal_evbuffer_add_buffer #define evbuffer_add_buffer opal_evbuffer_add_buffer
#define evbuffer_add_vprintf opal_evbuffer_add_vprintf
#define evbuffer_add_printf opal_evbuffer_add_printf #define evbuffer_add_printf opal_evbuffer_add_printf
#define evbuffer_add_vprintf opal_evbuffer_add_vprintf
#define evbuffer_drain opal_evbuffer_drain #define evbuffer_drain opal_evbuffer_drain
#define evbuffer_expand opal_evbuffer_expand #define evbuffer_expand opal_evbuffer_expand
#define evbuffer_find opal_evbuffer_find #define evbuffer_find opal_evbuffer_find
@ -32,17 +33,20 @@
/* epoll_sub.c */ /* epoll_sub.c */
/* these symbols should *NOT* be renamed */ /* these symbols should *NOT* be renamed */
/* evbuffer.c */
#define bufferevent_disable opal_bufferevent_disable /* event.h */
#define bufferevent_enable opal_bufferevent_enable #define OPAL_EV_TIMEOUT EV_TIMEOUT
#define bufferevent_free opal_bufferevent_free #define OPAL_EV_READ EV_READ
#define bufferevent_new opal_bufferevent_new #define OPAL_EV_WRITE EV_WRITE
#define bufferevent_priority_set opal_bufferevent_priority_set #define OPAL_EV_SIGNAL EV_SIGNAL
#define bufferevent_read opal_bufferevent_read #define OPAL_EV_PERSIST EV_PERSIST
#define bufferevent_settimeout opal_bufferevent_settimeout
#define bufferevent_setwatermark opal_bufferevent_setwatermark #define OPAL_EVENT_SIGNAL(ev) EVENT_SIGNAL(ev)
#define bufferevent_write opal_bufferevent_write
#define bufferevent_write_buffer opal_bufferevent_write_buffer #define OPAL_EVLOOP_ONCE EVLOOP_ONCE
#define OPAL_EVLOOP_NONBLOCK EVLOOP_NONBLOCK
#define OPAL_EVLOOP_ONELOOP EVLOOP_ONELOOP
/* event.c */ /* event.c */
#define current_base opal_current_base #define current_base opal_current_base
@ -51,6 +55,76 @@
#define event_get_version opal_event_get_version #define event_get_version opal_event_get_version
#define event_gotsig opal_event_gotsig #define event_gotsig opal_event_gotsig
#define event_sigcb opal_event_sigcb #define event_sigcb opal_event_sigcb
#define event_add opal_event_add_i
#define event_del opal_event_del_i
#define event_active opal_event_active_i
#define event_base opal_event_base
#define event opal_event
#define event_base_new opal_event_base_new
#define event_init opal_event_init
#define event_reinit opal_event_reinit
#define event_dispatch opal_event_dispatch
#define event_base_dispatch opal_event_base_dispatch
#define event_base_get_method opal_event_base_get_method
#define event_base_free opal_event_base_free
#define event_set_log_callback opal_event_set_log_callback
#define event_base_set opal_event_base_set
#define event_loop opal_event_loop
#define event_base_loop opal_event_base_loop
#define event_loopexit opal_event_loopexit
#define event_loopbreak opal_event_loopbreak
#define event_base_loopbreak opal_event_base_loopbreak
#define event_set opal_event_set
#define event_once opal_event_once
#define event_base_once opal_event_base_once
#define event_pending opal_event_pending
#define event_get_version opal_event_get_version
#define event_get_method opal_event_get_method
#define event_priority_init opal_event_priority_init
#define event_base_priority_init opal_event_base_priority_init
#define event_priority_set opal_event_priority_set
#define evbuffer opal_evbuffer
#define bufferevent opal_bufferevent
#define event_watermark opal_event_watermark
#define bufferevent_new opal_bufferevent_new
#define bufferevent_priority_set opal_bufferevent_priority_set
#define bufferevent_free opal_bufferevent_free
#define bufferevent_write opal_bufferevent_write
#define bufferevent_write_buffer opal_bufferevent_write_buffer
#define bufferevent_read opal_bufferevent_read
#define bufferevent_enable opal_bufferevent_enable
#define bufferevent_disable opal_bufferevent_disable
#define bufferevent_settimeout opal_bufferevent_settimeout
#define evbuffer_new opal_evbuffer_new
#define evbuffer_free opal_evbuffer_free
#define evbuffer_expand opal_evbuffer_expand
#define evbuffer_add opal_evbuffer_add
#define evbuffer_remove opal_evbuffer_remove
#define evbuffer_readline opal_evbuffer_readline
#define evbuffer_add_buffer opal_evbuffer_add_buffer
#define evbuffer_add_printf opal_evbuffer_add_printf
#define evbuffer_add_vprintf opal_evbuffer_add_vprintf
#define evbuffer_drain opal_evbuffer_drain
#define evbuffer_write opal_evbuffer_write
#define evbuffer_read opal_evbuffer_read
#define evbuffer_find opal_evbuffer_find
#define evbuffer_setcb opal_evbuffer_setcb
#define evtag_init opal_evtag_init
#define evtag_marshal opal_evtag_marshal
#define encode_int opal_encode_int
#define evtag_marshal_int opal_evtag_marshal_int
#define evtag_marshal_string opal_evtag_marshal_string
#define evtag_marshal_timeval opal_evtag_marshal_timeval
#define evtag_unmarshal opal_evtag_unmarshal
#define evtag_peek opal_evtag_peek
#define evtag_peek_length opal_evtag_peek_length
#define evtag_payload_length opal_evtag_payload_length
#define evtag_consume opal_evtag_consume
#define evtag_unmarshal_fixed opal_evtag_unmarshal_fixed
#define evtag_unmarshal_string opal_evtag_unmarshal_string
#define evtag_unmarshal_timeval opal_evtag_unmarshal_timeval
#define evtag_unmarshal_int opal_evtag_unmarshal_int
/* log.c */ /* log.c */
#define _event_debugx opal__event_debugx #define _event_debugx opal__event_debugx
@ -62,9 +136,47 @@
#define event_warnx opal_event_warnx #define event_warnx opal_event_warnx
/* poll.c */ /* poll.c */
#define poll_add opal_poll_add #define pollop opal_pollop
#define poll_del opal_poll_del
#define poll_dispatch opal_poll_dispatch /* event-internal.h */
#define poll_init opal_poll_init #define eventop opal_eventop
#define poll_recalc opal_poll_recalc #define event_base opal_event_base
#define _evsignal_set_handler _opal__evsignal_set_handler
#define _evsignal_restore_handler _opal__evsignal_restore_handler
/* evsignal.h */
#define evsignal_info opal_evsignal_info
#define evsignal_init opal_evsignal_init
#define evsignal_process opal_evsignal_process
#define evsignal_add opal_evsignal_add
#define evsignal_del opal_evsignal_del
#define evsignal_dealloc opal_evsignal_dealloc
/* evutil.c*/
#define evutil_socketpair opal_evutil_socketpair
#define evutil_make_socket_nonblocking opal_evutil_make_socket_nonblocking
/* kqueue.c */
#define kqop opal_kqop
/* min_heap.h */
#define min_heap_t opal_min_heap_t
#define min_heap_ctor opal_min_heap_ctor
#define min_heap_dtor opal_min_heap_dtor
#define min_heap_elem_init opal_min_heap_elem_init
#define min_heap_elem_greater opal_min_heap_elem_greater
#define min_heap_empty opal_min_heap_empty
#define min_heap_size opal_min_heap_size
#define min_heap_top opal_min_heap_top
#define min_heap_reserve opal_min_heap_reserve
#define min_heap_push opal_min_heap_push
#define min_heap_pop opal_min_heap_pop
#define min_heap_erase opal_min_heap_erase
#define min_heap_shift_up_ opal_min_heap_shift_up_
#define min_heap_shift_down_ opal_min_heap_shift_down_
/* select.c */
#define selectop opal_selectop

Просмотреть файл

@ -27,11 +27,26 @@
#ifndef _EVSIGNAL_H_ #ifndef _EVSIGNAL_H_
#define _EVSIGNAL_H_ #define _EVSIGNAL_H_
void opal_evsignal_init(sigset_t *); typedef void (*ev_sighandler_t)(int);
void opal_evsignal_process(void);
int opal_evsignal_recalc(sigset_t *); struct evsignal_info {
int opal_evsignal_deliver(sigset_t *); struct event_list signalqueue;
int opal_evsignal_add(sigset_t *, struct opal_event *); struct event ev_signal;
int opal_evsignal_del(sigset_t *, struct opal_event *); int ev_signal_pair[2];
int ev_signal_added;
volatile sig_atomic_t evsignal_caught;
sig_atomic_t evsigcaught[NSIG];
#ifdef HAVE_SIGACTION
struct sigaction **sh_old;
#else
ev_sighandler_t **sh_old;
#endif
int sh_old_max;
};
void evsignal_init(struct event_base *);
void evsignal_process(struct event_base *);
int evsignal_add(struct event *);
int evsignal_del(struct event *);
void evsignal_dealloc(struct event_base *);
#endif /* _EVSIGNAL_H_ */ #endif /* _EVSIGNAL_H_ */

199
opal/event/evutil.c Обычный файл
Просмотреть файл

@ -0,0 +1,199 @@
/*
* Copyright (c) 2007 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 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 "opal_config.h"
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include "misc.h"
#endif
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <errno.h>
#include "evutil.h"
#include "log.h"
int
evutil_socketpair(int family, int type, int protocol, int fd[2])
{
#ifndef WIN32
return socketpair(family, type, protocol, fd);
#else
/* This code is originally from Tor. Used with permission. */
/* This socketpair does not work when localhost is down. So
* it's really not the same thing at all. But it's close enough
* for now, and really, when localhost is down sometimes, we
* have other problems too.
*/
int listener = -1;
int connector = -1;
int acceptor = -1;
struct sockaddr_in listen_addr;
struct sockaddr_in connect_addr;
int size;
int saved_errno = -1;
if (protocol
#ifdef AF_UNIX
|| family != AF_UNIX
#endif
) {
EVUTIL_SET_SOCKET_ERROR(WSAEAFNOSUPPORT);
return -1;
}
if (!fd) {
EVUTIL_SET_SOCKET_ERROR(WSAEINVAL);
return -1;
}
listener = socket(AF_INET, type, 0);
if (listener < 0)
return -1;
memset(&listen_addr, 0, sizeof(listen_addr));
listen_addr.sin_family = AF_INET;
listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
listen_addr.sin_port = 0; /* kernel chooses port. */
if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
== -1)
goto tidy_up_and_fail;
if (listen(listener, 1) == -1)
goto tidy_up_and_fail;
connector = socket(AF_INET, type, 0);
if (connector < 0)
goto tidy_up_and_fail;
/* We want to find out the port number to connect to. */
size = sizeof(connect_addr);
if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
goto tidy_up_and_fail;
if (size != sizeof (connect_addr))
goto abort_tidy_up_and_fail;
if (connect(connector, (struct sockaddr *) &connect_addr,
sizeof(connect_addr)) == -1)
goto tidy_up_and_fail;
size = sizeof(listen_addr);
acceptor = accept(listener, (struct sockaddr *) &listen_addr, &size);
if (acceptor < 0)
goto tidy_up_and_fail;
if (size != sizeof(listen_addr))
goto abort_tidy_up_and_fail;
EVUTIL_CLOSESOCKET(listener);
/* Now check we are talking to ourself by matching port and host on the
two sockets. */
if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
goto tidy_up_and_fail;
if (size != sizeof (connect_addr)
|| listen_addr.sin_family != connect_addr.sin_family
|| listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr
|| listen_addr.sin_port != connect_addr.sin_port)
goto abort_tidy_up_and_fail;
fd[0] = connector;
fd[1] = acceptor;
return 0;
abort_tidy_up_and_fail:
saved_errno = WSAECONNABORTED;
tidy_up_and_fail:
if (saved_errno < 0)
saved_errno = WSAGetLastError();
if (listener != -1)
EVUTIL_CLOSESOCKET(listener);
if (connector != -1)
EVUTIL_CLOSESOCKET(connector);
if (acceptor != -1)
EVUTIL_CLOSESOCKET(acceptor);
EVUTIL_SET_SOCKET_ERROR(saved_errno);
return -1;
#endif
}
int
evutil_make_socket_nonblocking(int fd)
{
#ifdef WIN32
{
unsigned long nonblocking = 1;
ioctlsocket(fd, FIONBIO, (unsigned long*) &nonblocking);
}
#else
if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
event_warn("fcntl(O_NONBLOCK)");
return -1;
}
#endif
return 0;
}
#if 0
ev_int64_t
evutil_strtoll(const char *s, char **endptr, int base)
{
#ifdef HAVE_STRTOLL
return (ev_int64_t)strtoll(s, endptr, base);
#elif SIZEOF_LONG == 8
return (ev_int64_t)strtol(s, endptr, base);
#elif defined(WIN32) && defined(_MSC_VER) && _MSC_VER < 1300
/* XXXX on old versions of MS APIs, we only support base
* 10. */
ev_int64_t r;
if (base != 10)
return 0;
r = (ev_int64_t) _atoi64(s);
while (isspace(*s))
++s;
while (isdigit(*s))
++s;
if (endptr)
*endptr = (char*) s;
return r;
#elif defined(WIN32)
return (ev_int64_t) _strtoi64(s, endptr, base);
#else
#error "I don't know how to parse 64-bit integers."
#endif
}
#endif

176
opal/event/evutil.h Обычный файл
Просмотреть файл

@ -0,0 +1,176 @@
/*
* Copyright (c) 2007 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 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 _EVUTIL_H_
#define _EVUTIL_H_
/** @file evutil.h
Common convenience functions for cross-platform portability and
related socket manipulations.
*/
#include "opal_config.h"
#include "event_rename.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _EVENT_HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef _EVENT_HAVE_STDINT_H
#include <stdint.h>
#elif defined(_EVENT_HAVE_INTTYPES_H)
#include <inttypes.h>
#endif
#ifdef _EVENT_HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef _EVENT_HAVE_UINT64_T
#define ev_uint64_t uint64_t
#define ev_int64_t int64_t
#elif defined(WIN32)
#define ev_uint64_t __uint64_t
#define ev_int64_t __int64_t
#elif SIZEOF_LONG_LONG == 8
#define ev_uint64_t unsigned long long
#define ev_int64_t long long
#elif SIZEOF_LONG == 8
#define ev_uint64_t unsigned long
#define ev_int64_t long
#else
#error "No way to define ev_uint64_t"
#endif
#ifdef _EVENT_HAVE_UINT32_T
#define ev_uint32_t uint32_t
#elif defined(WIN32)
#define ev_uint32_t unsigned int
#elif SIZEOF_LONG == 4
#define ev_uint32_t unsigned long
#elif SIZEOF_INT == 4
#define ev_uint32_t unsigned int
#else
#error "No way to define ev_uint32_t"
#endif
#ifdef _EVENT_HAVE_UINT16_T
#define ev_uint16_t uint16_t
#elif defined(WIN32)
#define ev_uint16_t unsigned short
#elif SIZEOF_INT == 2
#define ev_uint16_t unsigned int
#elif SIZEOF_SHORT == 2
#define ev_uint16_t unsigned short
#else
#error "No way to define ev_uint16_t"
#endif
#ifdef _EVENT_HAVE_UINT8_T
#define ev_uint8_t uint8_t
#else
#define ev_uint8_t unsigned char
#endif
OPAL_DECLSPEC int evutil_socketpair(int d, int type, int protocol, int sv[2]);
OPAL_DECLSPEC int evutil_make_socket_nonblocking(int sock);
#ifdef WIN32
#define EVUTIL_CLOSESOCKET(s) closesocket(s)
#else
#define EVUTIL_CLOSESOCKET(s) close(s)
#endif
#ifdef WIN32
#define EVUTIL_SOCKET_ERROR() WSAGetLastError()
#define EVUTIL_SET_SOCKET_ERROR(errcode) \
do { WSASetLastError(errcode); } while (0)
#else
#define EVUTIL_SOCKET_ERROR() (errno)
#define EVUTIL_SET_SOCKET_ERROR(errcode) \
do { errno = (errcode); } while (0)
#endif
/*
* Manipulation functions for struct timeval
*/
#ifdef _EVENT_HAVE_TIMERADD
#define evutil_timeradd(tvp, uvp, vvp) timeradd((tvp), (uvp), (vvp))
#define evutil_timersub(tvp, uvp, vvp) timersub((tvp), (uvp), (vvp))
#else
#define evutil_timeradd(tvp, uvp, vvp) \
do { \
(vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \
(vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \
if ((vvp)->tv_usec >= 1000000) { \
(vvp)->tv_sec++; \
(vvp)->tv_usec -= 1000000; \
} \
} while (0)
#define evutil_timersub(tvp, uvp, vvp) \
do { \
(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
(vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
if ((vvp)->tv_usec < 0) { \
(vvp)->tv_sec--; \
(vvp)->tv_usec += 1000000; \
} \
} while (0)
#endif /* !_EVENT_HAVE_HAVE_TIMERADD */
#ifdef _EVENT_HAVE_TIMERCLEAR
#define evutil_timerclear(tvp) timerclear(tvp)
#else
#define evutil_timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0
#endif
#ifdef _EVENT_HAVE_TIMERCMP
#define evutil_timercmp(tvp, uvp, cmp) timercmp((tvp), (uvp), cmp)
#else
#define evutil_timercmp(tvp, uvp, cmp) \
(((tvp)->tv_sec == (uvp)->tv_sec) ? \
((tvp)->tv_usec cmp (uvp)->tv_usec) : \
((tvp)->tv_sec cmp (uvp)->tv_sec))
#endif
#ifdef _EVENT_HAVE_TIMERISSET
#define evutil_timerisset(tvp) timerisset(tvp)
#else
#define evutil_timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
#endif
/* big-int related functions */
ev_int64_t evutil_strtoll(const char *s, char **endptr, int base);
#ifdef __cplusplus
}
#endif
#endif /* _EVUTIL_H_ */

Просмотреть файл

@ -26,8 +26,8 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "opal_config.h"
#include "opal_config.h"
#ifdef HAVE_SYS_TYPES_H #ifdef HAVE_SYS_TYPES_H
#include <sys/types.h> #include <sys/types.h>
#endif #endif
@ -50,19 +50,24 @@
#include <inttypes.h> #include <inttypes.h>
#endif #endif
#if defined(HAVE_INTTYPES_H) && !defined(__OpenBSD__) && !defined(__FreeBSD__) /* Some platforms apparently define the udata field of struct kevent as
#define INTPTR(x) (intptr_t)x * intptr_t, whereas others define it as void*. There doesn't seem to be an
* easy way to tell them apart via autoconf, so we need to use OS macros. */
#if defined(HAVE_INTTYPES_H) && !defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__darwin__) && !defined(__APPLE__)
#define PTR_TO_UDATA(x) ((intptr_t)(x))
#else #else
#define INTPTR(x) x #define PTR_TO_UDATA(x) (x)
#endif #endif
#include "event.h" #include "event.h"
#include "event-internal.h"
#include "log.h" #include "log.h"
#include "opal/threads/mutex.h" #include "opal/threads/mutex.h"
extern opal_mutex_t opal_event_lock; extern opal_mutex_t opal_event_lock;
#define EVLIST_X_KQINKERNEL 0x1000 #define EVLIST_X_KQINKERNEL 0x1000
#define NEVENT 64 #define NEVENT 64
@ -75,87 +80,150 @@ struct kqop {
int kq; int kq;
}; };
static void *kq_init (void); static void *kq_init (struct event_base *);
static int kq_add (void *, struct opal_event *); static int kq_add (void *, struct event *);
static int kq_del (void *, struct opal_event *); static int kq_del (void *, struct event *);
static int kq_recalc (struct event_base *, void *, int);
static int kq_dispatch (struct event_base *, void *, struct timeval *); static int kq_dispatch (struct event_base *, void *, struct timeval *);
static int kq_insert (struct kqop *, struct kevent *); static int kq_insert (struct kqop *, struct kevent *);
static void kq_dealloc (struct event_base *, void *);
const struct opal_eventop opal_kqops = { const struct eventop kqops = {
"kqueue", "kqueue",
kq_init, kq_init,
kq_add, kq_add,
kq_del, kq_del,
kq_recalc, kq_dispatch,
kq_dispatch kq_dealloc,
1 /* need reinit */
}; };
static void * static void *
kq_init(void) kq_init(struct event_base *base)
{ {
int kq; int kq;
struct kqop *kqueueop; struct kqop *kqueueop;
/* Disable kqueue when this environment variable is set */ /* Disable kqueue when this environment variable is set */
if (getenv("EVENT_NOKQUEUE")) if (getenv("EVENT_NOKQUEUE"))
return (NULL); return (NULL);
if (!(kqueueop = calloc(1, sizeof(struct kqop)))) if (!(kqueueop = calloc(1, sizeof(struct kqop))))
return (NULL); return (NULL);
/* Initalize the kernel queue */ /* Initalize the kernel queue */
if ((kq = kqueue()) == -1) { if ((kq = kqueue()) == -1) {
event_warn("kqueue"); event_warn("kqueue");
free (kqueueop); free (kqueueop);
return (NULL); return (NULL);
} }
kqueueop->kq = kq; kqueueop->kq = kq;
/* Initalize fields */ /* Initalize fields */
kqueueop->changes = malloc(NEVENT * sizeof(struct kevent)); kqueueop->changes = malloc(NEVENT * sizeof(struct kevent));
if (kqueueop->changes == NULL) { if (kqueueop->changes == NULL) {
free (kqueueop); free (kqueueop);
return (NULL); return (NULL);
} }
kqueueop->events = malloc(NEVENT * sizeof(struct kevent)); kqueueop->events = malloc(NEVENT * sizeof(struct kevent));
if (kqueueop->events == NULL) { if (kqueueop->events == NULL) {
free (kqueueop->changes); free (kqueueop->changes);
free (kqueueop); free (kqueueop);
return (NULL); return (NULL);
} }
kqueueop->nevents = NEVENT; kqueueop->nevents = NEVENT;
/* Check for Mac OS X kqueue bug. */ /* Check for Mac OS X kqueue bug. */
kqueueop->changes[0].ident = -1; kqueueop->changes[0].ident = -1;
kqueueop->changes[0].filter = EVFILT_READ; kqueueop->changes[0].filter = EVFILT_READ;
kqueueop->changes[0].flags = EV_ADD; kqueueop->changes[0].flags = EV_ADD;
/* /*
* If kqueue works, then kevent will succeed, and it will * If kqueue works, then kevent will succeed, and it will
* stick an error in events[0]. If kqueue is broken, then * stick an error in events[0]. If kqueue is broken, then
* kevent will fail. * kevent will fail.
*/ */
if (kevent(kq,
kqueueop->changes, 1, kqueueop->events, NEVENT, NULL) != 1 ||
kqueueop->events[0].ident != -1 ||
kqueueop->events[0].flags != EV_ERROR) {
event_warn("%s: detected broken kqueue; not using.", __func__);
free(kqueueop->changes);
free(kqueueop->events);
free(kqueueop);
close(kq);
return (NULL);
}
/* Check if the kqueue can support pty */
{
int master, slave;
char name[1024];
if( 0 > openpty( &master, &slave, name, NULL, NULL ) ) {
event_warn("%s: unable to call openpty: error %d (%s)\n",
__func__, errno, strerror(errno) );
free(kqueueop->changes);
free(kqueueop->events);
free(kqueueop);
close(kq);
return NULL;
}
kqueueop->changes[0].ident = master;
kqueueop->changes[0].filter = EVFILT_READ;
kqueueop->changes[0].flags = EV_ADD;
if (kevent(kq, if (kevent(kq,
kqueueop->changes, 1, kqueueop->events, NEVENT, NULL) != 1 || kqueueop->changes, 1, kqueueop->events, NEVENT, NULL) != 1 ||
kqueueop->events[0].ident != (unsigned int) -1 || kqueueop->events[0].ident != master ||
kqueueop->events[0].flags != EV_ERROR) { kqueueop->events[0].flags != EV_ERROR) {
event_warn("%s: detected broken kqueue; not using.", __func__); event_warn("%s: detected broken kqueue (failed add); not using error %d (%s)\n",
free(kqueueop->changes); __func__, errno, strerror(errno));
free(kqueueop->events); free(kqueueop->changes);
free(kqueueop); free(kqueueop->events);
close(kq); free(kqueueop);
return (NULL); close(kq);
close(master);
close(slave);
return (NULL);
} }
kqueueop->changes[0].ident = master;
kqueueop->changes[0].filter = EVFILT_READ;
kqueueop->changes[0].flags = EV_DELETE;
if (kevent(kq,
kqueueop->changes, 1, kqueueop->events, NEVENT, NULL) != 1 ||
kqueueop->events[0].ident != master ||
kqueueop->events[0].flags != EV_ERROR) {
event_warn("%s: detected broken kqueue (failed delete); not using error %d (%s)",
__func__, errno, strerror(errno));
free(kqueueop->changes);
free(kqueueop->events);
free(kqueueop);
close(kq);
close(master);
close(slave);
return (NULL);
}
kqueueop->changes[0].ident = master;
kqueueop->changes[0].filter = EVFILT_READ;
kqueueop->changes[0].flags = EV_DELETE;
if (kevent(kq,
kqueueop->changes, 1, kqueueop->events, NEVENT, NULL) != 1 ||
kqueueop->events[0].ident != master ||
kqueueop->events[0].flags != EV_ERROR) {
event_warn("%s: detected broken kqueue (failed delete); not using error %d (%s)",
__func__, errno, strerror(errno));
free(kqueueop->changes);
free(kqueueop->events);
free(kqueueop);
close(kq);
close(master);
close(slave);
return (NULL);
}
close(master);
close(slave);
}
return (kqueueop); return (kqueueop);
}
static int
kq_recalc(struct event_base *base, void *arg, int max)
{
return (0);
} }
static int static int
@ -215,23 +283,26 @@ kq_dispatch(struct event_base *base, void *arg, struct timeval *tv)
struct kqop *kqop = arg; struct kqop *kqop = arg;
struct kevent *changes = kqop->changes; struct kevent *changes = kqop->changes;
struct kevent *events = kqop->events; struct kevent *events = kqop->events;
struct opal_event *ev; struct event *ev;
struct timespec ts; struct timespec ts, *ts_p = NULL;
int i, res; int i, res;
TIMEVAL_TO_TIMESPEC(tv, &ts); if (tv != NULL) {
TIMEVAL_TO_TIMESPEC(tv, &ts);
ts_p = &ts;
}
/* we should release the lock if we're going to enter the /* we should release the lock if we're going to enter the
kernel in a multi-threaded application. However, if we're kernel in a multi-threaded application. However, if we're
single threaded, there's really no advantage to releasing single threaded, there's really no advantage to releasing
the lock and it just takes up time we could spend doing the lock and it just takes up time we could spend doing
something else. */ something else. */
OPAL_THREAD_UNLOCK(&opal_event_lock); OPAL_THREAD_UNLOCK(&opal_event_lock);
res = kevent(kqop->kq, changes, kqop->nchanges,
events, kqop->nevents, &ts); res = kevent(kqop->kq, changes, kqop->nchanges,
events, kqop->nevents, ts_p);
OPAL_THREAD_LOCK(&opal_event_lock); OPAL_THREAD_LOCK(&opal_event_lock);
kqop->nchanges = 0; kqop->nchanges = 0;
if (res == -1) { if (res == -1) {
if (errno != EINTR) { if (errno != EINTR) {
event_warn("kevent"); event_warn("kevent");
@ -264,27 +335,29 @@ kq_dispatch(struct event_base *base, void *arg, struct timeval *tv)
events[i].data == ENOENT) events[i].data == ENOENT)
continue; continue;
errno = events[i].data; errno = events[i].data;
event_warn( "kevent failed with error code %d (%s)\n",
errno, strerror(errno) );
return (-1); return (-1);
} }
ev = (struct opal_event *)events[i].udata; ev = (struct event *)events[i].udata;
if (events[i].filter == EVFILT_READ) { if (events[i].filter == EVFILT_READ) {
which |= OPAL_EV_READ; which |= EV_READ;
} else if (events[i].filter == EVFILT_WRITE) { } else if (events[i].filter == EVFILT_WRITE) {
which |= OPAL_EV_WRITE; which |= EV_WRITE;
} else if (events[i].filter == EVFILT_SIGNAL) { } else if (events[i].filter == EVFILT_SIGNAL) {
which |= OPAL_EV_SIGNAL; which |= EV_SIGNAL;
} }
if (!which) if (!which)
continue; continue;
if (!(ev->ev_events & OPAL_EV_PERSIST)) if (!(ev->ev_events & EV_PERSIST))
opal_event_del_i(ev); ev->ev_flags &= ~EVLIST_X_KQINKERNEL;
opal_event_active_i(ev, which, event_active(ev, which,
ev->ev_events & OPAL_EV_SIGNAL ? events[i].data : 1); ev->ev_events & EV_SIGNAL ? events[i].data : 1);
} }
return (0); return (0);
@ -292,33 +365,37 @@ kq_dispatch(struct event_base *base, void *arg, struct timeval *tv)
static int static int
kq_add(void *arg, struct opal_event *ev) kq_add(void *arg, struct event *ev)
{ {
struct kqop *kqop = arg; struct kqop *kqop = arg;
struct kevent kev; struct kevent kev;
if (ev->ev_events & OPAL_EV_SIGNAL) { if (ev->ev_events & EV_SIGNAL) {
int nsignal = OPAL_EVENT_SIGNAL(ev); int nsignal = OPAL_EVENT_SIGNAL(ev);
struct timespec timeout = { 0, 0 };
memset(&kev, 0, sizeof(kev)); memset(&kev, 0, sizeof(kev));
kev.ident = nsignal; kev.ident = nsignal;
kev.filter = EVFILT_SIGNAL; kev.filter = EVFILT_SIGNAL;
kev.flags = EV_ADD; kev.flags = EV_ADD;
if (!(ev->ev_events & OPAL_EV_PERSIST)) if (!(ev->ev_events & EV_PERSIST))
kev.flags |= EV_ONESHOT; kev.flags |= EV_ONESHOT;
kev.udata = (void *) INTPTR(ev); kev.udata = PTR_TO_UDATA(ev);
if (kq_insert(kqop, &kev) == -1) /* Be ready for the signal if it is sent any time between
return (-1); * now and the next call to kq_dispatch. */
if (kevent(kqop->kq, &kev, 1, NULL, 0, &timeout) == -1)
return (-1);
if (signal(nsignal, kq_sighandler) == SIG_ERR) if (_evsignal_set_handler(ev->ev_base, nsignal,
kq_sighandler) == -1)
return (-1); return (-1);
ev->ev_flags |= EVLIST_X_KQINKERNEL; ev->ev_flags |= EVLIST_X_KQINKERNEL;
return (0); return (0);
} }
if (ev->ev_events & OPAL_EV_READ) { if (ev->ev_events & EV_READ) {
memset(&kev, 0, sizeof(kev)); memset(&kev, 0, sizeof(kev));
kev.ident = ev->ev_fd; kev.ident = ev->ev_fd;
kev.filter = EVFILT_READ; kev.filter = EVFILT_READ;
@ -327,9 +404,9 @@ kq_add(void *arg, struct opal_event *ev)
kev.fflags = NOTE_EOF; kev.fflags = NOTE_EOF;
#endif #endif
kev.flags = EV_ADD; kev.flags = EV_ADD;
if (!(ev->ev_events & OPAL_EV_PERSIST)) if (!(ev->ev_events & EV_PERSIST))
kev.flags |= EV_ONESHOT; kev.flags |= EV_ONESHOT;
kev.udata = (void *) INTPTR(ev); kev.udata = PTR_TO_UDATA(ev);
if (kq_insert(kqop, &kev) == -1) if (kq_insert(kqop, &kev) == -1)
return (-1); return (-1);
@ -337,14 +414,14 @@ kq_add(void *arg, struct opal_event *ev)
ev->ev_flags |= EVLIST_X_KQINKERNEL; ev->ev_flags |= EVLIST_X_KQINKERNEL;
} }
if (ev->ev_events & OPAL_EV_WRITE) { if (ev->ev_events & EV_WRITE) {
memset(&kev, 0, sizeof(kev)); memset(&kev, 0, sizeof(kev));
kev.ident = ev->ev_fd; kev.ident = ev->ev_fd;
kev.filter = EVFILT_WRITE; kev.filter = EVFILT_WRITE;
kev.flags = EV_ADD; kev.flags = EV_ADD;
if (!(ev->ev_events & OPAL_EV_PERSIST)) if (!(ev->ev_events & EV_PERSIST))
kev.flags |= EV_ONESHOT; kev.flags |= EV_ONESHOT;
kev.udata = (void *) INTPTR(ev); kev.udata = PTR_TO_UDATA(ev);
if (kq_insert(kqop, &kev) == -1) if (kq_insert(kqop, &kev) == -1)
return (-1); return (-1);
@ -356,7 +433,7 @@ kq_add(void *arg, struct opal_event *ev)
} }
static int static int
kq_del(void *arg, struct opal_event *ev) kq_del(void *arg, struct event *ev)
{ {
struct kqop *kqop = arg; struct kqop *kqop = arg;
struct kevent kev; struct kevent kev;
@ -364,25 +441,25 @@ kq_del(void *arg, struct opal_event *ev)
if (!(ev->ev_flags & EVLIST_X_KQINKERNEL)) if (!(ev->ev_flags & EVLIST_X_KQINKERNEL))
return (0); return (0);
if (ev->ev_events & OPAL_EV_SIGNAL) { if (ev->ev_events & EV_SIGNAL) {
int nsignal = OPAL_EVENT_SIGNAL(ev); int nsignal = OPAL_EVENT_SIGNAL(ev);
memset(&kev, 0, sizeof(kev)); memset(&kev, 0, sizeof(kev));
kev.ident = (int)signal; kev.ident = nsignal;
kev.filter = EVFILT_SIGNAL; kev.filter = EVFILT_SIGNAL;
kev.flags = EV_DELETE; kev.flags = EV_DELETE;
if (kq_insert(kqop, &kev) == -1) if (kq_insert(kqop, &kev) == -1)
return (-1); return (-1);
if (signal(nsignal, SIG_DFL) == SIG_ERR) if (_evsignal_restore_handler(ev->ev_base, nsignal) == -1)
return (-1); return (-1);
ev->ev_flags &= ~EVLIST_X_KQINKERNEL; ev->ev_flags &= ~EVLIST_X_KQINKERNEL;
return (0); return (0);
} }
if (ev->ev_events & OPAL_EV_READ) { if (ev->ev_events & EV_READ) {
memset(&kev, 0, sizeof(kev)); memset(&kev, 0, sizeof(kev));
kev.ident = ev->ev_fd; kev.ident = ev->ev_fd;
kev.filter = EVFILT_READ; kev.filter = EVFILT_READ;
@ -394,7 +471,7 @@ kq_del(void *arg, struct opal_event *ev)
ev->ev_flags &= ~EVLIST_X_KQINKERNEL; ev->ev_flags &= ~EVLIST_X_KQINKERNEL;
} }
if (ev->ev_events & OPAL_EV_WRITE) { if (ev->ev_events & EV_WRITE) {
memset(&kev, 0, sizeof(kev)); memset(&kev, 0, sizeof(kev));
kev.ident = ev->ev_fd; kev.ident = ev->ev_fd;
kev.filter = EVFILT_WRITE; kev.filter = EVFILT_WRITE;
@ -408,3 +485,18 @@ kq_del(void *arg, struct opal_event *ev)
return (0); return (0);
} }
static void
kq_dealloc(struct event_base *base, void *arg)
{
struct kqop *kqop = arg;
if (kqop->changes)
free(kqop->changes);
if (kqop->events)
free(kqop->events);
if (kqop->kq)
close(kqop->kq);
memset(kqop, 0, sizeof(struct kqop));
free(kqop);
}

Просмотреть файл

@ -46,7 +46,6 @@
#include "misc.h" #include "misc.h"
#endif #endif
#include <sys/types.h> #include <sys/types.h>
#include <sys/tree.h>
#ifdef HAVE_SYS_TIME_H #ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#else #else

Просмотреть файл

@ -27,17 +27,25 @@
#ifndef _LOG_H_ #ifndef _LOG_H_
#define _LOG_H_ #define _LOG_H_
void event_err(int eval, const char *fmt, ...); #ifdef __GNUC__
void event_warn(const char *fmt, ...); #define EV_CHECK_FMT(a,b) __attribute__((format(printf, a, b)))
void event_errx(int eval, const char *fmt, ...); #else
void event_warnx(const char *fmt, ...); #define EV_CHECK_FMT(a,b)
void event_msgx(const char *fmt, ...); #endif
void _event_debugx(const char *fmt, ...);
#undef USE_DEBUG void event_err(int eval, const char *fmt, ...) EV_CHECK_FMT(2,3);
void event_warn(const char *fmt, ...) EV_CHECK_FMT(1,2);
void event_errx(int eval, const char *fmt, ...) EV_CHECK_FMT(2,3);
void event_warnx(const char *fmt, ...) EV_CHECK_FMT(1,2);
void event_msgx(const char *fmt, ...) EV_CHECK_FMT(1,2);
void _event_debugx(const char *fmt, ...) EV_CHECK_FMT(1,2);
#ifdef USE_DEBUG #ifdef USE_DEBUG
#define event_debug(x) _event_debugx x #define event_debug(x) _event_debugx x
#else #else
#define event_debug(x) #define event_debug(x) do {;} while (0)
#endif #endif
#undef EV_CHECK_FMT
#endif #endif

138
opal/event/min_heap.h Обычный файл
Просмотреть файл

@ -0,0 +1,138 @@
/*
* Copyright (c) 2006 Maxim Yegorushkin <maxim.yegorushkin@gmail.com>
* 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 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 _MIN_HEAP_H_
#define _MIN_HEAP_H_
#include "event.h"
typedef struct min_heap
{
struct event** p;
unsigned n, a;
} min_heap_t;
static inline void min_heap_ctor(min_heap_t* s);
static inline void min_heap_dtor(min_heap_t* s);
static inline void min_heap_elem_init(struct event* e);
static inline int min_heap_elem_greater(struct event *a, struct event *b);
static inline int min_heap_empty(min_heap_t* s);
static inline unsigned min_heap_size(min_heap_t* s);
static inline struct event* min_heap_top(min_heap_t* s);
static inline int min_heap_reserve(min_heap_t* s, unsigned n);
static inline int min_heap_push(min_heap_t* s, struct event* e);
static inline struct event* min_heap_pop(min_heap_t* s);
static inline int min_heap_erase(min_heap_t* s, struct event* e);
static inline void min_heap_shift_up_(min_heap_t* s, unsigned hole_index, struct event* e);
static inline void min_heap_shift_down_(min_heap_t* s, unsigned hole_index, struct event* e);
int min_heap_elem_greater(struct event *a, struct event *b)
{
return timercmp(&a->ev_timeout, &b->ev_timeout, >);
}
void min_heap_ctor(min_heap_t* s) { s->p = 0; s->n = 0; s->a = 0; }
void min_heap_dtor(min_heap_t* s) { free(s->p); }
void min_heap_elem_init(struct event* e) { e->min_heap_idx = -1; }
int min_heap_empty(min_heap_t* s) { return 0u == s->n; }
unsigned min_heap_size(min_heap_t* s) { return s->n; }
struct event* min_heap_top(min_heap_t* s) { return s->n ? *s->p : 0; }
int min_heap_push(min_heap_t* s, struct event* e)
{
if(min_heap_reserve(s, s->n + 1))
return -1;
min_heap_shift_up_(s, s->n++, e);
return 0;
}
struct event* min_heap_pop(min_heap_t* s)
{
if(s->n)
{
struct event* e = *s->p;
e->min_heap_idx = -1;
min_heap_shift_down_(s, 0u, s->p[--s->n]);
return e;
}
return 0;
}
int min_heap_erase(min_heap_t* s, struct event* e)
{
if(((unsigned int)-1) != e->min_heap_idx)
{
min_heap_shift_down_(s, e->min_heap_idx, s->p[--s->n]);
e->min_heap_idx = -1;
return 0;
}
return -1;
}
int min_heap_reserve(min_heap_t* s, unsigned n)
{
if(s->a < n)
{
struct event** p;
unsigned a = s->a ? s->a * 2 : 8;
if(a < n)
a = n;
if(!(p = (struct event**)realloc(s->p, a * sizeof *p)))
return -1;
s->p = p;
s->a = a;
}
return 0;
}
void min_heap_shift_up_(min_heap_t* s, unsigned hole_index, struct event* e)
{
unsigned parent = (hole_index - 1) / 2;
while(hole_index && min_heap_elem_greater(s->p[parent], e))
{
(s->p[hole_index] = s->p[parent])->min_heap_idx = hole_index;
hole_index = parent;
parent = (hole_index - 1) / 2;
}
(s->p[hole_index] = e)->min_heap_idx = hole_index;
}
void min_heap_shift_down_(min_heap_t* s, unsigned hole_index, struct event* e)
{
unsigned min_child = 2 * (hole_index + 1);
while(min_child <= s->n)
{
min_child -= min_child == s->n || min_heap_elem_greater(s->p[min_child], s->p[min_child - 1]);
if(!(min_heap_elem_greater(e, s->p[min_child])))
break;
(s->p[hole_index] = s->p[min_child])->min_heap_idx = hole_index;
hole_index = min_child;
min_child = 2 * (hole_index + 1);
}
min_heap_shift_up_(s, hole_index, e);
}
#endif /* _MIN_HEAP_H_ */

Просмотреть файл

@ -37,7 +37,6 @@
#include <sys/_time.h> #include <sys/_time.h>
#endif #endif
#include <sys/queue.h> #include <sys/queue.h>
#include <sys/tree.h>
#ifdef HAVE_POLL_H #ifdef HAVE_POLL_H
#include <poll.h> #include <poll.h>
#endif #endif
@ -66,80 +65,58 @@
extern volatile sig_atomic_t opal_evsignal_caught; extern volatile sig_atomic_t opal_evsignal_caught;
extern opal_mutex_t opal_event_lock; extern opal_mutex_t opal_event_lock;
extern volatile sig_atomic_t evsignal_caught;
struct pollop { struct pollop {
int event_count; /* Highest number alloc */ int event_count; /* Highest number alloc */
int nfds; /* Size of event_* */ int nfds; /* Size of event_* */
int fd_count; /* Size of idxplus1_by_fd */ int fd_count; /* Size of idxplus1_by_fd */
struct pollfd *event_set; struct pollfd *event_set;
struct opal_event **event_r_back; struct event **event_r_back;
struct opal_event **event_w_back; struct event **event_w_back;
int *idxplus1_by_fd; /* Index into event_set by fd; we add 1 so int *idxplus1_by_fd; /* Index into event_set by fd; we add 1 so
* that 0 (which is easy to memset) can mean * that 0 (which is easy to memset) can mean
* "no entry." */ * "no entry." */
#if OPAL_EVENT_USE_SIGNALS
sigset_t evsigmask;
#endif
}; };
void *poll_init (void); static void *poll_init (struct event_base *);
int poll_add (void *, struct opal_event *); static int poll_add (void *, struct event *);
int poll_del (void *, struct opal_event *); static int poll_del (void *, struct event *);
int poll_recalc (struct event_base *, void *, int); static int poll_dispatch (struct event_base *, void *, struct timeval *);
int poll_dispatch (struct event_base *, void *, struct timeval *); static void poll_dealloc (struct event_base *, void *);
struct opal_eventop opal_pollops = { const struct eventop pollops = {
"poll", "poll",
poll_init, poll_init,
poll_add, poll_add,
poll_del, poll_del,
poll_recalc, poll_dispatch,
poll_dispatch poll_dealloc,
0
}; };
void * static void *
poll_init(void) poll_init(struct event_base *base)
{ {
struct pollop *pollop; struct pollop *pollop;
/* Disable kqueue when this environment variable is set */ /* Disable poll when this environment variable is set */
if (getenv("EVENT_NOPOLL")) if (getenv("EVENT_NOPOLL"))
return (NULL); return (NULL);
if (!(pollop = calloc(1, sizeof(struct pollop)))) if (!(pollop = calloc(1, sizeof(struct pollop))))
return (NULL); return (NULL);
#if OPAL_EVENT_USE_SIGNALS #if OPAL_EVENT_USE_SIGNALS
opal_evsignal_init(&pollop->evsigmask); evsignal_init(base);
#endif #endif
return (pollop); return (pollop);
} }
/*
* Called with the highest fd that we know about. If it is 0, completely
* recalculate everything.
*/
int
poll_recalc(struct event_base *base, void *arg, int max)
{
#if OPAL_EVENT_USE_SIGNALS
struct pollop *pop = arg;
return (opal_evsignal_recalc(&pop->evsigmask));
#else
return 0;
#endif
}
#ifdef CHECK_INVARIANTS #ifdef CHECK_INVARIANTS
static void static void
poll_check_ok(struct pollop *pop) poll_check_ok(struct pollop *pop)
{ {
int i, idx; int i, idx;
struct opal_event *ev; struct event *ev;
for (i = 0; i < pop->fd_count; ++i) { for (i = 0; i < pop->fd_count; ++i) {
idx = pop->idxplus1_by_fd[i]-1; idx = pop->idxplus1_by_fd[i]-1;
@ -168,49 +145,44 @@ poll_check_ok(struct pollop *pop)
#define poll_check_ok(pop) #define poll_check_ok(pop)
#endif #endif
int static int
poll_dispatch(struct event_base *base, void *arg, struct timeval *tv) poll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
{ {
int res, i, sec, nfds; int res, i, msec = -1, nfds;
struct pollop *pop = arg; struct pollop *pop = arg;
#if OPAL_EVENT_USE_SIGNALS
if (opal_evsignal_deliver(&pop->evsigmask) == -1)
return (-1);
#endif
poll_check_ok(pop); poll_check_ok(pop);
sec = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
if (tv != NULL)
msec = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
nfds = pop->nfds; nfds = pop->nfds;
/* we should release the lock if we're going to enter the /* we should release the lock if we're going to enter the
kernel in a multi-threaded application. However, if we're kernel in a multi-threaded application. However, if we're
single threaded, there's really no advantage to releasing single threaded, there's really no advantage to releasing
the lock and it just takes up time we could spend doing the lock and it just takes up time we could spend doing
something else. */ something else. */
OPAL_THREAD_UNLOCK(&opal_event_lock); OPAL_THREAD_UNLOCK(&opal_event_lock);
res = poll(pop->event_set, nfds, sec);
OPAL_THREAD_LOCK(&opal_event_lock);
#if OPAL_EVENT_USE_SIGNALS res = poll(pop->event_set, nfds, msec);
if (opal_evsignal_recalc(&pop->evsigmask) == -1)
return (-1); OPAL_THREAD_LOCK(&opal_event_lock);
#endif
if (res == -1) { if (res == -1) {
if (errno != EINTR) { if (errno != EINTR) {
event_warn("poll"); event_warn("poll");
return (-1); return (-1);
} }
#if OPAL_EVENT_USE_SIGNALS #if OPAL_EVENT_USE_SIGNALS
opal_evsignal_process(); evsignal_process(base);
#endif #endif
return (0); return (0);
} } else if (base->sig.evsignal_caught) {
#if OPAL_EVENT_USE_SIGNALS #if OPAL_EVENT_USE_SIGNALS
else if (opal_evsignal_caught) evsignal_process(base);
opal_evsignal_process();
#endif #endif
}
event_debug(("%s: poll reports %d", __func__, res)); event_debug(("%s: poll reports %d", __func__, res));
@ -218,8 +190,8 @@ poll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
return (0); return (0);
for (i = 0; i < nfds; i++) { for (i = 0; i < nfds; i++) {
int what = pop->event_set[i].revents; int what = pop->event_set[i].revents;
struct opal_event *r_ev = NULL, *w_ev = NULL; struct event *r_ev = NULL, *w_ev = NULL;
if (!what) if (!what)
continue; continue;
@ -240,22 +212,18 @@ poll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
continue; continue;
if (r_ev && (res & r_ev->ev_events)) { if (r_ev && (res & r_ev->ev_events)) {
if (!(r_ev->ev_events & OPAL_EV_PERSIST)) event_active(r_ev, res & r_ev->ev_events, 1);
opal_event_del_i(r_ev);
opal_event_active_i(r_ev, res & r_ev->ev_events, 1);
} }
if (w_ev && w_ev != r_ev && (res & w_ev->ev_events)) { if (w_ev && w_ev != r_ev && (res & w_ev->ev_events)) {
if (!(w_ev->ev_events & OPAL_EV_PERSIST)) event_active(w_ev, res & w_ev->ev_events, 1);
opal_event_del_i(w_ev);
opal_event_active_i(w_ev, res & w_ev->ev_events, 1);
} }
} }
return (0); return (0);
} }
int static int
poll_add(void *arg, struct opal_event *ev) poll_add(void *arg, struct event *ev)
{ {
struct pollop *pop = arg; struct pollop *pop = arg;
struct pollfd *pfd = NULL; struct pollfd *pfd = NULL;
@ -263,36 +231,55 @@ poll_add(void *arg, struct opal_event *ev)
#if OPAL_EVENT_USE_SIGNALS #if OPAL_EVENT_USE_SIGNALS
if (ev->ev_events & OPAL_EV_SIGNAL) if (ev->ev_events & OPAL_EV_SIGNAL)
return (opal_evsignal_add(&pop->evsigmask, ev)); return (evsignal_add(ev));
#endif #endif
if (!(ev->ev_events & (OPAL_EV_READ|OPAL_EV_WRITE))) if (!(ev->ev_events & (OPAL_EV_READ|OPAL_EV_WRITE)))
return (0); return (0);
poll_check_ok(pop); poll_check_ok(pop);
if (pop->nfds + 1 >= pop->event_count) { if (pop->nfds + 1 >= pop->event_count) {
struct pollfd *tmp_event_set;
struct event **tmp_event_r_back;
struct event **tmp_event_w_back;
int tmp_event_count;
if (pop->event_count < 32) if (pop->event_count < 32)
pop->event_count = 32; tmp_event_count = 32;
else else
pop->event_count *= 2; tmp_event_count = pop->event_count * 2;
/* We need more file descriptors */ /* We need more file descriptors */
pop->event_set = realloc(pop->event_set, tmp_event_set = realloc(pop->event_set,
pop->event_count * sizeof(struct pollfd)); tmp_event_count * sizeof(struct pollfd));
if (pop->event_set == NULL) { if (tmp_event_set == NULL) {
event_warn("realloc"); event_warn("realloc");
return (-1); return (-1);
} }
pop->event_r_back = realloc(pop->event_r_back, pop->event_set = tmp_event_set;
pop->event_count * sizeof(struct opal_event *));
pop->event_w_back = realloc(pop->event_w_back, tmp_event_r_back = realloc(pop->event_r_back,
pop->event_count * sizeof(struct opal_event *)); tmp_event_count * sizeof(struct event *));
if (pop->event_r_back == NULL || if (tmp_event_r_back == NULL) {
pop->event_w_back == NULL) { /* event_set overallocated; that's okay. */
event_warn("realloc"); event_warn("realloc");
return (-1); return (-1);
} }
pop->event_r_back = tmp_event_r_back;
tmp_event_w_back = realloc(pop->event_w_back,
tmp_event_count * sizeof(struct event *));
if (tmp_event_w_back == NULL) {
/* event_set and event_r_back overallocated; that's
* okay. */
event_warn("realloc");
return (-1);
}
pop->event_w_back = tmp_event_w_back;
pop->event_count = tmp_event_count;
} }
if (ev->ev_fd >= pop->fd_count) { if (ev->ev_fd >= pop->fd_count) {
int *tmp_idxplus1_by_fd;
int new_count; int new_count;
if (pop->fd_count < 32) if (pop->fd_count < 32)
new_count = 32; new_count = 32;
@ -300,12 +287,13 @@ poll_add(void *arg, struct opal_event *ev)
new_count = pop->fd_count * 2; new_count = pop->fd_count * 2;
while (new_count <= ev->ev_fd) while (new_count <= ev->ev_fd)
new_count *= 2; new_count *= 2;
pop->idxplus1_by_fd = tmp_idxplus1_by_fd =
realloc(pop->idxplus1_by_fd, new_count*sizeof(int)); realloc(pop->idxplus1_by_fd, new_count * sizeof(int));
if (pop->idxplus1_by_fd == NULL) { if (tmp_idxplus1_by_fd == NULL) {
event_warn("realloc"); event_warn("realloc");
return (-1); return (-1);
} }
pop->idxplus1_by_fd = tmp_idxplus1_by_fd;
memset(pop->idxplus1_by_fd + pop->fd_count, memset(pop->idxplus1_by_fd + pop->fd_count,
0, sizeof(int)*(new_count - pop->fd_count)); 0, sizeof(int)*(new_count - pop->fd_count));
pop->fd_count = new_count; pop->fd_count = new_count;
@ -341,18 +329,16 @@ poll_add(void *arg, struct opal_event *ev)
* Nothing to be done here. * Nothing to be done here.
*/ */
int static int
poll_del(void *arg, struct opal_event *ev) poll_del(void *arg, struct event *ev)
{ {
struct pollop *pop = arg; struct pollop *pop = arg;
struct pollfd *pfd = NULL; struct pollfd *pfd = NULL;
int i; int i;
#if OPAL_EVENT_USE_SIGNALS #if OPAL_EVENT_USE_SIGNALS
if (ev->ev_events & OPAL_EV_SIGNAL) if (ev->ev_events & OPAL_EV_SIGNAL)
return (opal_evsignal_del(&pop->evsigmask, ev)); return (evsignal_del(ev));
#endif #endif
if (!(ev->ev_events & (OPAL_EV_READ|OPAL_EV_WRITE))) if (!(ev->ev_events & (OPAL_EV_READ|OPAL_EV_WRITE)))
return (0); return (0);
@ -395,3 +381,22 @@ poll_del(void *arg, struct opal_event *ev)
poll_check_ok(pop); poll_check_ok(pop);
return (0); return (0);
} }
static void
poll_dealloc(struct event_base *base, void *arg)
{
struct pollop *pop = arg;
evsignal_dealloc(base);
if (pop->event_set)
free(pop->event_set);
if (pop->event_r_back)
free(pop->event_r_back);
if (pop->event_w_back)
free(pop->event_w_back);
if (pop->idxplus1_by_fd)
free(pop->idxplus1_by_fd);
memset(pop, 0, sizeof(struct pollop));
free(pop);
}

Просмотреть файл

@ -1,437 +0,0 @@
#include "opal_config.h"
/* Enable F_SETSIG and F_SETOWN */
#define _GNU_SOURCE
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#else
#include <sys/_time.h>
#endif
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/poll.h>
#include <sys/queue.h>
#ifndef HAVE_WORKING_RTSIG
#include <sys/stat.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#define EVLIST_X_NORT 0x1000 /* Skip RT signals (internal) */
#include "event.h"
#include "log.h"
extern struct event_list signalqueue;
struct rtsigop {
sigset_t sigs;
struct pollfd *poll;
struct event **toev;
int cur, max, total;
#ifndef HAVE_WORKING_RTSIG
int pollmode;
#endif
};
#define INIT_MAX 16
static int
poll_add(struct rtsigop *op, struct event *ev)
{
struct pollfd *pfd;
if (op->poll == NULL) return 0;
if (op->cur == op->max) {
void *p;
p = realloc(op->poll, sizeof(*op->poll) * (op->max << 1));
if (!p) {
errno = ENOMEM;
return -1;
}
op->poll = p;
p = realloc(op->toev, sizeof(*op->toev) * (op->max << 1));
if (!p) {
op->poll = realloc(op->poll, sizeof(*op->poll) * op->max);
errno = ENOMEM;
return -1;
}
op->toev = p;
op->max <<= 1;
}
pfd = &op->poll[op->cur];
pfd->fd = ev->ev_fd;
pfd->events = 0;
if (ev->ev_events & EV_READ) pfd->events |= POLLIN;
if (ev->ev_events & EV_WRITE) pfd->events |= POLLOUT;
pfd->revents = 0;
op->toev[op->cur] = ev;
op->cur++;
return 0;
}
static void
poll_free(struct rtsigop *op, int n)
{
if (op->poll == NULL) return;
op->cur--;
if (n < op->cur) {
memcpy(&op->poll[n], &op->poll[op->cur], sizeof(*op->poll));
op->toev[n] = op->toev[op->cur];
}
if (op->max > INIT_MAX && op->cur < op->max >> 1) {
op->max >>= 1;
op->poll = realloc(op->poll, sizeof(*op->poll) * op->max);
op->toev = realloc(op->toev, sizeof(*op->toev) * op->max);
}
}
static void
poll_remove(struct rtsigop *op, struct event *ev)
{
int i;
for (i = 0; i < op->cur; i++) {
if (op->toev[i] == ev) {
poll_free(op, i);
break;
}
}
}
static void
activate(struct event *ev, int flags)
{
if (!(ev->ev_events & EV_PERSIST)) event_del_i(ev);
event_active_i(ev, flags, 1);
}
static void *rtsig_init(void);
static int rtsig_add(void *, struct event *);
static int rtsig_del(void *, struct event *);
static int rtsig_recalc(struct event_base *, void *, int);
static int rtsig_dispatch(struct event_base *, void *, struct timeval *);
struct opal_eventop rtsigops = {
"rtsig",
rtsig_init,
rtsig_add,
rtsig_del,
rtsig_recalc,
rtsig_dispatch
};
static void *
rtsig_init(void)
{
struct rtsigop *op;
if (getenv("EVENT_NORTSIG"))
return (NULL);
op = malloc(sizeof(*op));
if (op == NULL) return (NULL);
memset(op, 0, sizeof(*op));
op->max = INIT_MAX;
op->poll = malloc(sizeof(*op->poll) * op->max);
if (op->poll == NULL) {
free(op);
return (NULL);
}
op->toev = malloc(sizeof(*op->toev) * op->max);
if (op->toev == NULL) {
free(op->poll);
free(op);
return (NULL);
}
sigemptyset(&op->sigs);
sigaddset(&op->sigs, SIGIO);
sigaddset(&op->sigs, SIGRTMIN);
sigprocmask(SIG_BLOCK, &op->sigs, NULL);
return (op);
}
static int
rtsig_add(void *arg, struct event *ev)
{
struct rtsigop *op = (struct rtsigop *) arg;
int flags, i;
#ifndef HAVE_WORKING_RTSIG
struct stat st;
#endif
if (ev->ev_events & EV_SIGNAL) {
sigaddset(&op->sigs, EVENT_SIGNAL(ev));
return sigprocmask(SIG_BLOCK, &op->sigs, NULL);
}
if (!(ev->ev_events & (EV_READ | EV_WRITE))) return 0;
#ifndef HAVE_WORKING_RTSIG
if (fstat(ev->ev_fd, &st) == -1) return -1;
if (S_ISFIFO(st.st_mode)) {
ev->ev_flags |= EVLIST_X_NORT;
op->pollmode++;
}
#endif
flags = fcntl(ev->ev_fd, F_GETFL);
if (flags == -1)
return (-1);
if (!(flags & O_ASYNC)) {
if (fcntl(ev->ev_fd, F_SETSIG, SIGRTMIN) == -1
|| fcntl(ev->ev_fd, F_SETOWN, (int) getpid()) == -1)
return (-1);
if (fcntl(ev->ev_fd, F_SETFL, flags | O_ASYNC))
return (-1);
}
#ifdef O_ONESIGFD
fcntl(ev->ev_fd, F_SETAUXFL, O_ONESIGFD);
#endif
op->total++;
if (poll_add(op, ev) == -1)
goto err;
return (0);
err:
i = errno;
fcntl(ev->ev_fd, F_SETFL, flags);
errno = i;
return (-1);
}
static int
rtsig_del(void *arg, struct event *ev)
{
struct rtsigop *op = (struct rtsigop *) arg;
if (ev->ev_events & EV_SIGNAL) {
sigset_t sigs;
sigdelset(&op->sigs, EVENT_SIGNAL(ev));
sigemptyset(&sigs);
sigaddset(&sigs, EVENT_SIGNAL(ev));
return (sigprocmask(SIG_UNBLOCK, &sigs, NULL));
}
if (!(ev->ev_events & (EV_READ | EV_WRITE)))
return (0);
#ifndef HAVE_WORKING_RTSIG
if (ev->ev_flags & EVLIST_X_NORT)
op->pollmode--;
#endif
poll_remove(op, ev);
op->total--;
return (0);
}
static int
rtsig_recalc(struct event_base *base, void *arg, int max)
{
return (0);
}
static int
rtsig_dispatch(struct event_base *base, void *arg, struct timeval *tv)
{
struct rtsigop *op = (struct rtsigop *) arg;
struct timespec ts;
int res, i;
if (op->poll == NULL)
goto retry_poll;
#ifndef HAVE_WORKING_RTSIG
if (op->pollmode)
goto poll_all;
#endif
if (op->cur) {
ts.tv_sec = ts.tv_nsec = 0;
} else {
ts.tv_sec = tv->tv_sec;
ts.tv_nsec = tv->tv_usec * 1000;
}
for (;;) {
siginfo_t info;
struct event *ev;
int signum;
signum = sigtimedwait(&op->sigs, &info, &ts);
if (signum == -1) {
if (errno == EAGAIN)
break;
return (errno == EINTR ? 0 : -1);
}
ts.tv_sec = ts.tv_nsec = 0;
if (signum == SIGIO) {
#ifndef HAVE_WORKING_RTSIG
poll_all:
#endif
free(op->poll);
free(op->toev);
retry_poll:
op->cur = 0;
op->max = op->total;
op->poll = malloc(sizeof(*op->poll) * op->total);
if (op->poll == NULL)
return (-1);
op->toev = malloc(sizeof(*op->toev) * op->total);
if (op->toev == NULL) {
free(op->poll);
op->poll = NULL;
return (-1);
}
TAILQ_FOREACH(ev, &base->eventqueue, ev_next)
if (!(ev->ev_flags & EVLIST_X_NORT))
poll_add(op, ev);
break;
}
if (signum == SIGRTMIN) {
int flags, i, sigok = 0;
if (info.si_band <= 0) { /* SI_SIGIO */
flags = EV_READ | EV_WRITE;
} else {
flags = 0;
if (info.si_band & POLLIN) flags |= EV_READ;
if (info.si_band & POLLOUT) flags |= EV_WRITE;
if (!flags) continue;
}
for (i = 0; flags && i < op->cur; i++) {
ev = op->toev[i];
if (ev->ev_fd == info.si_fd) {
flags &= ~ev->ev_events;
sigok = 1;
}
}
for (ev = TAILQ_FIRST(&base->eventqueue);
flags && ev != TAILQ_END(&base->eventqueue);
ev = TAILQ_NEXT(ev, ev_next)) {
if (ev->ev_fd == info.si_fd) {
if (flags & ev->ev_events) {
i = poll_add(op, ev);
if (i == -1) return -1;
flags &= ~ev->ev_events;
}
sigok = 1;
}
}
if (!sigok) {
flags = fcntl(info.si_fd, F_GETFL);
if (flags == -1) return -1;
fcntl(info.si_fd, F_SETFL, flags & ~O_ASYNC);
}
} else {
TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) {
if (EVENT_SIGNAL(ev) == signum)
activate(ev, EV_SIGNAL);
}
}
}
if (!op->cur)
return (0);
res = poll(op->poll, op->cur, tv->tv_sec * 1000 +
(tv->tv_usec + 999) / 1000);
if (res < 0)
return (-1);
i = 0;
#ifdef HAVE_WORKING_RTSIG
while (i < res) {
#else
while (i < op->cur) {
#endif
if (op->poll[i].revents) {
int flags = 0;
struct event *ev = op->toev[i];
if (op->poll[i].revents & POLLIN)
flags |= EV_READ;
if (op->poll[i].revents & POLLOUT)
flags |= EV_WRITE;
if (!(ev->ev_events & EV_PERSIST)) {
event_del_i(ev);
res--;
} else {
i++;
}
event_active_i(ev, flags, 1);
} else {
#ifndef HAVE_WORKING_RTSIG
if (op->toev[i]->ev_flags & EVLIST_X_NORT) {
i++;
res++;
continue;
}
#endif
for (;;) {
op->cur--;
if (i == op->cur)
break;
if (op->poll[op->cur].revents) {
memcpy(&op->poll[i], &op->poll[op->cur], sizeof(*op->poll));
op->toev[i] = op->toev[op->cur];
break;
}
}
}
}
#ifdef HAVE_WORKING_RTSIG
op->cur = res;
#endif
if (!op->cur) {
op->max = INIT_MAX;
free(op->poll);
free(op->toev);
/* We just freed it, we shouldn't have a problem getting it back. */
op->poll = malloc(sizeof(*op->poll) * op->max);
op->toev = malloc(sizeof(*op->toev) * op->max);
if (op->poll == NULL || op->toev == NULL)
event_err(1, "%s: malloc");
}
return (0);
}

Просмотреть файл

@ -1,8 +1,7 @@
AUTOMAKE_OPTIONS = foreign no-dependencies AUTOMAKE_OPTIONS = foreign no-dependencies
LDADD = ../libevent.la LDADD = ../libevent.la
CPPFPLAGS = -I.. AM_CFLAGS = -I$(top_srcdir) -I$(top_srcdir)/compat
CFLAGS = -I../compat
noinst_PROGRAMS = event-test time-test signal-test noinst_PROGRAMS = event-test time-test signal-test

Просмотреть файл

@ -1,8 +1,8 @@
# Makefile.in generated by automake 1.8.5 from Makefile.am. # Makefile.in generated by automake 1.10 from Makefile.am.
# @configure_input@ # @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004 Free Software Foundation, Inc. # 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation # This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved. # with or without modifications, as long as this notice is preserved.
@ -14,17 +14,11 @@
@SET_MAKE@ @SET_MAKE@
SOURCES = event-test.c signal-test.c time-test.c
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@ VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@ pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644 install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c
@ -36,6 +30,7 @@ POST_INSTALL = :
NORMAL_UNINSTALL = : NORMAL_UNINSTALL = :
PRE_UNINSTALL = : PRE_UNINSTALL = :
POST_UNINSTALL = : POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@ host_triplet = @host@
noinst_PROGRAMS = event-test$(EXEEXT) time-test$(EXEEXT) \ noinst_PROGRAMS = event-test$(EXEEXT) time-test$(EXEEXT) \
signal-test$(EXEEXT) signal-test$(EXEEXT)
@ -61,25 +56,24 @@ time_test_SOURCES = time-test.c
time_test_OBJECTS = time-test.$(OBJEXT) time_test_OBJECTS = time-test.$(OBJEXT)
time_test_LDADD = $(LDADD) time_test_LDADD = $(LDADD)
time_test_DEPENDENCIES = ../libevent.la time_test_DEPENDENCIES = ../libevent.la
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@
depcomp = depcomp =
am__depfiles_maybe = am__depfiles_maybe =
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \ LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CFLAGS) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC) CCLD = $(CC)
LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
SOURCES = event-test.c signal-test.c time-test.c SOURCES = event-test.c signal-test.c time-test.c
DIST_SOURCES = event-test.c signal-test.c time-test.c DIST_SOURCES = event-test.c signal-test.c time-test.c
ETAGS = etags ETAGS = etags
CTAGS = ctags CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@ ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@ AMTAR = @AMTAR@
AR = @AR@ AR = @AR@
AUTOCONF = @AUTOCONF@ AUTOCONF = @AUTOCONF@
@ -88,7 +82,7 @@ AUTOMAKE = @AUTOMAKE@
AWK = @AWK@ AWK = @AWK@
CC = @CC@ CC = @CC@
CCDEPMODE = @CCDEPMODE@ CCDEPMODE = @CCDEPMODE@
CFLAGS = -I../compat CFLAGS = @CFLAGS@
CPP = @CPP@ CPP = @CPP@
CPPFLAGS = @CPPFLAGS@ CPPFLAGS = @CPPFLAGS@
CXX = @CXX@ CXX = @CXX@
@ -106,6 +100,8 @@ EGREP = @EGREP@
EXEEXT = @EXEEXT@ EXEEXT = @EXEEXT@
F77 = @F77@ F77 = @F77@
FFLAGS = @FFLAGS@ FFLAGS = @FFLAGS@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
@ -117,10 +113,8 @@ LIBTOOL = @LIBTOOL@
LIBTOOL_DEPS = @LIBTOOL_DEPS@ LIBTOOL_DEPS = @LIBTOOL_DEPS@
LN_S = @LN_S@ LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@ LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
OBJEXT = @OBJEXT@ OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@ PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@ -130,54 +124,65 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@ PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@ RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@ SET_MAKE = @SET_MAKE@
SHELL = @SHELL@ SHELL = @SHELL@
STRIP = @STRIP@ STRIP = @STRIP@
VERSION = @VERSION@ VERSION = @VERSION@
ac_ct_AR = @ac_ct_AR@ abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@ ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@ ac_ct_CXX = @ac_ct_CXX@
ac_ct_F77 = @ac_ct_F77@ ac_ct_F77 = @ac_ct_F77@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@ am__include = @am__include@
am__leading_dot = @am__leading_dot@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@ am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@ bindir = @bindir@
build = @build@ build = @build@
build_alias = @build_alias@ build_alias = @build_alias@
build_cpu = @build_cpu@ build_cpu = @build_cpu@
build_os = @build_os@ build_os = @build_os@
build_vendor = @build_vendor@ build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@ datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@ exec_prefix = @exec_prefix@
host = @host@ host = @host@
host_alias = @host_alias@ host_alias = @host_alias@
host_cpu = @host_cpu@ host_cpu = @host_cpu@
host_os = @host_os@ host_os = @host_os@
host_vendor = @host_vendor@ host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@ includedir = @includedir@
infodir = @infodir@ infodir = @infodir@
install_sh = @install_sh@ install_sh = @install_sh@
libdir = @libdir@ libdir = @libdir@
libexecdir = @libexecdir@ libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@ localstatedir = @localstatedir@
mandir = @mandir@ mandir = @mandir@
mkdir_p = @mkdir_p@ mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@ prefix = @prefix@
program_transform_name = @program_transform_name@ program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@ sbindir = @sbindir@
sharedstatedir = @sharedstatedir@ sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@ sysconfdir = @sysconfdir@
target_alias = @target_alias@ target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = foreign no-dependencies AUTOMAKE_OPTIONS = foreign no-dependencies
LDADD = ../libevent.la LDADD = ../libevent.la
CPPFPLAGS = -I.. AM_CFLAGS = -I$(top_srcdir) -I$(top_srcdir)/compat
event_test_sources = event-test.c event_test_sources = event-test.c
time_test_sources = time-test.c time_test_sources = time-test.c
signal_test_sources = signal-test.c signal_test_sources = signal-test.c
@ -186,7 +191,7 @@ all: all-am
.SUFFIXES: .SUFFIXES:
.SUFFIXES: .c .lo .o .obj .SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \ @for dep in $?; do \
case '$(am__configure_deps)' in \ case '$(am__configure_deps)' in \
*$$dep*) \ *$$dep*) \
@ -211,9 +216,9 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
clean-noinstPROGRAMS: clean-noinstPROGRAMS:
@ -224,13 +229,13 @@ clean-noinstPROGRAMS:
done done
event-test$(EXEEXT): $(event_test_OBJECTS) $(event_test_DEPENDENCIES) event-test$(EXEEXT): $(event_test_OBJECTS) $(event_test_DEPENDENCIES)
@rm -f event-test$(EXEEXT) @rm -f event-test$(EXEEXT)
$(LINK) $(event_test_LDFLAGS) $(event_test_OBJECTS) $(event_test_LDADD) $(LIBS) $(LINK) $(event_test_OBJECTS) $(event_test_LDADD) $(LIBS)
signal-test$(EXEEXT): $(signal_test_OBJECTS) $(signal_test_DEPENDENCIES) signal-test$(EXEEXT): $(signal_test_OBJECTS) $(signal_test_DEPENDENCIES)
@rm -f signal-test$(EXEEXT) @rm -f signal-test$(EXEEXT)
$(LINK) $(signal_test_LDFLAGS) $(signal_test_OBJECTS) $(signal_test_LDADD) $(LIBS) $(LINK) $(signal_test_OBJECTS) $(signal_test_LDADD) $(LIBS)
time-test$(EXEEXT): $(time_test_OBJECTS) $(time_test_DEPENDENCIES) time-test$(EXEEXT): $(time_test_OBJECTS) $(time_test_DEPENDENCIES)
@rm -f time-test$(EXEEXT) @rm -f time-test$(EXEEXT)
$(LINK) $(time_test_LDFLAGS) $(time_test_OBJECTS) $(time_test_LDADD) $(LIBS) $(LINK) $(time_test_OBJECTS) $(time_test_LDADD) $(LIBS)
mostlyclean-compile: mostlyclean-compile:
-rm -f *.$(OBJEXT) -rm -f *.$(OBJEXT)
@ -253,10 +258,6 @@ mostlyclean-libtool:
clean-libtool: clean-libtool:
-rm -rf .libs _libs -rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \ unique=`for i in $$list; do \
@ -306,22 +307,21 @@ distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES) distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; for file in $$list; do \ list='$(DISTFILES)'; \
case $$file in \ dist_files=`for file in $$list; do echo $$file; done | \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ sed -e "s|^$$srcdirstrip/||;t" \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
esac; \ case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \ if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \ fi; \
@ -355,7 +355,7 @@ mostlyclean-generic:
clean-generic: clean-generic:
distclean-generic: distclean-generic:
-rm -f $(CONFIG_CLEAN_FILES) -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
maintainer-clean-generic: maintainer-clean-generic:
@ -369,7 +369,7 @@ clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
distclean: distclean-am distclean: distclean-am
-rm -f Makefile -rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \ distclean-am: clean-am distclean-compile distclean-generic \
distclean-libtool distclean-tags distclean-tags
dvi: dvi-am dvi: dvi-am
@ -383,12 +383,20 @@ info-am:
install-data-am: install-data-am:
install-dvi: install-dvi-am
install-exec-am: install-exec-am:
install-html: install-html-am
install-info: install-info-am install-info: install-info-am
install-man: install-man:
install-pdf: install-pdf-am
install-ps: install-ps-am
installcheck-am: installcheck-am:
maintainer-clean: maintainer-clean-am maintainer-clean: maintainer-clean-am
@ -408,19 +416,22 @@ ps: ps-am
ps-am: ps-am:
uninstall-am: uninstall-info-am uninstall-am:
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstPROGRAMS ctags distclean \ clean-libtool clean-noinstPROGRAMS ctags distclean \
distclean-compile distclean-generic distclean-libtool \ distclean-compile distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am html html-am info info-am \ distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-exec \ install install-am install-data install-data-am install-dvi \
install-exec-am install-info install-info-am install-man \ install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \ install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \ maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
pdf pdf-am ps ps-am tags uninstall uninstall-am \ pdf pdf-am ps ps-am tags uninstall uninstall-am
uninstall-info-am
verify: verify:

Просмотреть файл

@ -3,20 +3,16 @@
* cc -I/usr/local/include -o event-test event-test.c -L/usr/local/lib -levent * cc -I/usr/local/include -o event-test event-test.c -L/usr/local/lib -levent
*/ */
#ifdef HAVE_SYS_TYPES_H #ifdef HAVE_CONFIG_H
#include <sys/types.h> #include "config.h"
#endif #endif
#include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifndef WIN32 #ifndef WIN32
#ifdef HAVE_SYS_QUEUE_H
#include <sys/queue.h> #include <sys/queue.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif
#else #else
#include <windows.h> #include <windows.h>
#endif #endif
@ -28,18 +24,18 @@
#include <event.h> #include <event.h>
void static void
fifo_read(int fd, short event, void *arg) fifo_read(int fd, short event, void *arg)
{ {
char buf[255]; char buf[255];
int len; int len;
struct opal_event *ev = arg; struct event *ev = arg;
#ifdef WIN32 #ifdef WIN32
DWORD dwBytesRead; DWORD dwBytesRead;
#endif #endif
/* Reschedule this event */ /* Reschedule this event */
opal_event_add(ev, NULL); event_add(ev, NULL);
fprintf(stderr, "fifo_read called with fd: %d, event: %d, arg: %p\n", fprintf(stderr, "fifo_read called with fd: %d, event: %d, arg: %p\n",
fd, event, arg); fd, event, arg);
@ -49,7 +45,7 @@ fifo_read(int fd, short event, void *arg)
// Check for end of file. // Check for end of file.
if(len && dwBytesRead == 0) { if(len && dwBytesRead == 0) {
fprintf(stderr, "End Of File"); fprintf(stderr, "End Of File");
opal_event_del(ev); event_del(ev);
return; return;
} }
@ -73,7 +69,7 @@ fifo_read(int fd, short event, void *arg)
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
struct opal_event evfifo; struct event evfifo;
#ifdef WIN32 #ifdef WIN32
HANDLE socket; HANDLE socket;
// Open a file. // Open a file.
@ -90,7 +86,7 @@ main (int argc, char **argv)
#else #else
struct stat st; struct stat st;
char *fifo = "event.fifo"; const char *fifo = "event.fifo";
int socket; int socket;
if (lstat (fifo, &st) == 0) { if (lstat (fifo, &st) == 0) {
@ -122,19 +118,19 @@ main (int argc, char **argv)
fprintf(stderr, "Write data to %s\n", fifo); fprintf(stderr, "Write data to %s\n", fifo);
#endif #endif
/* Initalize the event library */ /* Initalize the event library */
opal_event_init(); event_init();
/* Initalize one event */ /* Initalize one event */
#ifdef WIN32 #ifdef WIN32
opal_event_set(&evfifo, (int)socket, OPAL_EV_READ, fifo_read, &evfifo); event_set(&evfifo, (int)socket, EV_READ, fifo_read, &evfifo);
#else #else
opal_event_set(&evfifo, socket, OPAL_EV_READ, fifo_read, &evfifo); event_set(&evfifo, socket, EV_READ, fifo_read, &evfifo);
#endif #endif
/* Add it to the active events, without a timeout */ /* Add it to the active events, without a timeout */
opal_event_add(&evfifo, NULL); event_add(&evfifo, NULL);
opal_event_dispatch(); event_dispatch();
#ifdef WIN32 #ifdef WIN32
CloseHandle(socket); CloseHandle(socket);
#endif #endif

Просмотреть файл

@ -3,21 +3,17 @@
* cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent * cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent
*/ */
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif #endif
#include <sys/stat.h> #include <sys/stat.h>
#ifndef WIN32 #ifndef WIN32
#ifdef HAVE_SYS_QUEUE_H
#include <sys/queue.h> #include <sys/queue.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif
#else #else
#include <windows.h> #include <windows.h>
#endif #endif
@ -32,15 +28,15 @@
int called = 0; int called = 0;
void static void
signal_cb(int fd, short event, void *arg) signal_cb(int fd, short event, void *arg)
{ {
struct opal_event *signal = arg; struct event *signal = arg;
printf("%s: got signal %d\n", __func__, OPAL_EVENT_SIGNAL(signal)); printf("%s: got signal %d\n", __func__, EVENT_SIGNAL(signal));
if (called >= 2) if (called >= 2)
opal_event_del(signal); event_del(signal);
called++; called++;
} }
@ -48,18 +44,18 @@ signal_cb(int fd, short event, void *arg)
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
struct opal_event signal_int; struct event signal_int;
/* Initalize the event library */ /* Initalize the event library */
opal_event_init(); event_init();
/* Initalize one event */ /* Initalize one event */
opal_event_set(&signal_int, SIGINT, OPAL_EV_SIGNAL|OPAL_EV_PERSIST, signal_cb, event_set(&signal_int, SIGINT, EV_SIGNAL|EV_PERSIST, signal_cb,
&signal_int); &signal_int);
opal_event_add(&signal_int, NULL); event_add(&signal_int, NULL);
opal_event_dispatch(); event_dispatch();
return (0); return (0);
} }

Просмотреть файл

@ -3,21 +3,18 @@
* cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent * cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent
*/ */
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif #endif
#include <sys/stat.h> #include <sys/stat.h>
#ifndef WIN32 #ifndef WIN32
#ifdef HAVE_SYS_QUEUE_H
#include <sys/queue.h> #include <sys/queue.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif
#else
#include <time.h> #include <time.h>
#endif
#ifdef HAVE_SYS_TIME_H #ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif #endif
@ -28,44 +25,45 @@
#include <errno.h> #include <errno.h>
#include <event.h> #include <event.h>
#include <evutil.h>
int lasttime; int lasttime;
void static void
timeout_cb(int fd, short event, void *arg) timeout_cb(int fd, short event, void *arg)
{ {
struct timeval tv; struct timeval tv;
struct opal_event *timeout = arg; struct event *timeout = arg;
int newtime = time(NULL); int newtime = time(NULL);
printf("%s: called at %d: %d\n", __func__, newtime, printf("%s: called at %d: %d\n", __func__, newtime,
newtime - lasttime); newtime - lasttime);
lasttime = newtime; lasttime = newtime;
timerclear(&tv); evutil_timerclear(&tv);
tv.tv_sec = 2; tv.tv_sec = 2;
opal_event_add(timeout, &tv); event_add(timeout, &tv);
} }
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
struct opal_event timeout; struct event timeout;
struct timeval tv; struct timeval tv;
/* Initalize the event library */ /* Initalize the event library */
opal_event_init(); event_init();
/* Initalize one event */ /* Initalize one event */
opal_evtimer_set(&timeout, timeout_cb, &timeout); evtimer_set(&timeout, timeout_cb, &timeout);
timerclear(&tv); evutil_timerclear(&tv);
tv.tv_sec = 2; tv.tv_sec = 2;
opal_event_add(&timeout, &tv); event_add(&timeout, &tv);
lasttime = time(NULL); lasttime = time(NULL);
opal_event_dispatch(); event_dispatch();
return (0); return (0);
} }

Просмотреть файл

@ -28,7 +28,6 @@
*/ */
#include "opal_config.h" #include "opal_config.h"
#include "opal/util/output.h" #include "opal/util/output.h"
#ifdef HAVE_SYS_TYPES_H #ifdef HAVE_SYS_TYPES_H
#include <sys/types.h> #include <sys/types.h>
#endif #endif
@ -41,10 +40,7 @@
#include <sys/select.h> #include <sys/select.h>
#endif #endif
#include <sys/queue.h> #include <sys/queue.h>
#include <sys/tree.h>
#ifndef __WINDOWS__
#include <signal.h> #include <signal.h>
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -58,15 +54,13 @@
#include "event.h" #include "event.h"
#include "event-internal.h" #include "event-internal.h"
#if OPAL_EVENT_USE_SIGNALS
#include "evsignal.h" #include "evsignal.h"
#endif
#include "log.h" #include "log.h"
#include "opal/threads/mutex.h" #include "opal/threads/mutex.h"
extern opal_mutex_t opal_event_lock; extern opal_mutex_t opal_event_lock;
#ifndef howmany #ifndef howmany
#define howmany(x, y) (((x)+((y)-1))/(y)) #define howmany(x, y) (((x)+((y)-1))/(y))
#endif #endif
@ -74,12 +68,13 @@ extern opal_mutex_t opal_event_lock;
#if OPAL_EVENT_USE_SIGNALS #if OPAL_EVENT_USE_SIGNALS
extern volatile sig_atomic_t opal_evsignal_caught; extern volatile sig_atomic_t opal_evsignal_caught;
#endif #endif
#ifdef __WINDOWS__ #ifdef __WINDOWS__
#define NFDBITS 32 #define NFDBITS 32
int fd_mask; int fd_mask;
#endif #endif
struct selectop { struct selectop {
int event_fds; /* Highest fd in fd set */ int event_fds; /* Highest fd in fd set */
int event_fdsz; int event_fdsz;
@ -87,51 +82,45 @@ struct selectop {
fd_set *event_writeset_in; fd_set *event_writeset_in;
fd_set *event_readset_out; fd_set *event_readset_out;
fd_set *event_writeset_out; fd_set *event_writeset_out;
struct opal_event **event_r_by_fd; struct event **event_r_by_fd;
struct opal_event **event_w_by_fd; struct event **event_w_by_fd;
#if OPAL_EVENT_USE_SIGNALS
sigset_t evsigmask;
#endif
}; };
static void *select_init (void); static void *select_init (struct event_base *);
static int select_add (void *, struct opal_event *); static int select_add (void *, struct event *);
static int select_del (void *, struct opal_event *); static int select_del (void *, struct event *);
static int select_recalc (struct event_base *, void *, int);
static int select_dispatch (struct event_base *, void *, struct timeval *); static int select_dispatch (struct event_base *, void *, struct timeval *);
static void select_dealloc (struct event_base *, void *);
const struct opal_eventop opal_selectops = { const struct eventop selectops = {
"select", "select",
select_init, select_init,
select_add, select_add,
select_del, select_del,
#ifdef WIN32 select_dispatch,
NULL, select_dealloc,
#else 0
select_recalc,
#endif
select_dispatch
}; };
static int select_resize(struct selectop *sop, int fdsz); static int select_resize(struct selectop *sop, int fdsz);
static void * static void *
select_init(void) select_init(struct event_base *base)
{ {
struct selectop *sop; struct selectop *sop;
/* Disable kqueue when this environment variable is set */ /* Disable select when this environment variable is set */
if (getenv("EVENT_NOSELECT")) if (getenv("EVENT_NOSELECT"))
return (NULL); return (NULL);
if (!(sop = calloc(1, sizeof(struct selectop)))) if (!(sop = calloc(1, sizeof(struct selectop))))
return (NULL); return (NULL);
select_resize(sop, howmany(32 + 1, NFDBITS)*sizeof(fd_mask)); select_resize(sop, howmany(32 + 1, NFDBITS)*sizeof(fd_mask));
#if OPAL_EVENT_USE_SIGNALS #if OPAL_EVENT_USE_SIGNALS
opal_evsignal_init(&sop->evsigmask); evsignal_init(base);
#endif #endif
return (sop); return (sop);
} }
@ -140,17 +129,17 @@ static void
check_selectop(struct selectop *sop) check_selectop(struct selectop *sop)
{ {
int i; int i;
for (i=0;i<=sop->event_fds;++i) { for (i = 0; i <= sop->event_fds; ++i) {
if (FD_ISSET(i, sop->event_readset_in)) { if (FD_ISSET(i, sop->event_readset_in)) {
assert(sop->event_r_by_fd[i]); assert(sop->event_r_by_fd[i]);
assert(sop->event_r_by_fd[i]->ev_events & EV_READ); assert(sop->event_r_by_fd[i]->ev_events & OPAL_EV_READ);
assert(sop->event_r_by_fd[i]->ev_fd == i); assert(sop->event_r_by_fd[i]->ev_fd == i);
} else { } else {
assert(! sop->event_r_by_fd[i]); assert(! sop->event_r_by_fd[i]);
} }
if (FD_ISSET(i, sop->event_writeset_in)) { if (FD_ISSET(i, sop->event_writeset_in)) {
assert(sop->event_w_by_fd[i]); assert(sop->event_w_by_fd[i]);
assert(sop->event_w_by_fd[i]->ev_events & EV_WRITE); assert(sop->event_w_by_fd[i]->ev_events & OPAL_EV_WRITE);
assert(sop->event_w_by_fd[i]->ev_fd == i); assert(sop->event_w_by_fd[i]->ev_fd == i);
} else { } else {
assert(! sop->event_w_by_fd[i]); assert(! sop->event_w_by_fd[i]);
@ -159,28 +148,9 @@ check_selectop(struct selectop *sop)
} }
#else #else
#define check_selectop(sop) #define check_selectop(sop) do { (void) sop; } while (0)
#endif #endif
/*
* Called with the highest fd that we know about. If it is 0, completely
* recalculate everything.
*/
static int
select_recalc(struct event_base *base, void *arg, int max)
{
struct selectop *sop = arg;
check_selectop(sop);
#if OPAL_EVENT_USE_SIGNALS
return (opal_evsignal_recalc(&sop->evsigmask));
#else
return (0);
#endif
}
static int static int
select_dispatch(struct event_base *base, void *arg, struct timeval *tv) select_dispatch(struct event_base *base, void *arg, struct timeval *tv)
{ {
@ -194,73 +164,40 @@ select_dispatch(struct event_base *base, void *arg, struct timeval *tv)
memcpy(sop->event_writeset_out, sop->event_writeset_in, memcpy(sop->event_writeset_out, sop->event_writeset_in,
sop->event_fdsz); sop->event_fdsz);
#if OPAL_EVENT_USE_SIGNALS
if (opal_evsignal_deliver(&sop->evsigmask) == -1)
return (-1);
#endif
/* we should release the lock if we're going to enter the /* we should release the lock if we're going to enter the
kernel in a multi-threaded application. However, if we're kernel in a multi-threaded application. However, if we're
single threaded, there's really no advantage to releasing single threaded, there's really no advantage to releasing
the lock and it just takes up time we could spend doing the lock and it just takes up time we could spend doing
something else. */ something else. */
OPAL_THREAD_UNLOCK(&opal_event_lock); OPAL_THREAD_UNLOCK(&opal_event_lock);
res = select(sop->event_fds + 1, sop->event_readset_out,
sop->event_writeset_out, NULL, tv); res = select(sop->event_fds + 1, sop->event_readset_out,
sop->event_writeset_out, NULL, tv);
OPAL_THREAD_LOCK(&opal_event_lock); OPAL_THREAD_LOCK(&opal_event_lock);
check_selectop(sop); check_selectop(sop);
#if OPAL_EVENT_USE_SIGNALS
if (opal_evsignal_recalc(&sop->evsigmask) == -1)
return (-1);
#endif
if (res == -1) { if (res == -1) {
#if 0
if (errno == EBADF) {
/* poll each of the file descriptors individually to determine
* which is bad
*/
for (ev = TAILQ_FIRST(&base->eventqueue); ev != NULL; ev = next) {
next = TAILQ_NEXT(ev, ev_next);
tv->tv_sec = 0;
tv->tv_usec = 0;
memset(sop->event_readset, 0, sop->event_fdsz);
memset(sop->event_writeset, 0, sop->event_fdsz);
if (ev->ev_events & OPAL_EV_WRITE)
FD_SET(ev->ev_fd, sop->event_writeset);
if (ev->ev_events & OPAL_EV_READ)
FD_SET(ev->ev_fd, sop->event_readset);
res = select(sop->event_fds + 1, sop->event_readset,
sop->event_writeset, NULL, tv);
if(res < 0) {
opal_output(0, "bad file descriptor: %d\n", ev->ev_fd);
opal_event_del_i(ev);
}
}
}
#endif
if (errno != EINTR) { if (errno != EINTR) {
opal_output(0, "select failed with errno=%d\n", errno); event_warn("select");
return (-1); return (-1);
} }
#if OPAL_EVENT_USE_SIGNALS #if OPAL_EVENT_USE_SIGNALS
opal_evsignal_process(); evsignal_process(base);
#endif #endif
return (0); return (0);
}
#if OPAL_EVENT_USE_SIGNALS #if OPAL_EVENT_USE_SIGNALS
else if (opal_evsignal_caught) } else if (base->sig.evsignal_caught) {
opal_evsignal_process(); evsignal_process(base);
#endif #endif
}
event_debug(("%s: select reports %d", __func__, res)); event_debug(("%s: select reports %d", __func__, res));
check_selectop(sop); check_selectop(sop);
for (i = 0; i <= sop->event_fds; ++i) { for (i = 0; i <= sop->event_fds; ++i) {
struct opal_event *r_ev = NULL, *w_ev = NULL; struct event *r_ev = NULL, *w_ev = NULL;
res = 0; res = 0;
if (FD_ISSET(i, sop->event_readset_out)) { if (FD_ISSET(i, sop->event_readset_out)) {
r_ev = sop->event_r_by_fd[i]; r_ev = sop->event_r_by_fd[i];
@ -271,14 +208,10 @@ select_dispatch(struct event_base *base, void *arg, struct timeval *tv)
res |= OPAL_EV_WRITE; res |= OPAL_EV_WRITE;
} }
if (r_ev && (res & r_ev->ev_events)) { if (r_ev && (res & r_ev->ev_events)) {
if (!(r_ev->ev_events & OPAL_EV_PERSIST)) event_active(r_ev, res & r_ev->ev_events, 1);
opal_event_del_i(r_ev);
opal_event_active_i(r_ev, res & r_ev->ev_events, 1);
} }
if (w_ev && w_ev != r_ev && (res & w_ev->ev_events)) { if (w_ev && w_ev != r_ev && (res & w_ev->ev_events)) {
if (!(w_ev->ev_events & OPAL_EV_PERSIST)) event_active(w_ev, res & w_ev->ev_events, 1);
opal_event_del_i(w_ev);
opal_event_active_i(w_ev, res & w_ev->ev_events, 1);
} }
} }
check_selectop(sop); check_selectop(sop);
@ -286,6 +219,7 @@ select_dispatch(struct event_base *base, void *arg, struct timeval *tv)
return (0); return (0);
} }
static int static int
select_resize(struct selectop *sop, int fdsz) select_resize(struct selectop *sop, int fdsz)
{ {
@ -295,8 +229,8 @@ select_resize(struct selectop *sop, int fdsz)
fd_set *writeset_in = NULL; fd_set *writeset_in = NULL;
fd_set *readset_out = NULL; fd_set *readset_out = NULL;
fd_set *writeset_out = NULL; fd_set *writeset_out = NULL;
struct opal_event **r_by_fd = NULL; struct event **r_by_fd = NULL;
struct opal_event **w_by_fd = NULL; struct event **w_by_fd = NULL;
n_events = (fdsz/sizeof(fd_mask)) * NFDBITS; n_events = (fdsz/sizeof(fd_mask)) * NFDBITS;
n_events_old = (sop->event_fdsz/sizeof(fd_mask)) * NFDBITS; n_events_old = (sop->event_fdsz/sizeof(fd_mask)) * NFDBITS;
@ -344,16 +278,15 @@ select_resize(struct selectop *sop, int fdsz)
return (-1); return (-1);
} }
static int static int
select_add(void *arg, struct opal_event *ev) select_add(void *arg, struct event *ev)
{ {
struct selectop *sop = arg; struct selectop *sop = arg;
#if OPAL_EVENT_USE_SIGNALS #if OPAL_EVENT_USE_SIGNALS
if (ev->ev_events & OPAL_EV_SIGNAL) if (ev->ev_events & OPAL_EV_SIGNAL)
return (opal_evsignal_add(&sop->evsigmask, ev)); return (evsignal_add(ev));
#endif #endif
check_selectop(sop); check_selectop(sop);
/* /*
* Keep track of the highest fd, so that we can calculate the size * Keep track of the highest fd, so that we can calculate the size
@ -362,7 +295,7 @@ select_add(void *arg, struct opal_event *ev)
if (sop->event_fds < ev->ev_fd) { if (sop->event_fds < ev->ev_fd) {
int fdsz = sop->event_fdsz; int fdsz = sop->event_fdsz;
if (fdsz < (int) sizeof(fd_mask)) if (fdsz < (int)sizeof(fd_mask))
fdsz = sizeof(fd_mask); fdsz = sizeof(fd_mask);
while (fdsz < while (fdsz <
@ -397,16 +330,15 @@ select_add(void *arg, struct opal_event *ev)
*/ */
static int static int
select_del(void *arg, struct opal_event *ev) select_del(void *arg, struct event *ev)
{ {
struct selectop *sop = arg; struct selectop *sop = arg;
check_selectop(sop); check_selectop(sop);
#if OPAL_EVENT_USE_SIGNALS #if OPAL_EVENT_USE_SIGNALS
if (ev->ev_events & OPAL_EV_SIGNAL) if (ev->ev_events & OPAL_EV_SIGNAL)
return (opal_evsignal_del(&sop->evsigmask, ev)); return (evsignal_del(ev));
#endif #endif
if (sop->event_fds < ev->ev_fd) { if (sop->event_fds < ev->ev_fd) {
check_selectop(sop); check_selectop(sop);
return (0); return (0);
@ -426,3 +358,25 @@ select_del(void *arg, struct opal_event *ev)
return (0); return (0);
} }
static void
select_dealloc(struct event_base *base, void *arg)
{
struct selectop *sop = arg;
evsignal_dealloc(base);
if (sop->event_readset_in)
free(sop->event_readset_in);
if (sop->event_writeset_in)
free(sop->event_writeset_in);
if (sop->event_readset_out)
free(sop->event_readset_out);
if (sop->event_writeset_out)
free(sop->event_writeset_out);
if (sop->event_r_by_fd)
free(sop->event_r_by_fd);
if (sop->event_w_by_fd)
free(sop->event_w_by_fd);
memset(sop, 0, sizeof(struct selectop));
free(sop);
}

Просмотреть файл

@ -28,17 +28,22 @@
*/ */
#include "opal_config.h" #include "opal_config.h"
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#undef WIN32_LEAN_AND_MEAN
#endif
#ifdef HAVE_SYS_TYPES_H #ifdef HAVE_SYS_TYPES_H
#include <sys/types.h> #include <sys/types.h>
#endif #endif
#ifdef HAVE_SYS_TIME_H #ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#else
#include <sys/_time.h>
#endif #endif
#include <sys/queue.h> #include <sys/queue.h>
#include <sys/tree.h> #ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> #include <sys/socket.h>
#endif
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -50,45 +55,33 @@
#ifdef HAVE_FCNTL_H #ifdef HAVE_FCNTL_H
#include <fcntl.h> #include <fcntl.h>
#endif #endif
#include <assert.h>
#include "event.h" #include "event.h"
#include "event-internal.h" #include "event-internal.h"
#include "evsignal.h" #include "evsignal.h"
#include "evutil.h"
#include "log.h" #include "log.h"
#include "opal/util/output.h" #include "opal/util/output.h"
struct event_base *evsignal_base = NULL;
extern struct opal_event_list opal_signalqueue; static void evsignal_handler(int sig);
#if defined(VXWORKS)
#define OPAL_NSIG (_NSIGS + 1)
#else
#define OPAL_NSIG NSIG
#endif
static sig_atomic_t opal_evsigcaught[OPAL_NSIG];
static int opal_needrecalc;
volatile sig_atomic_t opal_evsignal_caught = 0;
void opal_evsignal_handler(int sig);
static struct opal_event ev_signal;
static int ev_signal_pair[2];
static int ev_signal_added;
/* Callback for when the signal handler write a byte to our signaling socket */ /* Callback for when the signal handler write a byte to our signaling socket */
static void static void
evsignal_cb(int fd, short what, void *arg) evsignal_cb(int fd, short what, void *arg)
{ {
static char signals[100]; static char signals[100];
struct opal_event *ev = arg; #ifdef WIN32
SSIZE_T n;
#else
ssize_t n; ssize_t n;
#endif
n = read(fd, signals, sizeof(signals)); n = recv(fd, signals, sizeof(signals), 0);
if (n == -1) if (n == -1)
event_err(1, "%s: read", __func__); event_err(1, "%s: read", __func__);
opal_event_add_i(ev, NULL);
} }
#ifdef HAVE_SETFD #ifdef HAVE_SETFD
@ -101,184 +94,212 @@ evsignal_cb(int fd, short what, void *arg)
#endif #endif
void void
opal_evsignal_init(sigset_t *evsigmask) evsignal_init(struct event_base *base)
{ {
#ifndef WIN32
sigemptyset(evsigmask);
#endif
/* /*
* Our signal handler is going to write to one end of the socket * Our signal handler is going to write to one end of the socket
* pair to wake up our event loop. The event loop then scans for * pair to wake up our event loop. The event loop then scans for
* signals that got delivered. * signals that got delivered.
*/ */
#ifdef HAVE_SOCKETPAIR if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, base->sig.ev_signal_pair) == -1)
if (socketpair(AF_UNIX, SOCK_STREAM, 0, ev_signal_pair) == -1)
event_err(1, "%s: socketpair", __func__); event_err(1, "%s: socketpair", __func__);
#else
if (socketpair(AF_UNIX, SOCK_STREAM, 0, ev_signal_pair) == -1)
event_err(1, "%s: pipe", __func__);
#endif
FD_CLOSEONEXEC(ev_signal_pair[0]); FD_CLOSEONEXEC(base->sig.ev_signal_pair[0]);
FD_CLOSEONEXEC(ev_signal_pair[1]); FD_CLOSEONEXEC(base->sig.ev_signal_pair[1]);
base->sig.sh_old = NULL;
base->sig.sh_old_max = 0;
base->sig.evsignal_caught = 0;
memset(&base->sig.evsigcaught, 0, sizeof(sig_atomic_t)*NSIG);
fcntl(ev_signal_pair[0], F_SETFL, O_NONBLOCK); evutil_make_socket_nonblocking(base->sig.ev_signal_pair[0]);
opal_event_set(&ev_signal, ev_signal_pair[1], OPAL_EV_READ, event_set(&base->sig.ev_signal, base->sig.ev_signal_pair[1],
evsignal_cb, &ev_signal); OPAL_EV_READ | OPAL_EV_PERSIST, evsignal_cb, &base->sig.ev_signal);
ev_signal.ev_flags |= OPAL_EVLIST_INTERNAL; base->sig.ev_signal.ev_base = base;
base->sig.ev_signal.ev_flags |= EVLIST_INTERNAL;
} }
/* Helper: set the signal handler for evsignal to handler in base, so that
* we can restore the original handler when we clear the current one. */
int
_evsignal_set_handler(struct event_base *base,
int evsignal, void (*handler)(int))
{
#ifdef HAVE_SIGACTION
struct sigaction sa;
#else
ev_sighandler_t sh;
#endif
struct evsignal_info *sig = &base->sig;
void *p;
/*
* resize saved signal handler array up to the highest signal number.
* a dynamic array is used to keep footprint on the low side.
*/
if (evsignal >= sig->sh_old_max) {
event_debug(("%s: evsignal (%d) >= sh_old_max (%d), resizing",
__func__, evsignal, sig->sh_old_max));
sig->sh_old_max = evsignal + 1;
p = realloc(sig->sh_old, sig->sh_old_max * sizeof *sig->sh_old);
if (p == NULL) {
event_warn("realloc");
return (-1);
}
sig->sh_old = p;
}
/* allocate space for previous handler out of dynamic array */
sig->sh_old[evsignal] = malloc(sizeof *sig->sh_old[evsignal]);
if (sig->sh_old[evsignal] == NULL) {
event_warn("malloc");
return (-1);
}
/* save previous handler and setup new handler */
#ifdef HAVE_SIGACTION
memset(&sa, 0, sizeof(sa));
sa.sa_handler = handler;
sa.sa_flags |= SA_RESTART;
sigfillset(&sa.sa_mask);
if (sigaction(evsignal, &sa, sig->sh_old[evsignal]) == -1) {
event_warn("sigaction");
free(sig->sh_old[evsignal]);
return (-1);
}
#else
if ((sh = signal(evsignal, handler)) == SIG_ERR) {
event_warn("signal");
free(sig->sh_old[evsignal]);
return (-1);
}
*sig->sh_old[evsignal] = sh;
#endif
return (0);
}
int int
opal_evsignal_add(sigset_t *evsigmask, struct opal_event *ev) evsignal_add(struct event *ev)
{ {
int evsignal; int evsignal;
struct event_base *base = ev->ev_base;
struct evsignal_info *sig = &ev->ev_base->sig;
if (ev->ev_events & (OPAL_EV_READ|OPAL_EV_WRITE)) if (ev->ev_events & (OPAL_EV_READ|OPAL_EV_WRITE))
event_errx(1, "%s: OPAL_EV_SIGNAL incompatible use", __func__); event_errx(1, "%s: OPAL_EV_SIGNAL incompatible use", __func__);
evsignal = OPAL_EVENT_SIGNAL(ev); evsignal = OPAL_EVENT_SIGNAL(ev);
/* force a recalc of the events we are waiting for, otherwise event_debug(("%s: %p: changing signal handler", __func__, ev));
events aren't recalculated until the next time event_loop if (_evsignal_set_handler(base, evsignal, evsignal_handler) == -1)
is called. Since that might not be for some time, that return (-1);
gives a window where a signal handler *should* be installed
but actually is not. */
if (ev->ev_base->evsel->recalc && ev->ev_base->evsel->recalc(ev->ev_base, ev->ev_base->evbase, 0) == -1) {
opal_output(0, "opal_evsignal_add: opal_evsel->recalc() failed.");
return (-1);
}
#ifndef WIN32 /* catch signals if they happen quickly */
sigaddset(evsigmask, evsignal); evsignal_base = base;
#endif
if (!sig->ev_signal_added) {
sig->ev_signal_added = 1;
event_add(&sig->ev_signal, NULL);
}
return (0); return (0);
} }
int int
opal_evsignal_restart(void) _evsignal_restore_handler(struct event_base *base, int evsignal)
{ {
return (0); int ret = 0;
} struct evsignal_info *sig = &base->sig;
#ifdef HAVE_SIGACTION
struct sigaction *sh;
#else
ev_sighandler_t *sh;
#endif
/* /* restore previous handler */
* Nothing to be done here. sh = sig->sh_old[evsignal];
*/ sig->sh_old[evsignal] = NULL;
#ifdef HAVE_SIGACTION
if (sigaction(evsignal, sh, NULL) == -1) {
event_warn("sigaction");
ret = -1;
}
#else
if (signal(evsignal, *sh) == SIG_ERR) {
event_warn("signal");
ret = -1;
}
#endif
free(sh);
return ret;
}
int int
opal_evsignal_del(sigset_t *evsigmask, struct opal_event *ev) evsignal_del(struct event *ev)
{ {
#ifdef WIN32 event_debug(("%s: %p: restoring signal handler", __func__, ev));
return 0; return _evsignal_restore_handler(ev->ev_base, OPAL_EVENT_SIGNAL(ev));
#else
int evsignal, ret;
struct sigaction sa;
sigset_t set;
evsignal = OPAL_EVENT_SIGNAL(ev);
/* remove from the "in use" signal list */
sigdelset(evsigmask, evsignal);
opal_needrecalc = 1;
/* set back to default handler */
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_DFL;
ret = sigaction(evsignal, &sa, NULL);
/* unblock signal, in case we were blocking the "in use" signals
when this function was called */
sigemptyset(&set);
sigaddset(&set, evsignal);
sigprocmask(SIG_UNBLOCK, &set, NULL);
return ret;
#endif
} }
void static void
opal_evsignal_handler(int sig) evsignal_handler(int sig)
{ {
int save_errno = errno; int save_errno = errno;
opal_evsigcaught[sig]++; if(evsignal_base == NULL) {
opal_evsignal_caught = 1; event_warn(
"%s: received signal %d, but have no base configured",
__func__, sig);
return;
}
evsignal_base->sig.evsigcaught[sig]++;
evsignal_base->sig.evsignal_caught = 1;
#ifndef HAVE_SIGACTION
signal(sig, evsignal_handler);
#endif
/* Wake up our notification mechanism */ /* Wake up our notification mechanism */
write(ev_signal_pair[0], "a", 1); send(evsignal_base->sig.ev_signal_pair[0], "a", 1, 0);
errno = save_errno; errno = save_errno;
} }
int void
opal_evsignal_recalc(sigset_t *evsigmask) evsignal_process(struct event_base *base)
{ {
#ifdef WIN32 struct event *ev;
return 0; sig_atomic_t ncalls;
#else
struct sigaction sa;
struct opal_event *ev;
if (!ev_signal_added) { base->sig.evsignal_caught = 0;
ev_signal_added = 1; TAILQ_FOREACH(ev, &base->sig.signalqueue, ev_signal_next) {
opal_event_add_i(&ev_signal, NULL); ncalls = base->sig.evsigcaught[OPAL_EVENT_SIGNAL(ev)];
if (ncalls) {
if (!(ev->ev_events & OPAL_EV_PERSIST))
event_del(ev);
event_active(ev, OPAL_EV_SIGNAL, ncalls);
base->sig.evsigcaught[OPAL_EVENT_SIGNAL(ev)] = 0;
}
} }
if (TAILQ_FIRST(&opal_signalqueue) == NULL && !opal_needrecalc)
return (0);
opal_needrecalc = 0;
if (sigprocmask(SIG_BLOCK, evsigmask, NULL) == -1)
return (-1);
/* Reinstall our signal handler. */
memset(&sa, 0, sizeof(sa));
sa.sa_handler = opal_evsignal_handler;
sa.sa_mask = *evsigmask;
#if OMPI_HAVE_SA_RESTART
sa.sa_flags |= SA_RESTART;
#endif
TAILQ_FOREACH(ev, &opal_signalqueue, ev_signal_next) {
if (sigaction(OPAL_EVENT_SIGNAL(ev), &sa, NULL) == -1)
return (-1);
}
return (0);
#endif
}
int
opal_evsignal_deliver(sigset_t *evsigmask)
{
if (TAILQ_FIRST(&opal_signalqueue) == NULL)
return (0);
#ifdef WIN32
return 0;
#else
return (sigprocmask(SIG_UNBLOCK, evsigmask, NULL));
/* XXX - pending signals handled here */
#endif
} }
void void
opal_evsignal_process(void) evsignal_dealloc(struct event_base *base)
{ {
struct opal_event *ev; if(base->sig.ev_signal_added) {
sig_atomic_t ncalls; event_del(&base->sig.ev_signal);
base->sig.ev_signal_added = 0;
TAILQ_FOREACH(ev, &opal_signalqueue, ev_signal_next) {
ncalls = opal_evsigcaught[OPAL_EVENT_SIGNAL(ev)];
if (ncalls) {
if (!(ev->ev_events & OPAL_EV_PERSIST))
opal_event_del_i(ev);
opal_event_active_i(ev, OPAL_EV_SIGNAL, ncalls);
}
} }
assert(TAILQ_EMPTY(&base->sig.signalqueue));
memset(opal_evsigcaught, 0, sizeof(opal_evsigcaught)); EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[0]);
opal_evsignal_caught = 0; base->sig.ev_signal_pair[0] = -1;
EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[1]);
base->sig.ev_signal_pair[1] = -1;
base->sig.sh_old_max = 0;
/* per index frees are handled in evsignal_del() */
free(base->sig.sh_old);
} }

Просмотреть файл

@ -1,23 +1,35 @@
AUTOMAKE_OPTIONS = foreign no-dependencies AUTOMAKE_OPTIONS = foreign no-dependencies
LDADD = ../libevent.la CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/compat
CPPFPLAGS = -I..
CFLAGS = -I../compat @CFLAGS@ EXTRA_DIST = regress.rpc regress.gen.h regress.gen.c
noinst_PROGRAMS = test-init test-eof test-weof test-time regress bench noinst_PROGRAMS = test-init test-eof test-weof test-time regress bench
test_init_sources = test-init.c BUILT_SOURCES = regress.gen.c regress.gen.h
test_eof_sources = test-eof.c test_init_SOURCES = test-init.c
test_weof_sources = test-weof.c test_init_LDADD = ../libevent_core.la
test_time_sources = test-time.c test_eof_SOURCES = test-eof.c
regress_sources = regress.c test_eof_LDADD = ../libevent_core.la
bench_sources = bench.c test_weof_SOURCES = test-weof.c
test_weof_LDADD = ../libevent_core.la
test_time_SOURCES = test-time.c
test_time_LDADD = ../libevent_core.la
regress_SOURCES = regress.c regress.h regress_http.c regress_dns.c \
regress_rpc.c \
regress.gen.c regress.gen.h
regress_LDADD = ../libevent.la
bench_SOURCES = bench.c
bench_LDADD = ../libevent.la
regress.gen.c regress.gen.h: regress.rpc $(top_srcdir)/event_rpcgen.py
$(top_srcdir)/event_rpcgen.py $(srcdir)/regress.rpc || echo "No Python installed"
DISTCLEANFILES = *~ DISTCLEANFILES = *~
test: test-init test-eof test-weof test-time regress test: test-init test-eof test-weof test-time regress
verify: test verify: test
@./test.sh @$(srcdir)/test.sh
bench test-init test-eof test-weof test-time regress: ../libevent.la bench test-init test-eof test-weof test-time: ../libevent.la

Просмотреть файл

@ -1,8 +1,8 @@
# Makefile.in generated by automake 1.8.5 from Makefile.am. # Makefile.in generated by automake 1.10 from Makefile.am.
# @configure_input@ # @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004 Free Software Foundation, Inc. # 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation # This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved. # with or without modifications, as long as this notice is preserved.
@ -14,17 +14,11 @@
@SET_MAKE@ @SET_MAKE@
SOURCES = bench.c regress.c test-eof.c test-init.c test-time.c test-weof.c
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@ VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@ pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644 install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c
@ -36,6 +30,7 @@ POST_INSTALL = :
NORMAL_UNINSTALL = : NORMAL_UNINSTALL = :
PRE_UNINSTALL = : PRE_UNINSTALL = :
POST_UNINSTALL = : POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@ host_triplet = @host@
noinst_PROGRAMS = test-init$(EXEEXT) test-eof$(EXEEXT) \ noinst_PROGRAMS = test-init$(EXEEXT) test-eof$(EXEEXT) \
test-weof$(EXEEXT) test-time$(EXEEXT) regress$(EXEEXT) \ test-weof$(EXEEXT) test-time$(EXEEXT) regress$(EXEEXT) \
@ -50,51 +45,46 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES = CONFIG_CLEAN_FILES =
PROGRAMS = $(noinst_PROGRAMS) PROGRAMS = $(noinst_PROGRAMS)
bench_SOURCES = bench.c am_bench_OBJECTS = bench.$(OBJEXT)
bench_OBJECTS = bench.$(OBJEXT) bench_OBJECTS = $(am_bench_OBJECTS)
bench_LDADD = $(LDADD)
bench_DEPENDENCIES = ../libevent.la bench_DEPENDENCIES = ../libevent.la
regress_SOURCES = regress.c am_regress_OBJECTS = regress.$(OBJEXT) regress_http.$(OBJEXT) \
regress_OBJECTS = regress.$(OBJEXT) regress_dns.$(OBJEXT) regress_rpc.$(OBJEXT) \
regress_LDADD = $(LDADD) regress.gen.$(OBJEXT)
regress_OBJECTS = $(am_regress_OBJECTS)
regress_DEPENDENCIES = ../libevent.la regress_DEPENDENCIES = ../libevent.la
test_eof_SOURCES = test-eof.c am_test_eof_OBJECTS = test-eof.$(OBJEXT)
test_eof_OBJECTS = test-eof.$(OBJEXT) test_eof_OBJECTS = $(am_test_eof_OBJECTS)
test_eof_LDADD = $(LDADD) test_eof_DEPENDENCIES = ../libevent_core.la
test_eof_DEPENDENCIES = ../libevent.la am_test_init_OBJECTS = test-init.$(OBJEXT)
test_init_SOURCES = test-init.c test_init_OBJECTS = $(am_test_init_OBJECTS)
test_init_OBJECTS = test-init.$(OBJEXT) test_init_DEPENDENCIES = ../libevent_core.la
test_init_LDADD = $(LDADD) am_test_time_OBJECTS = test-time.$(OBJEXT)
test_init_DEPENDENCIES = ../libevent.la test_time_OBJECTS = $(am_test_time_OBJECTS)
test_time_SOURCES = test-time.c test_time_DEPENDENCIES = ../libevent_core.la
test_time_OBJECTS = test-time.$(OBJEXT) am_test_weof_OBJECTS = test-weof.$(OBJEXT)
test_time_LDADD = $(LDADD) test_weof_OBJECTS = $(am_test_weof_OBJECTS)
test_time_DEPENDENCIES = ../libevent.la test_weof_DEPENDENCIES = ../libevent_core.la
test_weof_SOURCES = test-weof.c DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@
test_weof_OBJECTS = test-weof.$(OBJEXT)
test_weof_LDADD = $(LDADD)
test_weof_DEPENDENCIES = ../libevent.la
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = depcomp =
am__depfiles_maybe = am__depfiles_maybe =
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \ LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CFLAGS) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC) CCLD = $(CC)
LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
SOURCES = bench.c regress.c test-eof.c test-init.c test-time.c \ $(LDFLAGS) -o $@
test-weof.c SOURCES = $(bench_SOURCES) $(regress_SOURCES) $(test_eof_SOURCES) \
DIST_SOURCES = bench.c regress.c test-eof.c test-init.c test-time.c \ $(test_init_SOURCES) $(test_time_SOURCES) $(test_weof_SOURCES)
test-weof.c DIST_SOURCES = $(bench_SOURCES) $(regress_SOURCES) $(test_eof_SOURCES) \
$(test_init_SOURCES) $(test_time_SOURCES) $(test_weof_SOURCES)
ETAGS = etags ETAGS = etags
CTAGS = ctags CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@ ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@ AMTAR = @AMTAR@
AR = @AR@ AR = @AR@
AUTOCONF = @AUTOCONF@ AUTOCONF = @AUTOCONF@
@ -103,9 +93,9 @@ AUTOMAKE = @AUTOMAKE@
AWK = @AWK@ AWK = @AWK@
CC = @CC@ CC = @CC@
CCDEPMODE = @CCDEPMODE@ CCDEPMODE = @CCDEPMODE@
CFLAGS = -I../compat @CFLAGS@ CFLAGS = @CFLAGS@
CPP = @CPP@ CPP = @CPP@
CPPFLAGS = @CPPFLAGS@ CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/compat
CXX = @CXX@ CXX = @CXX@
CXXCPP = @CXXCPP@ CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@ CXXDEPMODE = @CXXDEPMODE@
@ -121,6 +111,8 @@ EGREP = @EGREP@
EXEEXT = @EXEEXT@ EXEEXT = @EXEEXT@
F77 = @F77@ F77 = @F77@
FFLAGS = @FFLAGS@ FFLAGS = @FFLAGS@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
@ -132,10 +124,8 @@ LIBTOOL = @LIBTOOL@
LIBTOOL_DEPS = @LIBTOOL_DEPS@ LIBTOOL_DEPS = @LIBTOOL_DEPS@
LN_S = @LN_S@ LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@ LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
OBJEXT = @OBJEXT@ OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@ PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
@ -145,66 +135,87 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@ PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@ RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@ SET_MAKE = @SET_MAKE@
SHELL = @SHELL@ SHELL = @SHELL@
STRIP = @STRIP@ STRIP = @STRIP@
VERSION = @VERSION@ VERSION = @VERSION@
ac_ct_AR = @ac_ct_AR@ abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@ ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@ ac_ct_CXX = @ac_ct_CXX@
ac_ct_F77 = @ac_ct_F77@ ac_ct_F77 = @ac_ct_F77@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@ am__include = @am__include@
am__leading_dot = @am__leading_dot@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@ am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@ bindir = @bindir@
build = @build@ build = @build@
build_alias = @build_alias@ build_alias = @build_alias@
build_cpu = @build_cpu@ build_cpu = @build_cpu@
build_os = @build_os@ build_os = @build_os@
build_vendor = @build_vendor@ build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@ datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@ exec_prefix = @exec_prefix@
host = @host@ host = @host@
host_alias = @host_alias@ host_alias = @host_alias@
host_cpu = @host_cpu@ host_cpu = @host_cpu@
host_os = @host_os@ host_os = @host_os@
host_vendor = @host_vendor@ host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@ includedir = @includedir@
infodir = @infodir@ infodir = @infodir@
install_sh = @install_sh@ install_sh = @install_sh@
libdir = @libdir@ libdir = @libdir@
libexecdir = @libexecdir@ libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@ localstatedir = @localstatedir@
mandir = @mandir@ mandir = @mandir@
mkdir_p = @mkdir_p@ mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@ prefix = @prefix@
program_transform_name = @program_transform_name@ program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@ sbindir = @sbindir@
sharedstatedir = @sharedstatedir@ sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@ sysconfdir = @sysconfdir@
target_alias = @target_alias@ target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = foreign no-dependencies AUTOMAKE_OPTIONS = foreign no-dependencies
LDADD = ../libevent.la EXTRA_DIST = regress.rpc regress.gen.h regress.gen.c
CPPFPLAGS = -I.. BUILT_SOURCES = regress.gen.c regress.gen.h
test_init_sources = test-init.c test_init_SOURCES = test-init.c
test_eof_sources = test-eof.c test_init_LDADD = ../libevent_core.la
test_weof_sources = test-weof.c test_eof_SOURCES = test-eof.c
test_time_sources = test-time.c test_eof_LDADD = ../libevent_core.la
regress_sources = regress.c test_weof_SOURCES = test-weof.c
bench_sources = bench.c test_weof_LDADD = ../libevent_core.la
test_time_SOURCES = test-time.c
test_time_LDADD = ../libevent_core.la
regress_SOURCES = regress.c regress.h regress_http.c regress_dns.c \
regress_rpc.c \
regress.gen.c regress.gen.h
regress_LDADD = ../libevent.la
bench_SOURCES = bench.c
bench_LDADD = ../libevent.la
DISTCLEANFILES = *~ DISTCLEANFILES = *~
all: all-am all: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) all-am
.SUFFIXES: .SUFFIXES:
.SUFFIXES: .c .lo .o .obj .SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \ @for dep in $?; do \
case '$(am__configure_deps)' in \ case '$(am__configure_deps)' in \
*$$dep*) \ *$$dep*) \
@ -229,9 +240,9 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
clean-noinstPROGRAMS: clean-noinstPROGRAMS:
@ -242,22 +253,22 @@ clean-noinstPROGRAMS:
done done
bench$(EXEEXT): $(bench_OBJECTS) $(bench_DEPENDENCIES) bench$(EXEEXT): $(bench_OBJECTS) $(bench_DEPENDENCIES)
@rm -f bench$(EXEEXT) @rm -f bench$(EXEEXT)
$(LINK) $(bench_LDFLAGS) $(bench_OBJECTS) $(bench_LDADD) $(LIBS) $(LINK) $(bench_OBJECTS) $(bench_LDADD) $(LIBS)
regress$(EXEEXT): $(regress_OBJECTS) $(regress_DEPENDENCIES) regress$(EXEEXT): $(regress_OBJECTS) $(regress_DEPENDENCIES)
@rm -f regress$(EXEEXT) @rm -f regress$(EXEEXT)
$(LINK) $(regress_LDFLAGS) $(regress_OBJECTS) $(regress_LDADD) $(LIBS) $(LINK) $(regress_OBJECTS) $(regress_LDADD) $(LIBS)
test-eof$(EXEEXT): $(test_eof_OBJECTS) $(test_eof_DEPENDENCIES) test-eof$(EXEEXT): $(test_eof_OBJECTS) $(test_eof_DEPENDENCIES)
@rm -f test-eof$(EXEEXT) @rm -f test-eof$(EXEEXT)
$(LINK) $(test_eof_LDFLAGS) $(test_eof_OBJECTS) $(test_eof_LDADD) $(LIBS) $(LINK) $(test_eof_OBJECTS) $(test_eof_LDADD) $(LIBS)
test-init$(EXEEXT): $(test_init_OBJECTS) $(test_init_DEPENDENCIES) test-init$(EXEEXT): $(test_init_OBJECTS) $(test_init_DEPENDENCIES)
@rm -f test-init$(EXEEXT) @rm -f test-init$(EXEEXT)
$(LINK) $(test_init_LDFLAGS) $(test_init_OBJECTS) $(test_init_LDADD) $(LIBS) $(LINK) $(test_init_OBJECTS) $(test_init_LDADD) $(LIBS)
test-time$(EXEEXT): $(test_time_OBJECTS) $(test_time_DEPENDENCIES) test-time$(EXEEXT): $(test_time_OBJECTS) $(test_time_DEPENDENCIES)
@rm -f test-time$(EXEEXT) @rm -f test-time$(EXEEXT)
$(LINK) $(test_time_LDFLAGS) $(test_time_OBJECTS) $(test_time_LDADD) $(LIBS) $(LINK) $(test_time_OBJECTS) $(test_time_LDADD) $(LIBS)
test-weof$(EXEEXT): $(test_weof_OBJECTS) $(test_weof_DEPENDENCIES) test-weof$(EXEEXT): $(test_weof_OBJECTS) $(test_weof_DEPENDENCIES)
@rm -f test-weof$(EXEEXT) @rm -f test-weof$(EXEEXT)
$(LINK) $(test_weof_LDFLAGS) $(test_weof_OBJECTS) $(test_weof_LDADD) $(LIBS) $(LINK) $(test_weof_OBJECTS) $(test_weof_LDADD) $(LIBS)
mostlyclean-compile: mostlyclean-compile:
-rm -f *.$(OBJEXT) -rm -f *.$(OBJEXT)
@ -280,10 +291,6 @@ mostlyclean-libtool:
clean-libtool: clean-libtool:
-rm -rf .libs _libs -rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \ unique=`for i in $$list; do \
@ -333,22 +340,21 @@ distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES) distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; for file in $$list; do \ list='$(DISTFILES)'; \
case $$file in \ dist_files=`for file in $$list; do echo $$file; done | \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ sed -e "s|^$$srcdirstrip/||;t" \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
esac; \ case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \ if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \ fi; \
@ -360,10 +366,12 @@ distdir: $(DISTFILES)
fi; \ fi; \
done done
check-am: all-am check-am: all-am
check: check-am check: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) check-am
all-am: Makefile $(PROGRAMS) all-am: Makefile $(PROGRAMS)
installdirs: installdirs:
install: install-am install: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) install-am
install-exec: install-exec-am install-exec: install-exec-am
install-data: install-data-am install-data: install-data-am
uninstall: uninstall-am uninstall: uninstall-am
@ -382,12 +390,13 @@ mostlyclean-generic:
clean-generic: clean-generic:
distclean-generic: distclean-generic:
-rm -f $(CONFIG_CLEAN_FILES) -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
maintainer-clean-generic: maintainer-clean-generic:
@echo "This command is intended for maintainers to use" @echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild." @echo "it deletes files that may require special tools to rebuild."
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
clean: clean-am clean: clean-am
clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
@ -396,7 +405,7 @@ clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
distclean: distclean-am distclean: distclean-am
-rm -f Makefile -rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \ distclean-am: clean-am distclean-compile distclean-generic \
distclean-libtool distclean-tags distclean-tags
dvi: dvi-am dvi: dvi-am
@ -410,12 +419,20 @@ info-am:
install-data-am: install-data-am:
install-dvi: install-dvi-am
install-exec-am: install-exec-am:
install-html: install-html-am
install-info: install-info-am install-info: install-info-am
install-man: install-man:
install-pdf: install-pdf-am
install-ps: install-ps-am
installcheck-am: installcheck-am:
maintainer-clean: maintainer-clean-am maintainer-clean: maintainer-clean-am
@ -435,27 +452,33 @@ ps: ps-am
ps-am: ps-am:
uninstall-am: uninstall-info-am uninstall-am:
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstPROGRAMS ctags distclean \ clean-libtool clean-noinstPROGRAMS ctags distclean \
distclean-compile distclean-generic distclean-libtool \ distclean-compile distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am html html-am info info-am \ distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-exec \ install install-am install-data install-data-am install-dvi \
install-exec-am install-info install-info-am install-man \ install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \ install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \ maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
pdf pdf-am ps ps-am tags uninstall uninstall-am \ pdf pdf-am ps ps-am tags uninstall uninstall-am
uninstall-info-am
regress.gen.c regress.gen.h: regress.rpc $(top_srcdir)/event_rpcgen.py
$(top_srcdir)/event_rpcgen.py $(srcdir)/regress.rpc || echo "No Python installed"
test: test-init test-eof test-weof test-time regress test: test-init test-eof test-weof test-time regress
verify: test verify: test
@./test.sh @$(srcdir)/test.sh
bench test-init test-eof test-weof test-time regress: ../libevent.la bench test-init test-eof test-weof test-time: ../libevent.la
# Tell versions [3.59,3.63) of GNU make to not export all variables. # Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded. # Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT: .NOEXPORT:

Просмотреть файл

@ -16,13 +16,13 @@
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO OPAL_EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWLAM_EVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, OPAL_EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* *
* Mon 03/10/2003 - Modified by Davide Libenzi <davidel@xmailserver.org> * Mon 03/10/2003 - Modified by Davide Libenzi <davidel@xmailserver.org>
@ -37,40 +37,35 @@
#include "config.h" #include "config.h"
#endif #endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h> #include <sys/types.h>
#endif
#include <sys/stat.h> #include <sys/stat.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif #ifdef WIN32
#ifdef HAVE_SYS_SOCKET_H #include <windows.h>
#else
#include <sys/socket.h> #include <sys/socket.h>
#endif
#include <sys/signal.h> #include <sys/signal.h>
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h> #include <sys/resource.h>
#endif #endif
#include <fcntl.h> #include <fcntl.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif
#include <errno.h> #include <errno.h>
#include <event.h> #include <event.h>
#include <evutil.h>
static int count, writes, fired; static int count, writes, fired;
static int *pipes; static int *pipes;
static int num_pipes, num_active, num_writes; static int num_pipes, num_active, num_writes;
static struct opal_event *events; static struct event *events;
void static void
read_cb(int fd, short which, void *arg) read_cb(int fd, short which, void *arg)
{ {
int idx = (int) arg, widx = idx + 1; int idx = (int) arg, widx = idx + 1;
@ -86,19 +81,19 @@ read_cb(int fd, short which, void *arg)
} }
} }
struct timeval * static struct timeval *
run_once(void) run_once(void)
{ {
int *cp, i, space; int *cp, i, space;
static struct timeval ts, te; static struct timeval ts, te;
for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) { for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
opal_event_del(&events[i]); event_del(&events[i]);
opal_event_set(&events[i], cp[0], OPAL_EV_READ | OPAL_EV_PERSIST, read_cb, (void *) i); event_set(&events[i], cp[0], EV_READ | EV_PERSIST, read_cb, (void *) i);
opal_event_add(&events[i], NULL); event_add(&events[i], NULL);
} }
opal_event_loop(OPAL_EVLOOP_ONCE | OPAL_EVLOOP_NONBLOCK); event_loop(EVLOOP_ONCE | EVLOOP_NONBLOCK);
fired = 0; fired = 0;
space = num_pipes / num_active; space = num_pipes / num_active;
@ -111,7 +106,7 @@ run_once(void)
{ int xcount = 0; { int xcount = 0;
gettimeofday(&ts, NULL); gettimeofday(&ts, NULL);
do { do {
opal_event_loop(OPAL_EVLOOP_ONCE | OPAL_EVLOOP_NONBLOCK); event_loop(EVLOOP_ONCE | EVLOOP_NONBLOCK);
xcount++; xcount++;
} while (count != fired); } while (count != fired);
gettimeofday(&te, NULL); gettimeofday(&te, NULL);
@ -119,7 +114,7 @@ run_once(void)
if (xcount != count) fprintf(stderr, "Xcount: %d, Rcount: %d\n", xcount, count); if (xcount != count) fprintf(stderr, "Xcount: %d, Rcount: %d\n", xcount, count);
} }
timersub(&te, &ts, &te); evutil_timersub(&te, &ts, &te);
return (&te); return (&te);
} }
@ -127,11 +122,12 @@ run_once(void)
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
#ifndef WIN32
struct rlimit rl; struct rlimit rl;
#endif
int i, c; int i, c;
struct timeval *tv; struct timeval *tv;
int *cp; int *cp;
extern char *optarg;
num_pipes = 100; num_pipes = 100;
num_active = 1; num_active = 1;
@ -153,26 +149,28 @@ main (int argc, char **argv)
} }
} }
#ifndef WIN32
rl.rlim_cur = rl.rlim_max = num_pipes * 2 + 50; rl.rlim_cur = rl.rlim_max = num_pipes * 2 + 50;
if (setrlimit(RLIMIT_NOFILE, &rl) == -1) { if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {
perror("setrlimit"); perror("setrlimit");
exit(1); exit(1);
} }
#endif
events = calloc(num_pipes, sizeof(struct opal_event)); events = calloc(num_pipes, sizeof(struct event));
pipes = calloc(num_pipes * 2, sizeof(int)); pipes = calloc(num_pipes * 2, sizeof(int));
if (events == NULL || pipes == NULL) { if (events == NULL || pipes == NULL) {
perror("malloc"); perror("malloc");
exit(1); exit(1);
} }
opal_event_init(); event_init();
for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) { for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
#ifdef USE_PIPES #ifdef USE_PIPES
if (pipe(cp) == -1) { if (pipe(cp) == -1) {
#else #else
if (socketpair(AF_UNIX, SOCK_STREAM, 0, cp) == -1) { if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, cp) == -1) {
#endif #endif
perror("pipe"); perror("pipe");
exit(1); exit(1);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -2,14 +2,17 @@
* Compile with: * Compile with:
* cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent * cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_SYS_TYPES_H
#ifdef WIN32
#include <winsock2.h>
#endif
#include <sys/types.h> #include <sys/types.h>
#endif
#include <sys/stat.h> #include <sys/stat.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif
#ifdef HAVE_SYS_SOCKET_H #ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> #include <sys/socket.h>
#endif #endif
@ -17,17 +20,16 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif
#include <errno.h> #include <errno.h>
#include <event.h> #include <event.h>
#include <evutil.h>
int test_okay = 1; int test_okay = 1;
int called = 0; int called = 0;
void static void
read_cb(int fd, short event, void *arg) read_cb(int fd, short event, void *arg)
{ {
char buf[256]; char buf[256];
@ -40,21 +42,25 @@ read_cb(int fd, short event, void *arg)
if (len) { if (len) {
if (!called) if (!called)
opal_event_add(arg, NULL); event_add(arg, NULL);
} else if (called == 1) } else if (called == 1)
test_okay = 0; test_okay = 0;
called++; called++;
} }
#ifndef SHUT_WR
#define SHUT_WR 1
#endif
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
struct opal_event ev; struct event ev;
char *test = "test string"; const char *test = "test string";
int pair[2]; int pair[2];
if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
return (1); return (1);
@ -62,14 +68,14 @@ main (int argc, char **argv)
shutdown(pair[0], SHUT_WR); shutdown(pair[0], SHUT_WR);
/* Initalize the event library */ /* Initalize the event library */
opal_event_init(); event_init();
/* Initalize one event */ /* Initalize one event */
opal_event_set(&ev, pair[1], OPAL_EV_READ, read_cb, &ev); event_set(&ev, pair[1], EV_READ, read_cb, &ev);
opal_event_add(&ev, NULL); event_add(&ev, NULL);
opal_event_dispatch(); event_dispatch();
return (test_okay); return (test_okay);
} }

Просмотреть файл

@ -2,14 +2,14 @@
* Compile with: * Compile with:
* cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent * cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h> #include <sys/types.h>
#endif
#include <sys/stat.h> #include <sys/stat.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif
#ifdef HAVE_SYS_SOCKET_H #ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> #include <sys/socket.h>
#endif #endif
@ -17,9 +17,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif
#include <errno.h> #include <errno.h>
#include <event.h> #include <event.h>
@ -28,7 +26,7 @@ int
main(int argc, char **argv) main(int argc, char **argv)
{ {
/* Initalize the event library */ /* Initalize the event library */
opal_event_init(); event_init();
return (0); return (0);
} }

Просмотреть файл

@ -2,21 +2,19 @@
* Compile with: * Compile with:
* cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent * cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h> #include <sys/types.h>
#endif
#include <sys/stat.h> #include <sys/stat.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif
#include <fcntl.h> #include <fcntl.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif
#include <errno.h> #include <errno.h>
#include <event.h> #include <event.h>
@ -25,9 +23,19 @@ int called = 0;
#define NEVENT 20000 #define NEVENT 20000
struct opal_event *ev[NEVENT]; struct event *ev[NEVENT];
void static int
rand_int(int n)
{
#ifdef WIN32
return (int)(rand() * n);
#else
return (int)(random() % n);
#endif
}
static void
time_cb(int fd, short event, void *arg) time_cb(int fd, short event, void *arg)
{ {
struct timeval tv; struct timeval tv;
@ -37,13 +45,13 @@ time_cb(int fd, short event, void *arg)
if (called < 10*NEVENT) { if (called < 10*NEVENT) {
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
j = random() % NEVENT; j = rand_int(NEVENT);
tv.tv_sec = 0; tv.tv_sec = 0;
tv.tv_usec = random() % 50000L; tv.tv_usec = rand_int(50000);
if (tv.tv_usec % 2) if (tv.tv_usec % 2)
opal_evtimer_add(ev[j], &tv); evtimer_add(ev[j], &tv);
else else
opal_evtimer_del(ev[j]); evtimer_del(ev[j]);
} }
} }
} }
@ -55,19 +63,19 @@ main (int argc, char **argv)
int i; int i;
/* Initalize the event library */ /* Initalize the event library */
opal_event_init(); event_init();
for (i = 0; i < NEVENT; i++) { for (i = 0; i < NEVENT; i++) {
ev[i] = malloc(sizeof(struct opal_event)); ev[i] = malloc(sizeof(struct event));
/* Initalize one event */ /* Initalize one event */
opal_evtimer_set(ev[i], time_cb, ev[i]); evtimer_set(ev[i], time_cb, ev[i]);
tv.tv_sec = 0; tv.tv_sec = 0;
tv.tv_usec = random() % 50000L; tv.tv_usec = rand_int(50000);
opal_evtimer_add(ev[i], &tv); evtimer_add(ev[i], &tv);
} }
opal_event_dispatch(); event_dispatch();
return (called < NEVENT); return (called < NEVENT);
} }

Просмотреть файл

@ -2,14 +2,17 @@
* Compile with: * Compile with:
* cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent * cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_SYS_TYPES_H
#ifdef WIN32
#include <winsock2.h>
#endif
#include <sys/types.h> #include <sys/types.h>
#endif
#include <sys/stat.h> #include <sys/stat.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif
#ifdef HAVE_SYS_SOCKET_H #ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> #include <sys/socket.h>
#endif #endif
@ -18,21 +21,20 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif
#include <errno.h> #include <errno.h>
#include <event.h> #include <event.h>
#include <evutil.h>
int pair[2]; int pair[2];
int test_okay = 1; int test_okay = 1;
int called = 0; int called = 0;
void static void
write_cb(int fd, short event, void *arg) write_cb(int fd, short event, void *arg)
{ {
char *test = "test string"; const char *test = "test string";
int len; int len;
len = write(fd, test, strlen(test) + 1); len = write(fd, test, strlen(test) + 1);
@ -42,7 +44,7 @@ write_cb(int fd, short event, void *arg)
if (len > 0) { if (len > 0) {
if (!called) if (!called)
opal_event_add(arg, NULL); event_add(arg, NULL);
close(pair[0]); close(pair[0]);
} else if (called == 1) } else if (called == 1)
test_okay = 0; test_okay = 0;
@ -53,21 +55,25 @@ write_cb(int fd, short event, void *arg)
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
struct opal_event ev; struct event ev;
if (signal(SIGPIPE, SIG_IGN) == SIG_IGN) #ifndef WIN32
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
return (1); return (1);
#endif
if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
return (1); return (1);
/* Initalize the event library */ /* Initalize the event library */
opal_event_init(); event_init();
/* Initalize one event */ /* Initalize one event */
opal_event_set(&ev, pair[1], OPAL_EV_WRITE, write_cb, &ev); event_set(&ev, pair[1], EV_WRITE, write_cb, &ev);
opal_event_add(&ev, NULL);
opal_event_dispatch(); event_add(&ev, NULL);
event_dispatch();
return (test_okay); return (test_okay);
} }

Просмотреть файл

@ -1,17 +1,19 @@
#!/bin/sh #!/bin/sh
setup () { setup () {
export EVENT_NOKQUEUE=yes EVENT_NOKQUEUE=yes; export EVENT_NOKQUEUE
export EVENT_NODEVPOLL=yes EVENT_NODEVPOLL=yes; export EVENT_NODEVPOLL
export EVENT_NOPOLL=yes EVENT_NOPOLL=yes; export EVENT_NOPOLL
export EVENT_NOSELECT=yes EVENT_NOSELECT=yes; export EVENT_NOSELECT
export EVENT_NOEPOLL=yes EVENT_NOEPOLL=yes; export EVENT_NOEPOLL
export EVENT_NORTSIG=yes EVENT_NOEVPORT=yes; export EVENT_NOEVPORT
} }
test () { test () {
if ! ./test-init 2>/dev/null ; if ./test-init 2>/dev/null ;
then then
true
else
echo Skipping test echo Skipping test
return return
fi fi
@ -51,33 +53,39 @@ echo "Running tests:"
# Need to do this by hand? # Need to do this by hand?
setup setup
unset EVENT_NOKQUEUE unset EVENT_NOKQUEUE
export EVENT_NOKQUEUE
echo "KQUEUE" echo "KQUEUE"
test test
setup setup
unset EVENT_NODEVPOLL unset EVENT_NODEVPOLL
export EVENT_NODEVPOLL
echo "DEVPOLL" echo "DEVPOLL"
test test
setup setup
unset EVENT_NOPOLL unset EVENT_NOPOLL
export EVENT_NOPOLL
echo "POLL" echo "POLL"
test test
setup setup
unset EVENT_NOSELECT unset EVENT_NOSELECT
export EVENT_NOSELECT
echo "SELECT" echo "SELECT"
test test
setup
unset EVENT_NORTSIG
echo "RTSIG"
test
setup setup
unset EVENT_NOEPOLL unset EVENT_NOEPOLL
export EVENT_NOEPOLL
echo "EPOLL" echo "EPOLL"
test test
setup
unset EVENT_NOEVPORT
export EVENT_NOEVPORT
echo "EVPORT"
test

Просмотреть файл

@ -134,17 +134,17 @@ static int windows_module_map_to_socket_core(int processor_id, int *socket, int
return OPAL_ERR_NOT_SUPPORTED; return OPAL_ERR_NOT_SUPPORTED;
} }
static int windows_module_get_processor_info(int *num_processors, int *max_processor_id); static int windows_module_get_processor_info(int *num_processors, int *max_processor_id)
{ {
return OPAL_ERR_NOT_SUPPORTED; return OPAL_ERR_NOT_SUPPORTED;
} }
static int windows_module_get_socket_info(int *num_sockets, int *max_socket_num); static int windows_module_get_socket_info(int *num_sockets, int *max_socket_num)
{ {
return OPAL_ERR_NOT_SUPPORTED; return OPAL_ERR_NOT_SUPPORTED;
} }
static int windows_module_get_core_info(int socket, int *num_cores, int *max_core_num); static int windows_module_get_core_info(int socket, int *num_cores, int *max_core_num)
{ {
return OPAL_ERR_NOT_SUPPORTED; return OPAL_ERR_NOT_SUPPORTED;
} }

Просмотреть файл

@ -179,6 +179,7 @@ int orte_daemon(int argc, char *argv[])
char log_file[PATH_MAX]; char log_file[PATH_MAX];
char *jobidstring; char *jobidstring;
char *rml_uri; char *rml_uri;
char *tmp1, *tmp2;
int i; int i;
opal_buffer_t *buffer; opal_buffer_t *buffer;
char hostname[100]; char hostname[100];
@ -264,6 +265,36 @@ int orte_daemon(int argc, char *argv[])
if (1000 < i) i=0; if (1000 < i) i=0;
} }
/* _After_ opal_init_util() (and various other bookkeeping) but
_before_ orte_init(), we need to set an MCA param that tells
the orted not to use any other libevent mechanism except
"select" or "poll" (per potential pty issues with scalable
fd-monitoring mechanisms such as epoll() and friends -- these
issues *may* have been fixed in later OS releases and/or newer
versions of libevent, but we weren't willing to do all the
testing to figure it out. So force the orted to use
select()/poll() *only* -- there's so few fd's in the orted that
it really doesn't matter.
Note that pty's work fine with poll() on most systems, so we
prefer that (because it's more scalable than select()).
However, poll() does *not* work with ptys on OS X, so we use
select() there. */
mca_base_param_reg_string_name("opal", "event_include",
"Internal orted MCA param: tell opal_init() to use a specific mechanism in libevent",
true, true,
#ifdef __APPLE__
"select",
#else
"poll",
#endif
NULL);
tmp1 = mca_base_param_environ_variable("opal", NULL, "event_include");
asprintf(&tmp2, "%s=select", tmp1);
putenv(tmp2);
free(tmp1);
free(tmp2);
/* Okay, now on to serious business! */ /* Okay, now on to serious business! */
if (orted_globals.hnp) { if (orted_globals.hnp) {