128d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber/*
228d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber * Copyright (C) 2017 The Android Open Source Project
328d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber *
428d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
528d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber * you may not use this file except in compliance with the License.
628d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber * You may obtain a copy of the License at
728d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber *
828d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
928d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber *
1028d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber * Unless required by applicable law or agreed to in writing, software
1128d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1228d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1328d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber * See the License for the specific language governing permissions and
1428d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber * limitations under the License.
1528d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber */
1628d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber
1728d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber#include "PipeRelay.h"
1828d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber
1928d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber#include <sys/socket.h>
2028d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber#include <utils/Thread.h>
2128d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber
2228d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Hubernamespace android {
2328d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Hubernamespace lshal {
2428d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber
2528d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huberstruct PipeRelay::RelayThread : public Thread {
2628d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    explicit RelayThread(int fd, std::ostream &os);
2728d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber
2828d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    bool threadLoop() override;
2928d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber
3028d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huberprivate:
3128d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    int mFd;
3228d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    std::ostream &mOutStream;
3328d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber
3428d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    DISALLOW_COPY_AND_ASSIGN(RelayThread);
3528d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber};
3628d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber
3728d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber////////////////////////////////////////////////////////////////////////////////
3828d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber
3928d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas HuberPipeRelay::RelayThread::RelayThread(int fd, std::ostream &os)
4028d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    : mFd(fd),
4128d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber      mOutStream(os) {
4228d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber}
4328d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber
4428d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huberbool PipeRelay::RelayThread::threadLoop() {
4528d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    char buffer[1024];
4628d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    ssize_t n = read(mFd, buffer, sizeof(buffer));
4728d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber
4828d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    if (n <= 0) {
4928d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber        return false;
5028d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    }
5128d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber
5228d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    mOutStream.write(buffer, n);
5328d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber
5428d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    return true;
5528d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber}
5628d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber
5728d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber////////////////////////////////////////////////////////////////////////////////
5828d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber
5928d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas HuberPipeRelay::PipeRelay(std::ostream &os)
60734e378a7387b2d51f40f4e4cba8887703bd1839Chih-Hung Hsieh    : mInitCheck(NO_INIT) {
6128d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    int res = socketpair(AF_UNIX, SOCK_STREAM, 0 /* protocol */, mFds);
6228d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber
6328d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    if (res < 0) {
6428d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber        mInitCheck = -errno;
6528d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber        return;
6628d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    }
6728d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber
6828d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    mThread = new RelayThread(mFds[0], os);
6928d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    mInitCheck = mThread->run("RelayThread");
7028d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber}
7128d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber
7228d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Hubervoid PipeRelay::CloseFd(int *fd) {
7328d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    if (*fd >= 0) {
7428d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber        close(*fd);
7528d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber        *fd = -1;
7628d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    }
7728d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber}
7828d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber
7928d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas HuberPipeRelay::~PipeRelay() {
8028d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    if (mFds[1] >= 0) {
8128d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber        shutdown(mFds[1], SHUT_WR);
8228d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    }
8328d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber
8428d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    if (mFds[0] >= 0) {
8528d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber        shutdown(mFds[0], SHUT_RD);
8628d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    }
8728d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber
8828d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    if (mThread != NULL) {
8928d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber        mThread->join();
9028d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber        mThread.clear();
9128d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    }
9228d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber
9328d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    CloseFd(&mFds[1]);
9428d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    CloseFd(&mFds[0]);
9528d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber}
9628d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber
9728d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huberstatus_t PipeRelay::initCheck() const {
9828d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    return mInitCheck;
9928d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber}
10028d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber
10128d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huberint PipeRelay::fd() const {
10228d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber    return mFds[1];
10328d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber}
10428d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber
10528d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber}  // namespace lshal
10628d35913d5324dd520d80d9b6afdd0698afa8fd4Andreas Huber}  // namespace android
107