Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mac OSX 支持补丁 #4

Merged
merged 3 commits into from
Nov 29, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
.PHONY : all clean

CFLAGS = -g -Wall
SHARED = -fPIC --shared
LUALIB = -llua
LDFLAGS = -lpthread -llua -ldl -lm

uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
ifeq ($(uname_S), Darwin)
SHARED = -fPIC -dynamiclib -Wl,-undefined,dynamic_lookup
else
LDFLAGS += -ldl -lrt -Wl,-E
SHARED = -fPIC --shared
endif

all : \
skynet \
Expand Down Expand Up @@ -37,7 +44,7 @@ skynet : \
skynet-src/skynet_env.c \
skynet-src/skynet_monitor.c \
luacompat/compat52.c
gcc $(CFLAGS) -Iluacompat -Wl,-E -o $@ $^ -Iskynet-src -lpthread -ldl -lrt -Wl,-E $(LUALIB) -lm
gcc $(CFLAGS) -Iluacompat -o $@ $^ -Iskynet-src $(LDFLAGS)

luaclib:
mkdir luaclib
Expand Down Expand Up @@ -89,4 +96,4 @@ client : client-src/client.c

clean :
rm skynet client service/*.so luaclib/*.so


70 changes: 69 additions & 1 deletion connection/connection.c
Original file line number Diff line number Diff line change
@@ -1,28 +1,67 @@
#include "connection.h"

#include <stdio.h>
#include <sys/epoll.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>

/* Test for polling API */
#ifdef __linux__
#define HAVE_EPOLL 1
#endif

#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined (__NetBSD__)
#define HAVE_KQUEUE 1
#endif

#if !defined(HAVE_EPOLL) && !defined(HAVE_KQUEUE)
#error "system does not support epoll or kqueue API"
#endif
/* ! Test for polling API */

#ifdef HAVE_EPOLL
#include <sys/epoll.h>
#elif HAVE_KQUEUE
#include <sys/event.h>
#endif

#define EPOLLQUEUE 32

struct connection_pool {
#ifdef HAVE_EPOLL
int epoll_fd;
#elif HAVE_KQUEUE
int kqueue_fd;
#endif
int queue_len;
int queue_head;
#ifdef HAVE_EPOLL
struct epoll_event ev[EPOLLQUEUE];
#elif HAVE_KQUEUE
struct kevent ev[EPOLLQUEUE];
#endif
};

struct connection_pool *
connection_newpool(int max) {
#ifdef HAVE_EPOLL
int epoll_fd = epoll_create(max);
if (epoll_fd == -1) {
return NULL;
}
#elif HAVE_KQUEUE
int kqueue_fd = kqueue();
if (kqueue_fd == -1) {
return NULL;
}
#endif

struct connection_pool * pool = malloc(sizeof(*pool));
#ifdef HAVE_EPOLL
pool->epoll_fd = epoll_fd;
#elif HAVE_KQUEUE
pool->kqueue_fd = kqueue_fd;
#endif
pool->queue_len = 0;
pool->queue_head = 0;

Expand All @@ -31,32 +70,57 @@ connection_newpool(int max) {

void
connection_deletepool(struct connection_pool * pool) {
#if HAVE_EPOLL
close(pool->epoll_fd);
#elif HAVE_KQUEUE
close(pool->kqueue_fd);
#endif
free(pool);
}

int
connection_add(struct connection_pool * pool, int fd, void *ud) {
#if HAVE_EPOLL
struct epoll_event ev;
ev.events = EPOLLIN;
ev.data.ptr = ud;

if (epoll_ctl(pool->epoll_fd, EPOLL_CTL_ADD, fd, &ev) == -1) {
return 1;
}
#elif HAVE_KQUEUE
struct kevent ke;
EV_SET(&ke, fd, EVFILT_READ, EV_ADD, 0, 0, ud);
if (kevent(pool->kqueue_fd, &ke, 1, NULL, 0, NULL) == -1) {
return 1;
}
#endif
return 0;
}

void
connection_del(struct connection_pool * pool, int fd) {
#if HAVE_EPOLL
epoll_ctl(pool->epoll_fd, EPOLL_CTL_DEL, fd , NULL);
#elif HAVE_KQUEUE
struct kevent ke;
EV_SET(&ke, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
kevent(pool->kqueue_fd, &ke, 1, NULL, 0, NULL);
#endif
close(fd);
}

static int
_read_queue(struct connection_pool * pool, int timeout) {
pool->queue_head = 0;
#if HAVE_EPOLL
int n = epoll_wait(pool->epoll_fd , pool->ev, EPOLLQUEUE, timeout);
#elif HAVE_KQUEUE
struct timespec timeoutspec;
timeoutspec.tv_sec = timeout / 1000;
timeoutspec.tv_nsec = (timeout % 1000) * 1000000;
int n = kevent(pool->kqueue_fd, NULL, 0, pool->ev, EPOLLQUEUE, &timeoutspec);
#endif
if (n == -1) {
pool->queue_len = 0;
return -1;
Expand All @@ -72,6 +136,10 @@ connection_poll(struct connection_pool * pool, int timeout) {
return NULL;
}
}
#if HAVE_EPOLL
return pool->ev[pool->queue_head ++].data.ptr;
#elif HAVE_KQUEUE
return pool->ev[pool->queue_head ++].udata;
#endif
}

Loading