add solaris port backend

master
Marc Alexander Lehmann 2007-11-16 01:33:53 +00:00
parent adb3066ebd
commit ca5022c45d
6 changed files with 189 additions and 7 deletions

View File

@ -147,8 +147,14 @@ PREPROCESSOR SYMBOLS
will be detected at runtime and routed around by disabling this
backend.
EV_USE_PORT
If defined to be "1", libev will compile in support for the Solaris
10 port style backend. Its availability will be detected at runtime,
otherwise another method will be used as fallback. This is the
preferred backend for Solaris 10 systems.
EV_USE_DEVPOLL
EV_USE_PORTS
reserved for future expansion, works like the USE symbols above.

28
ev.c
View File

@ -61,6 +61,10 @@ extern "C" {
# define EV_USE_KQUEUE 1
# endif
# if HAVE_PORT_H && HAVE_PORT_H && HAVE_PORT_CREATE && !defined (EV_USE_PORT)
# define EV_USE_PORT 1
# endif
#endif
#include <math.h>
@ -95,6 +99,10 @@ extern "C" {
# define EV_USE_MONOTONIC 1
#endif
#ifndef EV_USE_REALTIME
# define EV_USE_REALTIME 1
#endif
#ifndef EV_USE_SELECT
# define EV_USE_SELECT 1
# define EV_SELECT_USE_FD_SET 1
@ -116,8 +124,8 @@ extern "C" {
# define EV_USE_KQUEUE 0
#endif
#ifndef EV_USE_REALTIME
# define EV_USE_REALTIME 1
#ifndef EV_USE_PORT
# define EV_USE_PORT 0
#endif
/**/
@ -712,6 +720,9 @@ childcb (EV_P_ struct ev_signal *sw, int revents)
/*****************************************************************************/
#if EV_USE_PORT
# include "ev_port.c"
#endif
#if EV_USE_KQUEUE
# include "ev_kqueue.c"
#endif
@ -780,6 +791,9 @@ loop_init (EV_P_ unsigned int flags)
flags |= 0x0000ffff;
method = 0;
#if EV_USE_PORT
if (!method && (flags & EVMETHOD_PORT )) method = port_init (EV_A_ flags);
#endif
#if EV_USE_KQUEUE
if (!method && (flags & EVMETHOD_KQUEUE)) method = kqueue_init (EV_A_ flags);
#endif
@ -803,6 +817,9 @@ loop_destroy (EV_P)
{
int i;
#if EV_USE_PORT
if (method == EVMETHOD_PORT ) port_destroy (EV_A);
#endif
#if EV_USE_KQUEUE
if (method == EVMETHOD_KQUEUE) kqueue_destroy (EV_A);
#endif
@ -835,12 +852,15 @@ loop_destroy (EV_P)
static void
loop_fork (EV_P)
{
#if EV_USE_EPOLL
if (method == EVMETHOD_EPOLL ) epoll_fork (EV_A);
#if EV_USE_PORT
if (method == EVMETHOD_PORT ) port_fork (EV_A);
#endif
#if EV_USE_KQUEUE
if (method == EVMETHOD_KQUEUE) kqueue_fork (EV_A);
#endif
#if EV_USE_EPOLL
if (method == EVMETHOD_EPOLL ) epoll_fork (EV_A);
#endif
if (ev_is_active (&sigev))
{

2
ev.h
View File

@ -241,7 +241,7 @@ union ev_any_watcher
#define EVMETHOD_EPOLL 0x00000004 /* linux */
#define EVMETHOD_KQUEUE 0x00000008 /* bsd */
#define EVMETHOD_DEVPOLL 0x00000010 /* solaris 8 */ /* NYI */
#define EVMETHOD_PORT 0x00000020 /* solaris 10 */ /* NYI */
#define EVMETHOD_PORT 0x00000020 /* solaris 10 */
/* flag bits */
#define EVFLAG_NOENV 0x01000000 /* do NOT consult environment */

147
ev_port.c Normal file
View File

@ -0,0 +1,147 @@
/*
* Copyright 2007 Marc Alexander Lehmann <libev@schmorp.de>
*
* 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 <sys/types.h>
#include <sys/time.h>
#include <poll.h>
#include <port.h>
#include <string.h>
#include <errno.h>
static void
port_modify (EV_P_ int fd, int oev, int nev)
{
/* we need to reassociate no matter what, as closes are
* once more silently being discarded.
*/
if (!nev)
{
if (oev)
port_dissociate (port_fd, PORT_SOURCE_FD, fd);
}
else if (0 >
port_associate (
port_fd, PORT_SOURCE_FD, fd,
(nev & EV_READ ? POLLIN : 0)
| (nev & EV_WRITE ? POLLOUT : 0),
0
)
)
{
if (errno == EBADFD)
fd_kill (EV_A_ fd);
else
syserr ("(libev) port_associate");
}
}
static void
port_poll (EV_P_ ev_tstamp timeout)
{
int res, i;
struct timespec ts;
uint_t nget = 1;
ts.tv_sec = (time_t)timeout;
ts.tv_nsec = (long)(timeout - (ev_tstamp)ts.tv_sec) * 1e9;
res = port_getn (port_fd, port_events, port_eventmax, &nget, &ts);
if (res < 0)
{
if (errno != EINTR && errno != ETIME)
syserr ("(libev) port_getn");
return;
}
for (i = 0; i < nget; ++i)
{
if (port_events [i].portev_source == PORT_SOURCE_FD)
{
int fd = port_events [i].portev_object;
fd_event (
EV_A_
fd,
(port_events [i].portev_events & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0)
| (port_events [i].portev_events & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0)
);
anfds [fd].events = 0; /* event received == disassociated */
fd_change (EV_A_ fd); /* need to reify later */
}
}
if (expect_false (nget == port_eventmax))
{
ev_free (port_events);
port_eventmax = array_roundsize (port_event_t, port_eventmax << 1);
port_events = (port_event_t *)ev_malloc (sizeof (port_event_t) * port_eventmax);
}
}
static int
port_init (EV_P_ int flags)
{
/* Initalize the kernel queue */
if ((port_fd = port_create ()) < 0)
return 0;
fcntl (port_fd, F_SETFD, FD_CLOEXEC); /* not sure if necessary, hopefully doesn't hurt */
method_fudge = 1e-3; /* needed to compensate for port_getn returning early */
method_modify = port_modify;
method_poll = port_poll;
port_eventmax = 64; /* intiial number of events receivable per poll */
port_events = (port_event_t *)ev_malloc (sizeof (port_event_t) * port_eventmax);
return EVMETHOD_PORT;
}
static void
port_destroy (EV_P)
{
close (port_fd);
ev_free (port_events);
}
static void
port_fork (EV_P)
{
close (port_fd);
while ((port_fd = port_create ()) < 0)
syserr ("(libev) port");
fcntl (port_fd, F_SETFD, FD_CLOEXEC);
/* re-register interest in fds */
fd_rearm_all (EV_A);
}

View File

@ -44,6 +44,12 @@ VARx(struct kevent *, kqueue_events)
VARx(int, kqueue_eventmax)
#endif
#if EV_USE_PORT || EV_GENWRAP
VARx(int, port_fd)
VARx(struct port_event *, port_events)
VARx(int, port_eventmax)
#endif
VARx(ANFD *, anfds)
VARx(int, anfdmax)

View File

@ -1,4 +1,4 @@
/* DO NOT EDIT, automaticlaly generated by update_ev_wrap */
/* DO NOT EDIT, automatically generated by update_ev_wrap */
#define now_floor ((loop)->now_floor)
#define mn_now ((loop)->mn_now)
#define rtmn_diff ((loop)->rtmn_diff)
@ -27,6 +27,9 @@
#define kqueue_changecnt ((loop)->kqueue_changecnt)
#define kqueue_events ((loop)->kqueue_events)
#define kqueue_eventmax ((loop)->kqueue_eventmax)
#define port_fd ((loop)->port_fd)
#define port_events ((loop)->port_events)
#define port_eventmax ((loop)->port_eventmax)
#define anfds ((loop)->anfds)
#define anfdmax ((loop)->anfdmax)
#define pendings ((loop)->pendings)