net/FakeSocket.cpp | 123 ++++++++++++++++++++++++++++------------------------- net/FakeSocket.hpp | 4 - 2 files changed, 69 insertions(+), 58 deletions(-)
New commits: commit 53416a290dbb6f83c688aed4d94bf3e91d53a812 Author: Tor Lillqvist <t...@iki.fi> AuthorDate: Mon Sep 17 20:39:53 2018 +0300 Commit: Tor Lillqvist <t...@collabora.com> CommitDate: Mon Sep 17 20:44:18 2018 +0300 Add fakeSocketShutdown() and drop fakeSocketFeed() Not sure whether the shutdown() implementation matches real shutdown() semantics, especially with regards to the behaviour of poll(), read(), and write() (on both the socket itself and the connectd one) afterwards. But let's see. The feed() API turned out to be not needed. (And in any case, it was suposed to be completely equivalent to writing to the peer socket.) diff --git a/net/FakeSocket.cpp b/net/FakeSocket.cpp index 37bfe7a7c..8dc214ae9 100644 --- a/net/FakeSocket.cpp +++ b/net/FakeSocket.cpp @@ -44,6 +44,7 @@ struct FakeSocketPair int fd[2]; bool listening; int connectingFd; + bool shutdown[2]; bool readable[2]; std::vector<char> buffer[2]; std::mutex *mutex; @@ -54,6 +55,8 @@ struct FakeSocketPair fd[1] = -1; listening = false; connectingFd = -1; + shutdown[0] = false; + shutdown[1] = false; readable[0] = false; readable[1] = false; mutex = new std::mutex(); @@ -104,11 +107,6 @@ int fakeSocketSocket() FakeSocketPair& result = fds[i]; result.fd[0] = i*2; - result.fd[1] = -1; - result.listening = false; - result.connectingFd = -1; - result.buffer[0].resize(0); - result.buffer[1].resize(0); loggingBuffer << "FakeSocket Create " << i*2 << flush(); @@ -187,17 +185,28 @@ static bool checkForPoll(std::vector<FakeSocketPair>& fds, struct pollfd *pollfd bool retval = false; for (int i = 0; i < nfds; i++) { - // Caller sets POLLNVAL for invalid fds. - if (pollfds[i].revents != POLLNVAL) + const int K = ((pollfds[i].fd)&1); + const int N = 1 - K; + + if (pollfds[i].fd < 0 || pollfds[i].fd/2 >= fds.size()) + { + pollfds[i].revents = POLLNVAL; + } + else { - pollfds[i].revents = 0; const int K = ((pollfds[i].fd)&1); - const int N = 1 - K; + if (fds[pollfds[i].fd/2].fd[K] == -1) + pollfds[i].revents = POLLNVAL; + else + pollfds[i].revents = 0; + } + + if (pollfds[i].revents == 0) + { if (pollfds[i].events & POLLIN) { - if (fds[pollfds[i].fd/2].fd[K] != -1 && - (fds[pollfds[i].fd/2].readable[K] || - (K == 0 && fds[pollfds[i].fd/2].listening && fds[pollfds[i].fd/2].connectingFd != -1))) + if (fds[pollfds[i].fd/2].readable[K] || + (K == 0 && fds[pollfds[i].fd/2].listening && fds[pollfds[i].fd/2].connectingFd != -1)) { pollfds[i].revents |= POLLIN; retval = true; @@ -207,7 +216,7 @@ static bool checkForPoll(std::vector<FakeSocketPair>& fds, struct pollfd *pollfd // open and not readable. if (pollfds[i].events & POLLOUT) { - if (fds[pollfds[i].fd/2].fd[N] != -1 && !fds[pollfds[i].fd/2].readable[N]) + if (fds[pollfds[i].fd/2].fd[N] != -1 && !fds[pollfds[i].fd/2].readable[N] && !fds[pollfds[i].fd/2].shutdown[N]) { pollfds[i].revents |= POLLOUT; retval = true; @@ -231,22 +240,6 @@ int fakeSocketPoll(struct pollfd *pollfds, int nfds, int timeout) std::vector<FakeSocketPair>& fds = getFds(); std::unique_lock<std::mutex> fdsLock(fdsMutex); - for (int i = 0; i < nfds; i++) - { - if (pollfds[i].fd < 0 || pollfds[i].fd/2 >= fds.size()) - { - pollfds[i].revents = POLLNVAL; - } - else - { - const int K = ((pollfds[i].fd)&1); - if (fds[pollfds[i].fd/2].fd[K] == -1) - pollfds[i].revents = POLLNVAL; - else - pollfds[i].revents = 0; - } - } - std::unique_lock<std::mutex> cvLock(cvMutex); fdsLock.unlock(); @@ -502,6 +495,13 @@ ssize_t fakeSocketRead(int fd, void *buf, size_t nbytes) return -1; } + if (pair.shutdown[K]) + { + loggingBuffer << "FakeSocket EBADF: Read from fd " << fd << " (shut down), " << nbytes << (nbytes == 1 ? " byte" : " bytes") << flush(); + errno = EBADF; + return -1; + } + if (!pair.readable[K]) { loggingBuffer << "FakeSocket EAGAIN: Read from fd " << fd << ", " << nbytes << (nbytes == 1 ? " byte" : " bytes") << flush(); @@ -520,8 +520,8 @@ ssize_t fakeSocketRead(int fd, void *buf, size_t nbytes) memmove(buf, pair.buffer[K].data(), result); pair.buffer[K].resize(0); - // If peer is closed, we continue to be readable - if (pair.fd[N] == -1) + // If peer is closed or shut down, we continue to be readable + if (pair.fd[N] == -1 || pair.shutdown[N]) pair.readable[K] = true; else pair.readable[K] = false; @@ -533,13 +533,13 @@ ssize_t fakeSocketRead(int fd, void *buf, size_t nbytes) return result; } -ssize_t fakeSocketFeed(int fd, const void *buf, size_t nbytes) +ssize_t fakeSocketWrite(int fd, const void *buf, size_t nbytes) { std::vector<FakeSocketPair>& fds = getFds(); std::unique_lock<std::mutex> fdsLock(fdsMutex); if (fd < 0 || fd/2 >= fds.size()) { - loggingBuffer << "FakeSocket EBADF: Feed to fd " << fd << ", " << nbytes << (nbytes == 1 ? " byte" : " bytes") << flush(); + loggingBuffer << "FakeSocket EBADF: Write to fd " << fd << ", " << nbytes << (nbytes == 1 ? " byte" : " bytes") << flush(); errno = EBADF; return -1; } @@ -549,41 +549,49 @@ ssize_t fakeSocketFeed(int fd, const void *buf, size_t nbytes) std::unique_lock<std::mutex> fdLock(pair.mutex[0]); fdsLock.unlock(); - // K: for this fd, whose read buffer we want to write into + // K: for this fd + // N: for its peer, whose read buffer we want to write into const int K = (fd&1); + const int N = 1 - K; if (pair.fd[K] == -1) { - loggingBuffer << "FakeSocket EBADF: Feed to fd " << fd << ", " << nbytes << (nbytes == 1 ? " byte" : " bytes") << flush(); + loggingBuffer << "FakeSocket EBADF: Write to fd " << fd << ", " << nbytes << (nbytes == 1 ? " byte" : " bytes") << flush(); + errno = EBADF; + return -1; + } + + if (pair.shutdown[K]) + { + loggingBuffer << "FakeSocket EBADF: Write to fd " << fd << " (shut down), " << nbytes << (nbytes == 1 ? " byte" : " bytes") << flush(); errno = EBADF; return -1; } - if (pair.readable[K]) + if (pair.readable[N]) { - loggingBuffer << "FakeSocket EAGAIN: Feed to fd " << fd << ", " << nbytes << (nbytes == 1 ? " byte" : " bytes") << flush(); + loggingBuffer << "FakeSocket EAGAIN: Write to fd " << fd << ", " << nbytes << (nbytes == 1 ? " byte" : " bytes") << flush(); errno = EAGAIN; return -1; } - pair.buffer[K].resize(nbytes); - memmove(pair.buffer[K].data(), buf, nbytes); - pair.readable[K] = true; + pair.buffer[N].resize(nbytes); + memmove(pair.buffer[N].data(), buf, nbytes); + pair.readable[N] = true; cv.notify_all(); - loggingBuffer << "FakeSocket Feed to fd " << fd << ": " << nbytes << (nbytes == 1 ? " byte" : " bytes") << flush(); - + loggingBuffer << "FakeSocket Write to fd " << fd << ": " << nbytes << (nbytes == 1 ? " byte" : " bytes") << flush(); return nbytes; } -ssize_t fakeSocketWrite(int fd, const void *buf, size_t nbytes) +int fakeSocketShutdown(int fd) { std::vector<FakeSocketPair>& fds = getFds(); std::unique_lock<std::mutex> fdsLock(fdsMutex); if (fd < 0 || fd/2 >= fds.size()) { - loggingBuffer << "FakeSocket EBADF: Write to fd " << fd << ", " << nbytes << (nbytes == 1 ? " byte" : " bytes") << flush(); + loggingBuffer << "FakeSocket EBADF: Shutdown fd " << fd << flush(); errno = EBADF; return -1; } @@ -593,33 +601,29 @@ ssize_t fakeSocketWrite(int fd, const void *buf, size_t nbytes) std::unique_lock<std::mutex> fdLock(pair.mutex[0]); fdsLock.unlock(); - // K: for this fd - // N: for its peer, whose read buffer we want to write into const int K = (fd&1); const int N = 1 - K; if (pair.fd[K] == -1) { - loggingBuffer << "FakeSocket EBADF: Write to fd " << fd << ", " << nbytes << (nbytes == 1 ? " byte" : " bytes") << flush(); + loggingBuffer << "FakeSocket EBADF: Shutdown fd " << fd << flush(); errno = EBADF; return -1; } - if (pair.readable[N]) + if (pair.fd[N] == -1) { - loggingBuffer << "FakeSocket EAGAIN: Write to fd " << fd << ", " << nbytes << (nbytes == 1 ? " byte" : " bytes") << flush(); - errno = EAGAIN; + loggingBuffer << "FakeSocket ENOTCONN: Shutdown fd " << fd << flush(); + errno = ENOTCONN; return -1; } - pair.buffer[N].resize(nbytes); - memmove(pair.buffer[N].data(), buf, nbytes); - pair.readable[N] = true; + pair.shutdown[K] = true; + pair.readable[K] = true; - cv.notify_all(); + loggingBuffer << "FakeSocket Shutdown fd " << fd << flush(); - loggingBuffer << "FakeSocket Write to fd " << fd << ": " << nbytes << (nbytes == 1 ? " byte" : " bytes") << flush(); - return nbytes; + return 0; } int fakeSocketClose(int fd) @@ -641,6 +645,13 @@ int fakeSocketClose(int fd) const int K = (fd&1); const int N = 1 - K; + if (pair.fd[K] == -1) + { + loggingBuffer << "FakeSocket EBADF: Close fd " << fd << flush(); + errno = EBADF; + return -1; + } + assert(pair.fd[K] == fd); pair.fd[K] = -1; diff --git a/net/FakeSocket.hpp b/net/FakeSocket.hpp index 7edd8c43c..bf9e94d61 100644 --- a/net/FakeSocket.hpp +++ b/net/FakeSocket.hpp @@ -38,10 +38,10 @@ ssize_t fakeSocketAvailableDataLength(int fd); ssize_t fakeSocketRead(int fd, void *buf, size_t nbytes); -ssize_t fakeSocketFeed(int fd, const void *buf, size_t nbytes); - ssize_t fakeSocketWrite(int fd, const void *buf, size_t nbytes); +int fakeSocketShutdown(int fd); + int fakeSocketClose(int fd); #endif // MOBILEAPP _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits