转载于 http://no001.blog.51cto.com/1142339/1354154
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#ifndef socket_poll_h
#define socket_poll_h
#include <stdbool.h>
typedef
int
poll_fd;
struct
event {
void
* s;
bool
read;
bool
write;
};
static
bool
sp_invalid(poll_fd fd);
static
poll_fd sp_create();
static
void
sp_release(poll_fd fd);
static
int
sp_add(poll_fd fd,
int
sock,
void
*ud);
static
void
sp_del(poll_fd fd,
int
sock);
static
void
sp_write(poll_fd,
int
sock,
void
*ud,
bool
enable);
static
int
sp_wait(poll_fd,
struct
event *e,
int
max);
static
void
sp_nonblocking(
int
sock);
#ifdef __linux__
#include "socket_epoll.h"
#endif
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined (__NetBSD__)
#include "socket_kqueue.h"
#endif
#endif
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
#ifndef poll_socket_epoll_h
#define poll_socket_epoll_h
#include <netdb.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
static
bool
sp_invalid(
int
efd) {
return
efd == -1;
}
static
int
sp_create() {
return
epoll_create(1024);
}
static
void
sp_release(
int
efd) {
close(efd);
}
static
int
sp_add(
int
efd,
int
sock,
void
*ud) {
struct
epoll_event ev;
ev.events = EPOLLIN;
ev.data.ptr = ud;
if
(epoll_ctl(efd, EPOLL_CTL_ADD, sock, &ev) == -1) {
return
1;
}
return
0;
}
static
void
sp_del(
int
efd,
int
sock) {
epoll_ctl(efd, EPOLL_CTL_DEL, sock , NULL);
}
static
void
sp_write(
int
efd,
int
sock,
void
*ud,
bool
enable) {
struct
epoll_event ev;
ev.events = EPOLLIN | (enable ? EPOLLOUT : 0);
ev.data.ptr = ud;
epoll_ctl(efd, EPOLL_CTL_MOD, sock, &ev);
}
static
int
sp_wait(
int
efd,
struct
event *e,
int
max) {
struct
epoll_event ev[max];
int
n = epoll_wait(efd , ev, max, -1);
int
i;
for
(i=0;i<n;i++) {
e[i].s = ev[i].data.ptr;
unsigned flag = ev[i].events;
e[i].write = (flag & EPOLLOUT) != 0;
e[i].read = (flag & EPOLLIN) != 0;
}
return
n;
}
static
void
sp_nonblocking(
int
fd) {
int
flag = fcntl(fd, F_GETFL, 0);
if
( -1 == flag ) {
return
;
}
fcntl(fd, F_SETFL, flag | O_NONBLOCK);
}
#endif
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
#ifndef poll_socket_kqueue_h
#define poll_socket_kqueue_h
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/event.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
static
bool
sp_invalid(
int
kfd) {
return
kfd == -1;
}
static
int
sp_create() {
return
kqueue();
}
static
void
sp_release(
int
kfd) {
close(kfd);
}
static
void
sp_del(
int
kfd,
int
sock) {
struct
kevent ke;
EV_SET(&ke, sock, EVFILT_READ, EV_DELETE, 0, 0, NULL);
kevent(kfd, &ke, 1, NULL, 0, NULL);
EV_SET(&ke, sock, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
kevent(kfd, &ke, 1, NULL, 0, NULL);
}
static
int
sp_add(
int
kfd,
int
sock,
void
*ud) {
struct
kevent ke;
EV_SET(&ke, sock, EVFILT_READ, EV_ADD, 0, 0, ud);
if
(kevent(kfd, &ke, 1, NULL, 0, NULL) == -1) {
return
1;
}
EV_SET(&ke, sock, EVFILT_WRITE, EV_ADD, 0, 0, ud);
if
(kevent(kfd, &ke, 1, NULL, 0, NULL) == -1) {
EV_SET(&ke, sock, EVFILT_READ, EV_DELETE, 0, 0, NULL);
kevent(kfd, &ke, 1, NULL, 0, NULL);
return
1;
}
EV_SET(&ke, sock, EVFILT_WRITE, EV_DISABLE, 0, 0, ud);
if
(kevent(kfd, &ke, 1, NULL, 0, NULL) == -1) {
sp_del(kfd, sock);
return
1;
}
return
0;
}
static
void
sp_write(
int
kfd,
int
sock,
void
*ud,
bool
enable) {
struct
kevent ke;
EV_SET(&ke, sock, EVFILT_WRITE, enable ? EV_ENABLE : EV_DISABLE, 0, 0, ud);
if
(kevent(kfd, &ke, 1, NULL, 0, NULL) == -1) {
// todo: check error
}
}
static
int
sp_wait(
int
kfd,
struct
event *e,
int
max) {
struct
kevent ev[max];
int
n = kevent(kfd, NULL, 0, ev, max, NULL);
int
i;
for
(i=0;i<n;i++) {
e[i].s = ev[i].udata;
unsigned filter = ev[i].filter;
e[i].write = (filter == EVFILT_WRITE);
e[i].read = (filter == EVFILT_READ);
}
return
n;
}
static
void
sp_nonblocking(
int
fd) {
int
flag = fcntl(fd, F_GETFL, 0);
if
( -1 == flag ) {
return
;
}
fcntl(fd, F_SETFL, flag | O_NONBLOCK);
}
#endif
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
#ifndef _RWLOCK_H_
#define _RWLOCK_H_
struct
rwlock {
int
write;
int
read;
};
static
inline
void
rwlock_init(
struct
rwlock *lock) {
lock->write = 0;
lock->read = 0;
}
static
inline
void
rwlock_rlock(
struct
rwlock *lock) {
for
(;;) {
while
(lock->write) {
__sync_synchronize();
}
__sync_add_and_fetch(&lock->read,1);
if
(lock->write) {
__sync_sub_and_fetch(&lock->read,1);
}
else
{
break
;
}
}
}
static
inline
void
rwlock_wlock(
struct
rwlock *lock) {
while
(__sync_lock_test_and_set(&lock->write,1)) {}
while
(lock->read) {
__sync_synchronize();
}
}
static
inline
void
rwlock_wunlock(
struct
rwlock *lock) {
__sync_lock_release(&lock->write);
}
static
inline
void
rwlock_runlock(
struct
rwlock *lock) {
__sync_sub_and_fetch(&lock->read,1);
}
#endif
|
1
2
3
4
5
6
|
#ifndef SKYNET_ENV_H
#define SKYNET_ENV_H
const
char
* skynet_getenv(
const
char
*key);
void
skynet_setenv(
const
char
*key,
const
char
*value);
void
skynet_env_init();
#endif
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
#
include
"skynet_env.h"
#
include
<lua.h>
#
include
<lauxlib.h>
#
include
<stdlib.h>
#
include
<assert.h>
struct skynet_env {
int
lock;
lua_State *L;
};
static
struct skynet_env *E = NULL;
#define LOCK(q)
while
(__sync_lock_test_and_set(&(q)->lock,
1
)) {}
#define UNLOCK(q) __sync_lock_release(&(q)->lock);
const
char *
skynet_getenv(
const
char *key) {
LOCK(E)
lua_State *L = E->L;
lua_getglobal(L, key);
const
char * result = lua_tostring(L, -
1
);
lua_pop(L,
1
);
UNLOCK(E)
return
result;
}
void
skynet_setenv(
const
char *key,
const
char *value) {
LOCK(E)
lua_State *L = E->L;
lua_getglobal(L, key);
assert(lua_isnil(L, -
1
));
lua_pop(L,
1
);
lua_pushstring(L,value);
lua_setglobal(L,key);
UNLOCK(E)
}
void
skynet_env_init() {
E = malloc(sizeof(*E));
E->lock =
0
;
E->L = luaL_newstate();
}
|