mirror of
https://github.com/darlinghq/darling-libkqueue.git
synced 2024-11-23 11:49:50 +00:00
Merge new files from the trunk
git-svn-id: svn://svn.code.sf.net/p/libkqueue/code/branches/stable@564 fb4e3144-bc1c-4b72-a658-5bcd248dd7f7
This commit is contained in:
parent
eb1f64505b
commit
01da712896
385
src/linux/platform.c
Normal file
385
src/linux/platform.c
Normal file
@ -0,0 +1,385 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Mark Heily <mark@heily.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "../common/private.h"
|
||||
|
||||
//XXX-FIXME TEMP
|
||||
const struct filter evfilt_proc = EVFILT_NOTIMPL;
|
||||
|
||||
/*
|
||||
* Per-thread epoll event buffer used to ferry data between
|
||||
* kevent_wait() and kevent_copyout().
|
||||
*/
|
||||
static __thread struct epoll_event epevt[MAX_KEVENT];
|
||||
|
||||
const struct kqueue_vtable kqops = {
|
||||
linux_kqueue_init,
|
||||
linux_kqueue_free,
|
||||
linux_kevent_wait,
|
||||
linux_kevent_copyout,
|
||||
NULL,
|
||||
NULL,
|
||||
linux_eventfd_init,
|
||||
linux_eventfd_close,
|
||||
linux_eventfd_raise,
|
||||
linux_eventfd_lower,
|
||||
linux_eventfd_descriptor
|
||||
};
|
||||
|
||||
// NOT USED YET: taken from trunk
|
||||
#ifdef TODO
|
||||
int
|
||||
linux_kqueue_init(struct kqueue *kq)
|
||||
{
|
||||
kq->kq_id = epoll_create(1);
|
||||
if (kq->kq_id < 0) {
|
||||
dbg_perror("epoll_create(2)");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (filter_register_all(kq) < 0) {
|
||||
close(kq->kq_id);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
#if DEADWOOD
|
||||
//might be useful in posix
|
||||
|
||||
/* Add each filter's pollable descriptor to the epollset */
|
||||
for (i = 0; i < EVFILT_SYSCOUNT; i++) {
|
||||
filt = &kq->kq_filt[i];
|
||||
|
||||
if (filt->kf_id == 0)
|
||||
continue;
|
||||
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
ev.events = EPOLLIN;
|
||||
ev.data.ptr = filt;
|
||||
|
||||
if (epoll_ctl(kq->kq_id, EPOLL_CTL_ADD, filt->kf_pfd, &ev) < 0) {
|
||||
dbg_perror("epoll_ctl(2)");
|
||||
close(kq->kq_id);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
linux_kqueue_free(struct kqueue *kq UNUSED)
|
||||
{
|
||||
abort();//FIXME
|
||||
}
|
||||
|
||||
static int
|
||||
linux_kevent_wait_hires(
|
||||
struct kqueue *kq,
|
||||
const struct timespec *timeout)
|
||||
{
|
||||
fd_set fds;
|
||||
int n;
|
||||
int epfd;
|
||||
|
||||
dbg_printf("waiting for events (timeout=%ld sec %ld nsec)",
|
||||
timeout->tv_sec, timeout->tv_nsec);
|
||||
epfd = kqueue_epfd(kq);
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(epfd, &fds);
|
||||
n = pselect(epfd + 1, &fds, NULL , NULL, timeout, NULL);
|
||||
if (n < 0) {
|
||||
if (errno == EINTR) {
|
||||
dbg_puts("signal caught");
|
||||
return (-1);
|
||||
}
|
||||
dbg_perror("pselect(2)");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (n);
|
||||
}
|
||||
|
||||
int
|
||||
linux_kevent_wait(
|
||||
struct kqueue *kq,
|
||||
int nevents,
|
||||
const struct timespec *ts)
|
||||
{
|
||||
int timeout, nret;
|
||||
|
||||
/* Use pselect() if the timeout value is less than one millisecond. */
|
||||
if (ts != NULL && ts->tv_sec == 0 && ts->tv_nsec < 1000000) {
|
||||
nret = linux_kevent_wait_hires(kq, ts);
|
||||
|
||||
/* Otherwise, use epoll_wait() directly */
|
||||
} else {
|
||||
|
||||
/* Convert timeout to the format used by epoll_wait() */
|
||||
if (ts == NULL)
|
||||
timeout = -1;
|
||||
else
|
||||
timeout = (1000 * ts->tv_sec) + (ts->tv_nsec / 1000000);
|
||||
|
||||
dbg_puts("waiting for events");
|
||||
nret = epoll_wait(kqueue_epfd(kq), &epevt[0], nevents, timeout);
|
||||
if (nret < 0) {
|
||||
dbg_perror("epoll_wait");
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
return (nret);
|
||||
}
|
||||
|
||||
int
|
||||
linux_kevent_copyout(struct kqueue *kq, int nready,
|
||||
struct kevent *eventlist, int nevents UNUSED)
|
||||
{
|
||||
struct epoll_event *ev;
|
||||
struct filter *filt;
|
||||
struct knote *kn;
|
||||
int i, nret, rv;
|
||||
|
||||
nret = nready;
|
||||
for (i = 0; i < nready; i++) {
|
||||
ev = &epevt[i];
|
||||
kn = (struct knote *) ev->data.ptr;
|
||||
knote_lock(kn);
|
||||
filt = &kq->kq_filt[~(kn->kev.filter)];
|
||||
rv = filt->kf_copyout(eventlist, kn, ev);
|
||||
if (slowpath(rv < 0)) {
|
||||
dbg_puts("knote_copyout failed");
|
||||
/* XXX-FIXME: hard to handle this without losing events */
|
||||
abort();
|
||||
}
|
||||
|
||||
/*
|
||||
* Certain flags cause the associated knote to be deleted
|
||||
* or disabled.
|
||||
*/
|
||||
if (eventlist->flags & EV_DISPATCH)
|
||||
knote_disable(filt, kn); //FIXME: Error checking
|
||||
if (eventlist->flags & EV_ONESHOT) {
|
||||
knote_delete(filt, kn); //FIXME: Error checking
|
||||
} else {
|
||||
knote_unlock(kn);
|
||||
}
|
||||
|
||||
/* If an empty kevent structure is returned, the event is discarded. */
|
||||
/* TODO: add these semantics to windows + solaris platform.c */
|
||||
if (fastpath(eventlist->filter != 0)) {
|
||||
eventlist++;
|
||||
} else {
|
||||
dbg_puts("spurious wakeup, discarding event");
|
||||
nret--;
|
||||
}
|
||||
}
|
||||
|
||||
return (nret);
|
||||
}
|
||||
|
||||
#endif //NOT USED
|
||||
|
||||
|
||||
int
|
||||
linux_eventfd_init(struct eventfd *e)
|
||||
{
|
||||
int evfd;
|
||||
|
||||
if ((evfd = eventfd(0, 0)) < 0) {
|
||||
dbg_perror("eventfd");
|
||||
return (-1);
|
||||
}
|
||||
if (fcntl(evfd, F_SETFL, O_NONBLOCK) < 0) {
|
||||
dbg_perror("fcntl");
|
||||
close(evfd);
|
||||
return (-1);
|
||||
}
|
||||
e->ef_id = evfd;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
linux_eventfd_close(struct eventfd *e)
|
||||
{
|
||||
close(e->ef_id);
|
||||
e->ef_id = -1;
|
||||
}
|
||||
|
||||
int
|
||||
linux_eventfd_raise(struct eventfd *e)
|
||||
{
|
||||
uint64_t counter;
|
||||
int rv = 0;
|
||||
|
||||
dbg_puts("raising event level");
|
||||
counter = 1;
|
||||
if (write(e->ef_id, &counter, sizeof(counter)) < 0) {
|
||||
switch (errno) {
|
||||
case EAGAIN:
|
||||
/* Not considered an error */
|
||||
break;
|
||||
|
||||
case EINTR:
|
||||
rv = -EINTR;
|
||||
break;
|
||||
|
||||
default:
|
||||
dbg_printf("write(2): %s", strerror(errno));
|
||||
rv = -1;
|
||||
}
|
||||
}
|
||||
return (rv);
|
||||
}
|
||||
|
||||
int
|
||||
linux_eventfd_lower(struct eventfd *e)
|
||||
{
|
||||
uint64_t cur;
|
||||
ssize_t n;
|
||||
int rv = 0;
|
||||
|
||||
/* Reset the counter */
|
||||
dbg_puts("lowering event level");
|
||||
n = read(e->ef_id, &cur, sizeof(cur));
|
||||
if (n < 0) {
|
||||
switch (errno) {
|
||||
case EAGAIN:
|
||||
/* Not considered an error */
|
||||
break;
|
||||
|
||||
case EINTR:
|
||||
rv = -EINTR;
|
||||
break;
|
||||
|
||||
default:
|
||||
dbg_printf("read(2): %s", strerror(errno));
|
||||
rv = -1;
|
||||
}
|
||||
} else if (n != sizeof(cur)) {
|
||||
dbg_puts("short read");
|
||||
rv = -1;
|
||||
}
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
||||
int
|
||||
linux_eventfd_descriptor(struct eventfd *e)
|
||||
{
|
||||
return (e->ef_id);
|
||||
}
|
||||
|
||||
int
|
||||
linux_get_descriptor_type(struct knote *kn)
|
||||
{
|
||||
socklen_t slen;
|
||||
struct stat sb;
|
||||
int i, lsock;
|
||||
|
||||
/*
|
||||
* Test if the descriptor is a socket.
|
||||
*/
|
||||
if (fstat(kn->kev.ident, &sb) < 0) {
|
||||
dbg_perror("fstat(2)");
|
||||
return (-1);
|
||||
}
|
||||
if (! S_ISSOCK(sb.st_mode)) {
|
||||
//FIXME: could be a pipe, device file, or other non-regular file
|
||||
kn->kn_flags |= KNFL_REGULAR_FILE;
|
||||
dbg_printf("fd %d is a regular file\n", (int)kn->kev.ident);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test if the socket is active or passive.
|
||||
*/
|
||||
slen = sizeof(lsock);
|
||||
lsock = 0;
|
||||
i = getsockopt(kn->kev.ident, SOL_SOCKET, SO_ACCEPTCONN, (char *) &lsock, &slen);
|
||||
if (i < 0) {
|
||||
switch (errno) {
|
||||
case ENOTSOCK: /* same as lsock = 0 */
|
||||
return (0);
|
||||
break;
|
||||
default:
|
||||
dbg_perror("getsockopt(3)");
|
||||
return (-1);
|
||||
}
|
||||
} else {
|
||||
if (lsock)
|
||||
kn->kn_flags |= KNFL_PASSIVE_SOCKET;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
epoll_event_dump(struct epoll_event *evt)
|
||||
{
|
||||
static __thread char buf[128];
|
||||
|
||||
if (evt == NULL)
|
||||
return "(null)";
|
||||
|
||||
#define EPEVT_DUMP(attrib) \
|
||||
if (evt->events & attrib) \
|
||||
strcat(&buf[0], #attrib" ");
|
||||
|
||||
snprintf(&buf[0], 128, " { data = %p, events = ", evt->data.ptr);
|
||||
EPEVT_DUMP(EPOLLIN);
|
||||
EPEVT_DUMP(EPOLLOUT);
|
||||
#if defined(HAVE_EPOLLRDHUP)
|
||||
EPEVT_DUMP(EPOLLRDHUP);
|
||||
#endif
|
||||
EPEVT_DUMP(EPOLLONESHOT);
|
||||
EPEVT_DUMP(EPOLLET);
|
||||
strcat(&buf[0], "}\n");
|
||||
|
||||
return (&buf[0]);
|
||||
#undef EPEVT_DUMP
|
||||
}
|
||||
|
||||
int
|
||||
epoll_update(int op, struct filter *filt, struct knote *kn, struct epoll_event *ev)
|
||||
{
|
||||
dbg_printf("op=%d fd=%d events=%s", op, (int)kn->kev.ident,
|
||||
epoll_event_dump(ev));
|
||||
if (epoll_ctl(filter_epfd(filt), op, kn->kev.ident, ev) < 0) {
|
||||
dbg_printf("epoll_ctl(2): %s", strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a file descriptor, return the path to the file it refers to.
|
||||
*/
|
||||
int
|
||||
linux_fd_to_path(char *buf, size_t bufsz, int fd)
|
||||
{
|
||||
char path[1024]; //TODO: Maxpathlen, etc.
|
||||
|
||||
if (snprintf(&path[0], sizeof(path), "/proc/%d/fd/%d", getpid(), fd) < 0)
|
||||
return (-1);
|
||||
|
||||
memset(buf, 0, bufsz);
|
||||
return (readlink(path, buf, bufsz));
|
||||
}
|
||||
|
86
src/linux/platform.h
Normal file
86
src/linux/platform.h
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Mark Heily <mark@heily.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _KQUEUE_LINUX_PLATFORM_H
|
||||
#define _KQUEUE_LINUX_PLATFORM_H
|
||||
|
||||
struct filter;
|
||||
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <sys/eventfd.h>
|
||||
#include <sys/signalfd.h>
|
||||
#include <sys/timerfd.h>
|
||||
|
||||
/*
|
||||
* Get the current thread ID
|
||||
*/
|
||||
# define _GNU_SOURCE
|
||||
# include <linux/unistd.h>
|
||||
# include <sys/syscall.h>
|
||||
# include <unistd.h>
|
||||
extern long int syscall (long int __sysno, ...);
|
||||
|
||||
/* Convenience macros to access the epoll descriptor for the kqueue */
|
||||
#define kqueue_epfd(kq) ((kq)->kq_id)
|
||||
#define filter_epfd(filt) ((filt)->kf_kqueue->kq_id)
|
||||
|
||||
/*
|
||||
* Additional members of struct filter
|
||||
*/
|
||||
#undef FILTER_PLATFORM_SPECIFIC
|
||||
|
||||
/*
|
||||
* Additional members of struct knote
|
||||
*/
|
||||
#define KNOTE_PLATFORM_SPECIFIC \
|
||||
int kn_epollfd; /* A copy of filter->epfd */ \
|
||||
union { \
|
||||
int kn_timerfd; \
|
||||
int kn_signalfd; \
|
||||
int kn_inotifyfd; \
|
||||
int kn_eventfd; \
|
||||
} kdata
|
||||
|
||||
/*
|
||||
* Additional members of struct kqueue
|
||||
*/
|
||||
#define KQUEUE_PLATFORM_SPECIFIC \
|
||||
struct epoll_event kq_plist[MAX_KEVENT]; \
|
||||
size_t kq_nplist
|
||||
|
||||
int linux_kqueue_init(struct kqueue *);
|
||||
void linux_kqueue_free(struct kqueue *);
|
||||
|
||||
int linux_kevent_wait(struct kqueue *, int, const struct timespec *);
|
||||
int linux_kevent_copyout(struct kqueue *, int, struct kevent *, int);
|
||||
|
||||
int linux_knote_copyout(struct kevent *, struct knote *);
|
||||
|
||||
int linux_eventfd_init(struct eventfd *);
|
||||
void linux_eventfd_close(struct eventfd *);
|
||||
int linux_eventfd_raise(struct eventfd *);
|
||||
int linux_eventfd_lower(struct eventfd *);
|
||||
int linux_eventfd_descriptor(struct eventfd *);
|
||||
|
||||
/* utility functions */
|
||||
|
||||
int linux_get_descriptor_type(struct knote *);
|
||||
int linux_fd_to_path(char *, size_t, int);
|
||||
|
||||
|
||||
#endif /* ! _KQUEUE_LINUX_PLATFORM_H */
|
90
src/posix/platform.c
Normal file
90
src/posix/platform.c
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Mark Heily <mark@heily.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "../common/private.h"
|
||||
|
||||
int
|
||||
posix_kqueue_init(struct kqueue *kq UNUSED)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
posix_kqueue_free(struct kqueue *kq UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
posix_eventfd_init(struct eventfd *e)
|
||||
{
|
||||
int sd[2];
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sd) < 0) {
|
||||
return (-1);
|
||||
}
|
||||
if ((fcntl(sd[0], F_SETFL, O_NONBLOCK) < 0) ||
|
||||
(fcntl(sd[1], F_SETFL, O_NONBLOCK) < 0)) {
|
||||
close(sd[0]);
|
||||
close(sd[1]);
|
||||
return (-1);
|
||||
}
|
||||
e->ef_wfd = sd[0];
|
||||
e->ef_id = sd[1];
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
posix_eventfd_close(struct eventfd *e)
|
||||
{
|
||||
close(e->ef_id);
|
||||
close(e->ef_wfd);
|
||||
e->ef_id = -1;
|
||||
}
|
||||
|
||||
int
|
||||
posix_eventfd_raise(struct eventfd *e)
|
||||
{
|
||||
dbg_puts("raising event level");
|
||||
if (write(e->ef_wfd, ".", 1) < 0) {
|
||||
/* FIXME: handle EAGAIN and EINTR */
|
||||
dbg_printf("write(2) on fd %d: %s", e->ef_wfd, strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
posix_eventfd_lower(struct eventfd *e)
|
||||
{
|
||||
char buf[1024];
|
||||
|
||||
/* Reset the counter */
|
||||
dbg_puts("lowering event level");
|
||||
if (read(e->ef_id, &buf, sizeof(buf)) < 0) {
|
||||
/* FIXME: handle EAGAIN and EINTR */
|
||||
/* FIXME: loop so as to consume all data.. may need mutex */
|
||||
dbg_printf("read(2): %s", strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
posix_eventfd_descriptor(struct eventfd *e)
|
||||
{
|
||||
return (e->ef_id);
|
||||
}
|
86
src/posix/platform.h
Normal file
86
src/posix/platform.h
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Mark Heily <mark@heily.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _KQUEUE_POSIX_PLATFORM_H
|
||||
#define _KQUEUE_POSIX_PLATFORM_H
|
||||
|
||||
/* Required by glibc for MAP_ANON */
|
||||
#define __USE_MISC 1
|
||||
|
||||
#include "../../include/sys/event.h"
|
||||
|
||||
/*
|
||||
* GCC-compatible atomic operations
|
||||
*/
|
||||
#define atomic_inc(p) __sync_add_and_fetch((p), 1)
|
||||
#define atomic_dec(p) __sync_sub_and_fetch((p), 1)
|
||||
#define atomic_cas(p, oval, nval) __sync_val_compare_and_swap(p, oval, nval)
|
||||
#define atomic_ptr_cas(p, oval, nval) __sync_val_compare_and_swap(p, oval, nval)
|
||||
|
||||
/*
|
||||
* GCC-compatible branch prediction macros
|
||||
*/
|
||||
#define fastpath(x) __builtin_expect((x), 1)
|
||||
#define slowpath(x) __builtin_expect((x), 0)
|
||||
|
||||
/*
|
||||
* GCC-compatible attributes
|
||||
*/
|
||||
#ifdef MAKE_STATIC
|
||||
# define CONSTRUCTOR
|
||||
#else
|
||||
# define CONSTRUCTOR __attribute__ ((constructor))
|
||||
#endif
|
||||
#define VISIBLE __attribute__((visibility("default")))
|
||||
#define HIDDEN __attribute__((visibility("hidden")))
|
||||
#define UNUSED __attribute__((unused))
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <pthread.h>
|
||||
#include <poll.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
* Additional members of 'struct eventfd'
|
||||
*/
|
||||
#define EVENTFD_PLATFORM_SPECIFIC \
|
||||
int ef_wfd
|
||||
|
||||
void posix_kqueue_free(struct kqueue *);
|
||||
int posix_kqueue_init(struct kqueue *);
|
||||
|
||||
int posix_kevent_wait(struct kqueue *, const struct timespec *);
|
||||
int posix_kevent_copyout(struct kqueue *, int, struct kevent *, int);
|
||||
|
||||
int posix_eventfd_init(struct eventfd *);
|
||||
void posix_eventfd_close(struct eventfd *);
|
||||
int posix_eventfd_raise(struct eventfd *);
|
||||
int posix_eventfd_lower(struct eventfd *);
|
||||
int posix_eventfd_descriptor(struct eventfd *);
|
||||
|
||||
#endif /* ! _KQUEUE_POSIX_PLATFORM_H */
|
Loading…
Reference in New Issue
Block a user