12008747941749ad27fe80663d23036ac320e998fJason Sams/*
22008747941749ad27fe80663d23036ac320e998fJason Sams * Copyright (C) 2011 The Android Open Source Project
32008747941749ad27fe80663d23036ac320e998fJason Sams *
42008747941749ad27fe80663d23036ac320e998fJason Sams * Licensed under the Apache License, Version 2.0 (the "License");
52008747941749ad27fe80663d23036ac320e998fJason Sams * you may not use this file except in compliance with the License.
62008747941749ad27fe80663d23036ac320e998fJason Sams * You may obtain a copy of the License at
72008747941749ad27fe80663d23036ac320e998fJason Sams *
82008747941749ad27fe80663d23036ac320e998fJason Sams *      http://www.apache.org/licenses/LICENSE-2.0
92008747941749ad27fe80663d23036ac320e998fJason Sams *
102008747941749ad27fe80663d23036ac320e998fJason Sams * Unless required by applicable law or agreed to in writing, software
112008747941749ad27fe80663d23036ac320e998fJason Sams * distributed under the License is distributed on an "AS IS" BASIS,
122008747941749ad27fe80663d23036ac320e998fJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132008747941749ad27fe80663d23036ac320e998fJason Sams * See the License for the specific language governing permissions and
142008747941749ad27fe80663d23036ac320e998fJason Sams * limitations under the License.
152008747941749ad27fe80663d23036ac320e998fJason Sams */
162008747941749ad27fe80663d23036ac320e998fJason Sams
172008747941749ad27fe80663d23036ac320e998fJason Sams#include "rsFifoSocket.h"
182008747941749ad27fe80663d23036ac320e998fJason Sams
192008747941749ad27fe80663d23036ac320e998fJason Sams#include <stdio.h>
202008747941749ad27fe80663d23036ac320e998fJason Sams#include <stdlib.h>
212008747941749ad27fe80663d23036ac320e998fJason Sams#include <ctype.h>
222008747941749ad27fe80663d23036ac320e998fJason Sams#include <unistd.h>
235f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams#include <poll.h>
242008747941749ad27fe80663d23036ac320e998fJason Sams#include <sys/types.h>
252008747941749ad27fe80663d23036ac320e998fJason Sams#include <sys/socket.h>
262008747941749ad27fe80663d23036ac320e998fJason Sams
2711496ac131bb691edf5bdcab3029dceef5c1e4e1Chih-Hung Hsiehnamespace android {
2811496ac131bb691edf5bdcab3029dceef5c1e4e1Chih-Hung Hsiehnamespace renderscript {
292008747941749ad27fe80663d23036ac320e998fJason Sams
302008747941749ad27fe80663d23036ac320e998fJason SamsFifoSocket::FifoSocket() {
315f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams    mShutdown = false;
322008747941749ad27fe80663d23036ac320e998fJason Sams}
332008747941749ad27fe80663d23036ac320e998fJason Sams
342008747941749ad27fe80663d23036ac320e998fJason SamsFifoSocket::~FifoSocket() {
352008747941749ad27fe80663d23036ac320e998fJason Sams
362008747941749ad27fe80663d23036ac320e998fJason Sams}
372008747941749ad27fe80663d23036ac320e998fJason Sams
385f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Samsbool FifoSocket::init(bool supportNonBlocking, bool supportReturnValues, size_t maxDataSize) {
392008747941749ad27fe80663d23036ac320e998fJason Sams    int ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
40c2459dc5f1c9d299247f77d565c5be5dc57c75e0Yang Ni    return (ret == 0);
412008747941749ad27fe80663d23036ac320e998fJason Sams}
422008747941749ad27fe80663d23036ac320e998fJason Sams
432008747941749ad27fe80663d23036ac320e998fJason Samsvoid FifoSocket::shutdown() {
445f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams    mShutdown = true;
455f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams    uint64_t d = 0;
465f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams    ::send(sv[0], &d, sizeof(d), 0);
475f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams    ::send(sv[1], &d, sizeof(d), 0);
485f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams    close(sv[0]);
495f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams    close(sv[1]);
502008747941749ad27fe80663d23036ac320e998fJason Sams}
512008747941749ad27fe80663d23036ac320e998fJason Sams
525f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Samsbool FifoSocket::writeAsync(const void *data, size_t bytes, bool waitForSpace) {
531a4efa363916977ef9aeab756725b3bdc880a15bJason Sams    if (bytes == 0) {
545f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams        return true;
551a4efa363916977ef9aeab756725b3bdc880a15bJason Sams    }
56af12ac6a08651464f8d823add667c706f993b587Steve Block    //ALOGE("writeAsync %p %i", data, bytes);
571a4efa363916977ef9aeab756725b3bdc880a15bJason Sams    size_t ret = ::send(sv[0], data, bytes, 0);
582008747941749ad27fe80663d23036ac320e998fJason Sams    rsAssert(ret == bytes);
59bd726b2159c14bd78d45f3157befcb733037f8d4Jason Sams    if (ret != bytes) {
60bd726b2159c14bd78d45f3157befcb733037f8d4Jason Sams        ALOGE("writeAsync %p %zu  ret %zu", data, bytes, ret);
61bd726b2159c14bd78d45f3157befcb733037f8d4Jason Sams    }
625f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams    return true;
632008747941749ad27fe80663d23036ac320e998fJason Sams}
642008747941749ad27fe80663d23036ac320e998fJason Sams
652008747941749ad27fe80663d23036ac320e998fJason Samsvoid FifoSocket::writeWaitReturn(void *retData, size_t retBytes) {
665f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams    if (mShutdown) {
675f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams        return;
685f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams    }
695f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams
70af12ac6a08651464f8d823add667c706f993b587Steve Block    //ALOGE("writeWaitReturn %p %i", retData, retBytes);
715f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams    size_t ret = ::recv(sv[0], retData, retBytes, MSG_WAITALL);
72af12ac6a08651464f8d823add667c706f993b587Steve Block    //ALOGE("writeWaitReturn %i", ret);
732008747941749ad27fe80663d23036ac320e998fJason Sams    rsAssert(ret == retBytes);
742008747941749ad27fe80663d23036ac320e998fJason Sams}
752008747941749ad27fe80663d23036ac320e998fJason Sams
762008747941749ad27fe80663d23036ac320e998fJason Samssize_t FifoSocket::read(void *data, size_t bytes) {
775f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams    if (mShutdown) {
785f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams        return 0;
795f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams    }
805f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams
81af12ac6a08651464f8d823add667c706f993b587Steve Block    //ALOGE("read %p %i", data, bytes);
825f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams    size_t ret = ::recv(sv[1], data, bytes, MSG_WAITALL);
835f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams    rsAssert(ret == bytes || mShutdown);
845f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams    //ALOGE("read ret %i  bytes %i", ret, bytes);
855f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams    if (mShutdown) {
865f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams        ret = 0;
875f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams    }
882008747941749ad27fe80663d23036ac320e998fJason Sams    return ret;
892008747941749ad27fe80663d23036ac320e998fJason Sams}
902008747941749ad27fe80663d23036ac320e998fJason Sams
915f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Samsbool FifoSocket::isEmpty() {
925f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams    struct pollfd p;
935f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams    p.fd = sv[1];
945f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams    p.events = POLLIN;
955f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams    int r = poll(&p, 1, 0);
965f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams    //ALOGE("poll r=%i", r);
975f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Sams    return r == 0;
982008747941749ad27fe80663d23036ac320e998fJason Sams}
992008747941749ad27fe80663d23036ac320e998fJason Sams
1002008747941749ad27fe80663d23036ac320e998fJason Sams
1015f27d6fb0b0b9184ba9820c629fc1354a635e515Jason Samsvoid FifoSocket::readReturn(const void *data, size_t bytes) {
102c2459dc5f1c9d299247f77d565c5be5dc57c75e0Yang Ni    ::send(sv[1], data, bytes, 0);
1032008747941749ad27fe80663d23036ac320e998fJason Sams}
1042008747941749ad27fe80663d23036ac320e998fJason Sams
10511496ac131bb691edf5bdcab3029dceef5c1e4e1Chih-Hung Hsieh} // namespace renderscript
10611496ac131bb691edf5bdcab3029dceef5c1e4e1Chih-Hung Hsieh} // namespace android
107