support error event, see #644

This commit is contained in:
Cloud Wu
2017-05-27 10:41:29 +08:00
parent a504c5e624
commit 7400e51451
4 changed files with 22 additions and 4 deletions

View File

@@ -59,6 +59,7 @@ sp_wait(int efd, struct event *e, int max) {
unsigned flag = ev[i].events;
e[i].write = (flag & EPOLLOUT) != 0;
e[i].read = (flag & EPOLLIN) != 0;
e[i].error = (flag & EPOLLERR) != 0;
}
return n;

View File

@@ -38,17 +38,17 @@ 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) {
if (kevent(kfd, &ke, 1, NULL, 0, NULL) == -1 || ke.flags & EV_ERROR) {
return 1;
}
EV_SET(&ke, sock, EVFILT_WRITE, EV_ADD, 0, 0, ud);
if (kevent(kfd, &ke, 1, NULL, 0, NULL) == -1) {
if (kevent(kfd, &ke, 1, NULL, 0, NULL) == -1 || ke.flags & EV_ERROR) {
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) {
if (kevent(kfd, &ke, 1, NULL, 0, NULL) == -1 || ke.flags & EV_ERROR) {
sp_del(kfd, sock);
return 1;
}
@@ -59,7 +59,7 @@ 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) {
if (kevent(kfd, &ke, 1, NULL, 0, NULL) == -1 || ke.flags & EV_ERROR) {
// todo: check error
}
}
@@ -75,6 +75,7 @@ sp_wait(int kfd, struct event *e, int max) {
unsigned filter = ev[i].filter;
e[i].write = (filter == EVFILT_WRITE);
e[i].read = (filter == EVFILT_READ);
e[i].error = false; // kevent has not error event
}
return n;

View File

@@ -9,6 +9,7 @@ struct event {
void * s;
bool read;
bool write;
bool error;
};
static bool sp_invalid(poll_fd fd);

View File

@@ -1302,6 +1302,21 @@ socket_server_poll(struct socket_server *ss, struct socket_message * result, int
break;
return type;
}
if (e->error) {
// close when error
int error;
socklen_t len = sizeof(error);
int code = getsockopt(s->fd, SOL_SOCKET, SO_ERROR, &error, &len);
if (code < 0) {
result->data = strerror(errno);
} else if (error != 0) {
result->data = strerror(error);
} else {
result->data = "Unknown error";
}
force_close(ss, s, result);
return SOCKET_ERR;
}
break;
}
}