184f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom/*
284f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom * Copyright (C) 2010 The Android Open Source Project
384f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom *
484f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License");
584f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom * you may not use this file except in compliance with the License.
684f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom * You may obtain a copy of the License at
784f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom *
884f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom *      http://www.apache.org/licenses/LICENSE-2.0
984f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom *
1084f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom * Unless required by applicable law or agreed to in writing, software
1184f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS,
1284f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1384f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom * See the License for the specific language governing permissions and
1484f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom * limitations under the License.
1584f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom */
1684f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom
1784f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom#ifndef NET_FD_H_included
1884f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom#define NET_FD_H_included
1984f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom
2084f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom/**
2184f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom * Wraps access to the int inside a java.io.FileDescriptor, taking care of throwing exceptions.
2284f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom */
2384f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstromclass NetFd {
2484f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrompublic:
2584f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom    NetFd(JNIEnv* env, jobject fileDescriptor)
2684f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom        : mEnv(env), mFileDescriptor(fileDescriptor), mFd(-1)
2784f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom    {
2884f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom    }
2984f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom
3084f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom    bool isClosed() {
3184f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom        mFd = jniGetFDFromFileDescriptor(mEnv, mFileDescriptor);
3284f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom        bool closed = (mFd == -1);
3384f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom        if (closed) {
3484f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom            jniThrowException(mEnv, "java/net/SocketException", "Socket closed");
3584f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom        }
3684f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom        return closed;
3784f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom    }
3884f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom
3984f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom    int get() const {
4084f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom        return mFd;
4184f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom    }
4284f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom
4384f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstromprivate:
4484f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom    JNIEnv* mEnv;
4584f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom    jobject mFileDescriptor;
4684f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom    int mFd;
4784f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom
4884f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom    // Disallow copy and assignment.
4984f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom    NetFd(const NetFd&);
5084f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom    void operator=(const NetFd&);
5184f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom};
5284f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom
5384f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom/**
5484f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom * Used to retry syscalls that can return EINTR. This differs from TEMP_FAILURE_RETRY in that
5584f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom * it also considers the case where the reason for failure is that another thread called
5684f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom * Socket.close.
5784f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom */
5884f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom#define NET_FAILURE_RETRY(fd, exp) ({               \
5984f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom    typeof (exp) _rc;                               \
6084f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom    do {                                            \
6184f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom        _rc = (exp);                                \
6284f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom        if (_rc == -1) {                            \
6384f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom            if (fd.isClosed() || errno != EINTR) {  \
6484f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom                break;                              \
6584f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom            }                                       \
6684f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom        }                                           \
6784f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom    } while (_rc == -1);                            \
6884f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom    _rc; })
6984f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom
7084f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom#endif // NET_FD_H_included
71