Add android/utils/eintr_wrapper.h
Add a new Android-specific header that defines two macros to
handle EINTR in a consistent way, as well as allow detecting
when a system call loops too many times and exit with a fatal
error message when that happens.
+ Unit tests.
+ Update existing code under android/ which uses to deal directly
with EINTR to use the new HANDLE_EINTR() and IGNORE_EINTR()
+ Remove EINTR checks for functions that call socket_xxx() functions
which already loop around EINTR.
Change-Id: I1d2ee64d9743a2edc506f616465ea091878db620
diff --git a/android/protocol/fb-updates-impl.c b/android/protocol/fb-updates-impl.c
index dde79c1..e36c4bf 100644
--- a/android/protocol/fb-updates-impl.c
+++ b/android/protocol/fb-updates-impl.c
@@ -17,6 +17,7 @@
#include "android/utils/system.h"
#include "android/utils/debug.h"
+#include "android/utils/eintr_wrapper.h"
#include "android/utils/panic.h"
#include "android/sync-utils.h"
#include "android/protocol/core-connection.h"
@@ -113,21 +114,20 @@
// Read updates while they are immediately available.
for (;;) {
// Read next chunk of data.
- ret = socket_recv(fbi->sock, fbi->reader_buffer + fbi->reader_offset,
- fbi->reader_bytes - fbi->reader_offset);
- if (ret == 0) {
- /* disconnection ! */
- fbUpdatesImpl_destroy();
+ ret = HANDLE_EINTR(
+ socket_recv(fbi->sock,
+ fbi->reader_buffer + fbi->reader_offset,
+ fbi->reader_bytes - fbi->reader_offset));
+ if (ret < 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) {
+ // Chunk is not avalable at this point. Come back later.
return;
}
- if (ret < 0) {
- if (errno == EINTR) {
- /* loop on EINTR */
- continue;
- } else if (errno == EWOULDBLOCK || errno == EAGAIN) {
- // Chunk is not avalable at this point. Come back later.
- return;
- }
+ if (ret <= 0) {
+ /* disconnection ! */
+ derror("Unable to receive framebuffer data: %s\n",
+ ret < 0 ? strerror(errno), "unexpected disconnection");
+ fbUpdatesImpl_destroy();
+ return;
}
fbi->reader_offset += ret;