87 lines
3.5 KiB
C
87 lines
3.5 KiB
C
/**
|
|
* Copyright (c) 2021 OceanBase
|
|
* OceanBase CE is licensed under Mulan PubL v2.
|
|
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
|
* You may obtain a copy of Mulan PubL v2 at:
|
|
* http://license.coscl.org.cn/MulanPubL-2.0
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
* See the Mulan PubL v2 for more details.
|
|
*/
|
|
|
|
static int pipefd_handle_event(pipefd_t *s)
|
|
{
|
|
int ret = 0;
|
|
// because edge trigger, a loop is needed.
|
|
// Note, if an error occurs while processing a client_fd_info,
|
|
// the returned result will still be 0.
|
|
while (1) {
|
|
client_fd_info_t client_fd_info;
|
|
int rbytes = read(s->fd, &client_fd_info, sizeof(client_fd_info));
|
|
if (0 == rbytes) {
|
|
ret = EAGAIN;
|
|
ussl_log_error("read EOF, pipe fd may be closed, pipefd:%d, errno:%d",
|
|
s->fd, errno);
|
|
break;
|
|
} else if (-1 == rbytes) {
|
|
if (EAGAIN != errno && EWOULDBLOCK != errno) {
|
|
ussl_log_error("call read failed, pipefd:%d, errno:%d", s->fd, errno);
|
|
}
|
|
ret = EAGAIN;
|
|
break;
|
|
} else {
|
|
clientfd_sk_t *clientfd_sk = (clientfd_sk_t *)s->fty->create((ussl_sf_t *)s->fty);
|
|
if (!clientfd_sk) {
|
|
ussl_log_error("create clientfd sock failed, the clientfd will be closed. clientfd:%d, "
|
|
"gid:%lu, errno:%d",
|
|
client_fd_info.client_fd, client_fd_info.client_gid, errno);
|
|
if (client_fd_info.client_fd >= 0) {
|
|
shutdown(client_fd_info.client_fd, SHUT_WR);
|
|
if (0 != libc_epoll_ctl(client_fd_info.org_epfd, EPOLL_CTL_ADD,
|
|
client_fd_info.client_fd, &client_fd_info.event)) {
|
|
ussl_log_error("give back fd to origin epoll failed, fd:%d, errno:%d",
|
|
client_fd_info.client_fd, errno);
|
|
}
|
|
}
|
|
} else {
|
|
memcpy(&clientfd_sk->fd_info, &client_fd_info, sizeof(client_fd_info));
|
|
clientfd_sk->fd = client_fd_info.client_fd;
|
|
clientfd_sk->ep = s->ep;
|
|
if (0 != ussl_eloop_regist(clientfd_sk->ep, (ussl_sock_t *)clientfd_sk, EPOLLOUT)) {
|
|
ussl_log_warn("[pipefd_handle_event] call eloop_regist failed, the clientfd will be "
|
|
"closed. clientfd:%d, gid:0x%lx, errno:%d",
|
|
client_fd_info.client_fd, client_fd_info.client_gid, errno);
|
|
if (client_fd_info.client_fd >= 0) {
|
|
shutdown(client_fd_info.client_fd, SHUT_WR);
|
|
if (0 != libc_epoll_ctl(client_fd_info.org_epfd, EPOLL_CTL_ADD,
|
|
client_fd_info.client_fd, &client_fd_info.event)) {
|
|
ussl_log_warn("give back fd to origin epoll failed, fd:%d, errno:%d",
|
|
client_fd_info.client_fd, errno);
|
|
}
|
|
}
|
|
s->fty->destroy(s->fty, (ussl_sock_t *)clientfd_sk);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int pipefd_init(ussl_eloop_t *ep, pipefd_t *s, ussl_sf_t *sf, int fd)
|
|
{
|
|
int ret = 0;
|
|
ussl_sk_init((ussl_sock_t *)s, sf, (void *)pipefd_handle_event, fd);
|
|
s->ep = ep;
|
|
if (s->fd < 0) {
|
|
ret = -EIO;
|
|
errno = EINVAL;
|
|
ussl_log_error("pipefd is initialized with an invalid fd, errno:%d", errno);
|
|
} else if (0 != (ret = ussl_eloop_regist(ep, (ussl_sock_t *)s, EPOLLIN))) {
|
|
ussl_log_error("regist pipefd failed, ret:%d", ret);
|
|
if (s->fd >= 0) {
|
|
close(s->fd);
|
|
}
|
|
}
|
|
return ret;
|
|
} |