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/ui-commands-impl.c b/android/protocol/ui-commands-impl.c
index 2ceeca1..307e7c7 100644
--- a/android/protocol/ui-commands-impl.c
+++ b/android/protocol/ui-commands-impl.c
@@ -22,6 +22,7 @@
#include "android/sync-utils.h"
#include "android/utils/system.h"
#include "android/utils/debug.h"
+#include "android/utils/eintr_wrapper.h"
#include "android/utils/panic.h"
#include "android/protocol/core-connection.h"
#include "android/protocol/ui-commands-impl.h"
@@ -124,23 +125,23 @@
// Read requests while they are immediately available.
for (;;) {
// Read next chunk of data.
- status = socket_recv(uicmd->sock,
- uicmd->reader_buffer + uicmd->reader_offset,
- uicmd->reader_bytes - uicmd->reader_offset);
- if (status == 0) {
- /* Disconnection, meaning that the core process got terminated. */
- fprintf(stderr, "core-ui-control service got disconnected\n");
- uiCmdImpl_destroy();
+ status = HANDLE_EINTR(
+ socket_recv(uicmd->sock,
+ uicmd->reader_buffer + uicmd->reader_offset,
+ uicmd->reader_bytes - uicmd->reader_offset));
+ if (status < 0 && (errno == EWOULDBLOCK || errno == EGAIN) {
+ // Chunk is not avalable at this point. Come back later.
return;
}
- if (status < 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 (status <= 0) {
+ /* Disconnection, meaning that the core process got terminated. */
+ fprintf(stderr,
+ "core-ui-control service got disconnected: %s\n",
+ status < 0 ?
+ strerror(errno) :
+ "unexpected disconnection");
+ uiCmdImpl_destroy();
+ return;
}
uicmd->reader_offset += status;