diff options
author | Mathias Agopian <mathias@google.com> | 2013-09-09 23:36:25 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2013-09-10 21:10:53 -0700 |
commit | 90ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0 (patch) | |
tree | 18e3cac4c05f7b19989dff34b507118c44bbd59b /libs/gui | |
parent | 63108c34ec181e923b68ee840bb7960f205466a7 (diff) | |
download | frameworks_native-90ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0.zip frameworks_native-90ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0.tar.gz frameworks_native-90ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0.tar.bz2 |
fix a few problems with BitTube
BitTube used to send objects one at a time and didn't
handle errors properly.
We now send all the objects in one call, which means they
have to be read as a single batch as well. This changes the
BitTube API.
Update SensorService to the new API.
Also added an API to set the size of the send buffer.
Bug: 10641596
Change-Id: I77c70d35e351fdba0416fae4b7ca3b1d56272251
Diffstat (limited to 'libs/gui')
-rw-r--r-- | libs/gui/BitTube.cpp | 100 | ||||
-rw-r--r-- | libs/gui/SensorEventQueue.cpp | 26 |
2 files changed, 68 insertions, 58 deletions
diff --git a/libs/gui/BitTube.cpp b/libs/gui/BitTube.cpp index cf44bb9..85a7de7 100644 --- a/libs/gui/BitTube.cpp +++ b/libs/gui/BitTube.cpp @@ -32,39 +32,26 @@ 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; +static const size_t DEFAULT_SOCKET_BUFFER_SIZE = 4 * 1024; BitTube::BitTube() : mSendFd(-1), mReceiveFd(-1) { - 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)); - } + init(DEFAULT_SOCKET_BUFFER_SIZE, DEFAULT_SOCKET_BUFFER_SIZE); +} + +BitTube::BitTube(size_t bufsize) + : mSendFd(-1), mReceiveFd(-1) +{ + init(bufsize, bufsize); } BitTube::BitTube(const Parcel& data) : mSendFd(-1), mReceiveFd(-1) { 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 { + if (mReceiveFd < 0) { mReceiveFd = -errno; ALOGE("BitTube(Parcel): can't dup filedescriptor (%s)", strerror(-mReceiveFd)); @@ -80,6 +67,25 @@ BitTube::~BitTube() close(mReceiveFd); } +void BitTube::init(size_t rcvbuf, size_t sndbuf) { + int sockets[2]; + if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) { + size_t size = DEFAULT_SOCKET_BUFFER_SIZE; + setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)); + setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)); + // sine we don't use the "return channel", we keep it small... + setsockopt(sockets[0], 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)); + } +} + status_t BitTube::initCheck() const { if (mReceiveFd < 0) { @@ -98,10 +104,10 @@ ssize_t BitTube::write(void const* vaddr, size_t size) ssize_t err, len; do { len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL); + // cannot return less than size, since we're using SOCK_SEQPACKET err = len < 0 ? errno : 0; } while (err == EINTR); return err == 0 ? len : -err; - } ssize_t BitTube::read(void* vaddr, size_t size) @@ -134,39 +140,31 @@ status_t BitTube::writeToParcel(Parcel* reply) const 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 - return size; - } else if (size == 0) { - // no more space - break; - } - numObjects++; - } - return numObjects; + const char* vaddr = reinterpret_cast<const char*>(events); + ssize_t size = tube->write(vaddr, count*objSize); + + // should never happen because of SOCK_SEQPACKET + LOG_ALWAYS_FATAL_IF((size >= 0) && (size % objSize), + "BitTube::sendObjects(count=%d, size=%d), res=%d (partial events were sent!)", + count, objSize, size); + + //ALOGE_IF(size<0, "error %d sending %d events", size, count); + return size < 0 ? size : size / objSize; } 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 - return size; - } else if (size == 0) { - // no more messages - break; - } - numObjects++; - } - return numObjects; + char* vaddr = reinterpret_cast<char*>(events); + ssize_t size = tube->read(vaddr, count*objSize); + + // should never happen because of SOCK_SEQPACKET + LOG_ALWAYS_FATAL_IF((size >= 0) && (size % objSize), + "BitTube::recvObjects(count=%d, size=%d), res=%d (partial events were received!)", + count, objSize, size); + + //ALOGE_IF(size<0, "error %d receiving %d events", size, count); + return size < 0 ? size : size / objSize; } // ---------------------------------------------------------------------------- diff --git a/libs/gui/SensorEventQueue.cpp b/libs/gui/SensorEventQueue.cpp index 08b8ac8..ab50c1d 100644 --- a/libs/gui/SensorEventQueue.cpp +++ b/libs/gui/SensorEventQueue.cpp @@ -35,12 +35,12 @@ namespace android { // ---------------------------------------------------------------------------- SensorEventQueue::SensorEventQueue(const sp<ISensorEventConnection>& connection) - : mSensorEventConnection(connection) -{ + : mSensorEventConnection(connection), mRecBuffer(NULL), mAvailable(0), mConsumed(0) { + mRecBuffer = new ASensorEvent[MAX_RECEIVE_BUFFER_EVENT_COUNT]; } -SensorEventQueue::~SensorEventQueue() -{ +SensorEventQueue::~SensorEventQueue() { + delete [] mRecBuffer; } void SensorEventQueue::onFirstRef() @@ -59,9 +59,21 @@ ssize_t SensorEventQueue::write(const sp<BitTube>& tube, return BitTube::sendObjects(tube, events, numEvents); } -ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents) -{ - return BitTube::recvObjects(mSensorChannel, events, numEvents); +ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents) { + if (mAvailable == 0) { + ssize_t err = BitTube::recvObjects(mSensorChannel, + mRecBuffer, MAX_RECEIVE_BUFFER_EVENT_COUNT); + if (err < 0) { + return err; + } + mAvailable = err; + mConsumed = 0; + } + size_t count = numEvents < mAvailable ? numEvents : mAvailable; + memcpy(events, mRecBuffer + mConsumed, count*sizeof(ASensorEvent)); + mAvailable -= count; + mConsumed += count; + return count; } sp<Looper> SensorEventQueue::getLooper() const |