13e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root/*
23e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * Copyright (C) 2010 The Android Open Source Project
33e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root *
43e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * Licensed under the Apache License, Version 2.0 (the "License");
53e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * you may not use this file except in compliance with the License.
63e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * You may obtain a copy of the License at
73e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root *
83e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root *      http://www.apache.org/licenses/LICENSE-2.0
93e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root *
103e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * Unless required by applicable law or agreed to in writing, software
113e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * distributed under the License is distributed on an "AS IS" BASIS,
123e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * See the License for the specific language governing permissions and
143e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * limitations under the License.
153e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root */
163e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root
173e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root#ifndef NET_FD_H_included
183e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root#define NET_FD_H_included
193e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root
2066516884139574a34a9855ca822d56ace0fdfe8bNathan Mittler#include "Errors.h"
2166516884139574a34a9855ca822d56ace0fdfe8bNathan Mittler#include "JniUtil.h"
2266516884139574a34a9855ca822d56ace0fdfe8bNathan Mittler
233e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root/**
243e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * Wraps access to the int inside a java.io.FileDescriptor, taking care of throwing exceptions.
253e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root */
263e46e4ee56c8e37158f46941dedd5b436d724baaKenny Rootclass NetFd {
273e46e4ee56c8e37158f46941dedd5b436d724baaKenny Rootpublic:
283e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root    NetFd(JNIEnv* env, jobject fileDescriptor)
2966516884139574a34a9855ca822d56ace0fdfe8bNathan Mittler        : mEnv(env), mFileDescriptor(fileDescriptor), mFd(-1) {}
303e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root
313e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root    bool isClosed() {
3266516884139574a34a9855ca822d56ace0fdfe8bNathan Mittler        mFd = conscrypt::JniUtil::jniGetFDFromFileDescriptor(mEnv, mFileDescriptor);
333e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root        bool closed = (mFd == -1);
343e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root        if (closed) {
3566516884139574a34a9855ca822d56ace0fdfe8bNathan Mittler            conscrypt::Errors::jniThrowException(mEnv, "java/net/SocketException", "Socket closed");
363e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root        }
373e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root        return closed;
383e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root    }
393e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root
403e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root    int get() const {
413e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root        return mFd;
423e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root    }
433e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root
443e46e4ee56c8e37158f46941dedd5b436d724baaKenny Rootprivate:
453e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root    JNIEnv* mEnv;
463e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root    jobject mFileDescriptor;
473e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root    int mFd;
483e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root
493e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root    // Disallow copy and assignment.
503e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root    NetFd(const NetFd&);
513e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root    void operator=(const NetFd&);
523e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root};
533e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root
543e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root/**
553e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * Used to retry syscalls that can return EINTR. This differs from TEMP_FAILURE_RETRY in that
563e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * it also considers the case where the reason for failure is that another thread called
573e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * Socket.close.
583e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root */
5966516884139574a34a9855ca822d56ace0fdfe8bNathan Mittler#define NET_FAILURE_RETRY(fd, exp)                     \
6066516884139574a34a9855ca822d56ace0fdfe8bNathan Mittler    ({                                                 \
6166516884139574a34a9855ca822d56ace0fdfe8bNathan Mittler        typeof(exp) _rc;                               \
6266516884139574a34a9855ca822d56ace0fdfe8bNathan Mittler        do {                                           \
6366516884139574a34a9855ca822d56ace0fdfe8bNathan Mittler            _rc = (exp);                               \
6466516884139574a34a9855ca822d56ace0fdfe8bNathan Mittler            if (_rc == -1) {                           \
6566516884139574a34a9855ca822d56ace0fdfe8bNathan Mittler                if (fd.isClosed() || errno != EINTR) { \
6666516884139574a34a9855ca822d56ace0fdfe8bNathan Mittler                    break;                             \
6766516884139574a34a9855ca822d56ace0fdfe8bNathan Mittler                }                                      \
6866516884139574a34a9855ca822d56ace0fdfe8bNathan Mittler            }                                          \
6966516884139574a34a9855ca822d56ace0fdfe8bNathan Mittler        } while (_rc == -1);                           \
7066516884139574a34a9855ca822d56ace0fdfe8bNathan Mittler        _rc;                                           \
7166516884139574a34a9855ca822d56ace0fdfe8bNathan Mittler    })
723e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root
7366516884139574a34a9855ca822d56ace0fdfe8bNathan Mittler#endif  // NET_FD_H_included
74