Files
oceanbase/deps/ussl-hook/loop/pipefd.c
2023-07-12 05:12:18 +00:00

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;
}