diff options
| author | 2012-04-02 17:02:19 -0700 | |
|---|---|---|
| committer | 2012-04-02 18:41:10 -0700 | |
| commit | 7b5be95cb3903087742f1079fe89cddd8abe3696 (patch) | |
| tree | fb45ed1d40465a1283e9a416b90433bc9b66ffe0 /libs/gui/BitTube.cpp | |
| parent | 0e1080f887bcd80c75910cabe7b2eca224bf739c (diff) | |
use a socketpair instead of a pipe in BitTube
Bug: 6252830
Change-Id: Ia7a7b08409517214136261c05569dc5959a597ab
Diffstat (limited to 'libs/gui/BitTube.cpp')
| -rw-r--r-- | libs/gui/BitTube.cpp | 74 |
1 files changed, 63 insertions, 11 deletions
diff --git a/libs/gui/BitTube.cpp b/libs/gui/BitTube.cpp index 55f4178421..355a319c52 100644 --- a/libs/gui/BitTube.cpp +++ b/libs/gui/BitTube.cpp @@ -16,9 +16,9 @@ #include <stdint.h> #include <sys/types.h> +#include <sys/socket.h> #include <fcntl.h> -#include <signal.h> #include <unistd.h> #include <utils/Errors.h> @@ -30,17 +30,25 @@ namespace android { // ---------------------------------------------------------------------------- +// Socket buffer size. The default is typically about 128KB, which is much larger than +// we really need. So we make it smaller. +static const size_t SOCKET_BUFFER_SIZE = 4 * 1024; + + BitTube::BitTube() : mSendFd(-1), mReceiveFd(-1) { - int fds[2]; - if (pipe(fds) == 0) { - mReceiveFd = fds[0]; - mSendFd = fds[1]; - fcntl(mReceiveFd, F_SETFL, O_NONBLOCK); - fcntl(mSendFd, F_SETFL, O_NONBLOCK); - // ignore SIGPIPE, we handle write errors through EPIPE instead - signal(SIGPIPE, SIG_IGN); + int sockets[2]; + if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) { + int size = SOCKET_BUFFER_SIZE; + setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)); + setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)); + setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)); + setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)); + fcntl(sockets[0], F_SETFL, O_NONBLOCK); + fcntl(sockets[1], F_SETFL, O_NONBLOCK); + mReceiveFd = sockets[0]; + mSendFd = sockets[1]; } else { mReceiveFd = -errno; ALOGE("BitTube: pipe creation failed (%s)", strerror(-mReceiveFd)); @@ -52,6 +60,9 @@ BitTube::BitTube(const Parcel& data) { mReceiveFd = dup(data.readFileDescriptor()); if (mReceiveFd >= 0) { + int size = SOCKET_BUFFER_SIZE; + setsockopt(mReceiveFd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)); + setsockopt(mReceiveFd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)); fcntl(mReceiveFd, F_SETFL, O_NONBLOCK); } else { mReceiveFd = -errno; @@ -86,7 +97,7 @@ ssize_t BitTube::write(void const* vaddr, size_t size) { ssize_t err, len; do { - len = ::write(mSendFd, vaddr, size); + len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL); err = len < 0 ? errno : 0; } while (err == EINTR); return err == 0 ? len : -err; @@ -97,7 +108,7 @@ ssize_t BitTube::read(void* vaddr, size_t size) { ssize_t err, len; do { - len = ::read(mReceiveFd, vaddr, size); + len = ::recv(mReceiveFd, vaddr, size, MSG_DONTWAIT); err = len < 0 ? errno : 0; } while (err == EINTR); if (err == EAGAIN || err == EWOULDBLOCK) { @@ -119,5 +130,46 @@ status_t BitTube::writeToParcel(Parcel* reply) const return result; } + +ssize_t BitTube::sendObjects(const sp<BitTube>& tube, + void const* events, size_t count, size_t objSize) +{ + ssize_t numObjects = 0; + for (size_t i=0 ; i<count ; i++) { + const char* vaddr = reinterpret_cast<const char*>(events) + objSize * i; + ssize_t size = tube->write(vaddr, objSize); + if (size < 0) { + // error occurred + numObjects = -size; + break; + } else if (size == 0) { + // no more space + break; + } + numObjects++; + } + return numObjects; +} + +ssize_t BitTube::recvObjects(const sp<BitTube>& tube, + void* events, size_t count, size_t objSize) +{ + ssize_t numObjects = 0; + for (size_t i=0 ; i<count ; i++) { + char* vaddr = reinterpret_cast<char*>(events) + objSize * i; + ssize_t size = tube->read(vaddr, objSize); + if (size < 0) { + // error occurred + numObjects = -size; + break; + } else if (size == 0) { + // no more messages + break; + } + numObjects++; + } + return numObjects; +} + // ---------------------------------------------------------------------------- }; // namespace android |