OSDN Git Service

DO NOT MERGE ANYWHERE Restart failed system calls interrupted with errno of EINTR
authorPavlin Radoslavov <pavlin@google.com>
Thu, 12 May 2016 18:36:44 +0000 (11:36 -0700)
committerZach Johnson <zachoverflow@google.com>
Tue, 17 May 2016 17:11:57 +0000 (10:11 -0700)
In number of places we don't handle properly system calls failures
when the errno is EINTR (i.e., the system call was interrupted
by a signal). In all our use cases, the system calls should be
restarted. The handling of the following system calls (as used in the code)
has been updated/fixed:

  poll, send, recv, sendmsg, nanosleep, epoll_wait
  read - mostly (e.g., socket-like fds)
  write - mostly (e.g., socket-like fds)
  select, accept, connect

Bug: 28471477
Bug: 28658141
Change-Id: I03e6f0f67e33876780fb6d02c33eb84547ba8f95

19 files changed:
audio_a2dp_hw/audio_a2dp_hw.c
btif/co/bta_hh_co.c
btif/co/bta_hl_co.c
btif/src/btif_hl.c
btif/src/btif_pan.c
btif/src/btif_sock_l2cap.c
btif/src/btif_sock_rfc.c
btif/src/btif_sock_thread.c
btif/src/btif_sock_util.c
hci/src/btsnoop_net.c
hci/src/hci_hal_h4.c
hci/src/hci_hal_mct.c
osi/include/osi.h
osi/include/socket.h
osi/src/eager_reader.c
osi/src/reactor.c
osi/src/socket.c
tools/hci/main.c
udrv/ulinux/uipc.c

index 2980336..c3320ef 100644 (file)
@@ -48,6 +48,7 @@
 
 #define LOG_TAG "bt_a2dp_hw"
 #include "osi/include/log.h"
+#include "osi/include/osi.h"
 
 /*****************************************************************************
 **  Constants & Macros
@@ -236,27 +237,25 @@ static int skt_connect(char *path, size_t buffer_sz)
 
 static int skt_read(int fd, void *p, size_t len)
 {
-    int read;
     struct pollfd pfd;
     struct timespec ts;
+    ssize_t read;
 
     FNLOG();
 
     ts_log("skt_read recv", len, NULL);
 
-    if ((read = recv(fd, p, len, MSG_NOSIGNAL)) == -1)
-    {
-        ERROR("write failed with errno=%d\n", errno);
-        return -1;
-    }
+    OSI_NO_INTR(read = recv(fd, p, len, MSG_NOSIGNAL));
+    if (read == -1)
+        ERROR("read failed with errno=%d\n", errno);
 
-    return read;
+    return (int)read;
 }
 
 static int skt_write(int fd, const void *p, size_t len)
 {
-    int sent;
     struct pollfd pfd;
+    ssize_t sent;
 
     FNLOG();
 
@@ -270,14 +269,11 @@ static int skt_write(int fd, const void *p, size_t len)
         return 0;
 
     ts_log("skt_write", len, NULL);
-
-    if ((sent = send(fd, p, len, MSG_NOSIGNAL)) == -1)
-    {
+    OSI_NO_INTR(sent = send(fd, p, len, MSG_NOSIGNAL));
+    if (sent == -1)
         ERROR("write failed with errno=%d\n", errno);
-        return -1;
-    }
 
-    return sent;
+    return (int)sent;
 }
 
 static int skt_disconnect(int fd)
@@ -302,29 +298,15 @@ static int skt_disconnect(int fd)
 
 static int a2dp_ctrl_receive(struct a2dp_stream_common *common, void* buffer, int length)
 {
-    int ret = recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL);
+    ssize_t ret;
+
+    OSI_NO_INTR(ret = recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL));
     if (ret < 0)
     {
         ERROR("ack failed (%s)", strerror(errno));
-        if (errno == EINTR)
-        {
-            /* retry again */
-            ret = recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL);
-            if (ret < 0)
-            {
-               ERROR("ack failed (%s)", strerror(errno));
-               skt_disconnect(common->ctrl_fd);
-               common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
-               return -1;
-            }
-        }
-        else
-        {
-               skt_disconnect(common->ctrl_fd);
-               common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
-               return -1;
-
-        }
+        skt_disconnect(common->ctrl_fd);
+        common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
+        return -1;
     }
     return ret;
 }
@@ -336,7 +318,9 @@ static int a2dp_command(struct a2dp_stream_common *common, char cmd)
     DEBUG("A2DP COMMAND %s", dump_a2dp_ctrl_event(cmd));
 
     /* send command */
-    if (send(common->ctrl_fd, &cmd, 1, MSG_NOSIGNAL) == -1)
+    ssize_t sent;
+    OSI_NO_INTR(sent = send(common->ctrl_fd, &cmd, 1, MSG_NOSIGNAL));
+    if (sent == -1)
     {
         ERROR("cmd failed (%s)", strerror(errno));
         skt_disconnect(common->ctrl_fd);
index bd6fd6f..92a471a 100644 (file)
@@ -29,6 +29,7 @@
 #include <unistd.h>
 #include <linux/uhid.h>
 #include <unistd.h>
+#include "osi/include/osi.h"
 #include "btif_hh.h"
 #include "bta_api.h"
 #include "bta_hh_api.h"
@@ -58,8 +59,9 @@ void uhid_set_non_blocking(int fd)
 /*Internal function to perform UHID write and error checking*/
 static int uhid_write(int fd, const struct uhid_event *ev)
 {
-    ssize_t ret = write(fd, ev, sizeof(*ev));
+    ssize_t ret;
 
+    OSI_NO_INTR(ret = write(fd, ev, sizeof(*ev)));
     if (ret < 0){
         int rtn = -errno;
         APPL_TRACE_ERROR("%s: Cannot write to uhid:%s",
@@ -197,7 +199,6 @@ static void *btif_hh_poll_event_thread(void *arg)
     btif_hh_device_t *p_dev = arg;
     APPL_TRACE_DEBUG("%s: Thread created fd = %d", __FUNCTION__, p_dev->fd);
     struct pollfd pfds[1];
-    int ret;
 
     pfds[0].fd = p_dev->fd;
     pfds[0].events = POLLIN;
@@ -206,7 +207,8 @@ static void *btif_hh_poll_event_thread(void *arg)
     uhid_set_non_blocking(p_dev->fd);
 
     while(p_dev->hh_keep_polling){
-        ret = poll(pfds, 1, 50);
+        int ret;
+        OSI_NO_INTR(ret = poll(pfds, 1, 50));
         if (ret < 0) {
             APPL_TRACE_ERROR("%s: Cannot poll for fds: %s\n", __FUNCTION__, strerror(errno));
             break;
index 9aa91f7..a07426f 100644 (file)
@@ -34,6 +34,8 @@
 #include <fcntl.h>
 #include <ctype.h>
 #include <cutils/sockets.h>
+
+#include "osi/include/osi.h"
 #include "bta_api.h"
 #include "btm_api.h"
 #include "bta_sys.h"
@@ -369,7 +371,6 @@ void bta_hl_co_put_rx_data (UINT8 app_id, tBTA_HL_MDL_HANDLE mdl_handle,
     UINT8 app_idx, mcl_idx, mdl_idx;
     btif_hl_mdl_cb_t *p_dcb;
     tBTA_HL_STATUS status = BTA_HL_STATUS_FAIL;
-    int            r;
     BTIF_TRACE_DEBUG("%s app_id=%d mdl_handle=0x%x data_size=%d",
                       __FUNCTION__,app_id, mdl_handle, data_size);
 
@@ -384,7 +385,9 @@ void bta_hl_co_put_rx_data (UINT8 app_id, tBTA_HL_MDL_HANDLE mdl_handle,
             {
                 BTIF_TRACE_DEBUG("app_idx=%d mcl_idx=0x%x mdl_idx=0x%x data_size=%d",
                                   app_idx, mcl_idx, mdl_idx, data_size);
-                r = send(p_dcb->p_scb->socket_id[1], p_dcb->p_rx_pkt, data_size, 0);
+                ssize_t r;
+                OSI_NO_INTR(r = send(p_dcb->p_scb->socket_id[1], p_dcb->p_rx_pkt,
+                                     data_size, 0));
 
                 if (r == data_size)
                 {
index 9d0c0d7..2468809 100644 (file)
@@ -4795,8 +4795,9 @@ void btif_hl_select_monitor_callback(fd_set *p_cur_set ,fd_set *p_org_set) {
                 }
                 p_dcb->p_tx_pkt = btif_hl_get_buf (p_dcb->mtu);
                 if (p_dcb) {
-                    int r = (int)recv(p_scb->socket_id[1], p_dcb->p_tx_pkt,
-                            p_dcb->mtu, MSG_DONTWAIT);
+                    ssize_t r;
+                    OSI_NO_INTR(r = recv(p_scb->socket_id[1], p_dcb->p_tx_pkt,
+                                         p_dcb->mtu, MSG_DONTWAIT));
                     if (r > 0) {
                         BTIF_TRACE_DEBUG("btif_hl_select_monitor_callback send data r =%d", r);
                         p_dcb->tx_size = r;
@@ -4851,8 +4852,13 @@ static inline int btif_hl_select_wakeup_init(fd_set* set){
 *******************************************************************************/
 static inline int btif_hl_select_wakeup(void){
     char sig_on = btif_hl_signal_select_wakeup;
-    BTIF_TRACE_DEBUG("btif_hl_select_wakeup");
-    return send(signal_fds[1], &sig_on, sizeof(sig_on), 0);
+
+    BTIF_TRACE_DEBUG("%s", __func__);
+
+    ssize_t ret;
+    OSI_NO_INTR(ret = send(signal_fds[1], &sig_on, sizeof(sig_on), 0));
+
+    return (int)ret;
 }
 
 /*******************************************************************************
@@ -4866,8 +4872,13 @@ static inline int btif_hl_select_wakeup(void){
 *******************************************************************************/
 static inline int btif_hl_select_close_connected(void){
     char sig_on = btif_hl_signal_select_close_connected;
-    BTIF_TRACE_DEBUG("btif_hl_select_close_connected");
-    return send(signal_fds[1], &sig_on, sizeof(sig_on), 0);
+
+    BTIF_TRACE_DEBUG("%s", __func__);
+
+    ssize_t ret;
+    OSI_NO_INTR(ret = send(signal_fds[1], &sig_on, sizeof(sig_on), 0));
+
+    return (int)ret;
 }
 
 /*******************************************************************************
@@ -4881,10 +4892,13 @@ static inline int btif_hl_select_close_connected(void){
 *******************************************************************************/
 static inline int btif_hl_close_select_thread(void)
 {
-    int result = 0;
+    ssize_t result = 0;
     char sig_on = btif_hl_signal_select_exit;
-    BTIF_TRACE_DEBUG("btif_hl_signal_select_exit");
-    result = send(signal_fds[1], &sig_on, sizeof(sig_on), 0);
+
+    BTIF_TRACE_DEBUG("%", __func__);
+
+    OSI_NO_INTR(result = send(signal_fds[1], &sig_on, sizeof(sig_on), 0));
+
     if (btif_is_enabled())
     {
         /* Wait for the select_thread_id to exit if BT is still enabled
@@ -4895,7 +4909,8 @@ static inline int btif_hl_close_select_thread(void)
         }
     }
     list_free(soc_queue);
-    return result;
+
+    return (int)result;
 }
 
 /*******************************************************************************
@@ -4910,9 +4925,13 @@ static inline int btif_hl_close_select_thread(void)
 static inline int btif_hl_select_wake_reset(void){
     char sig_recv = 0;
 
-    BTIF_TRACE_DEBUG("btif_hl_select_wake_reset");
-    recv(signal_fds[0], &sig_recv, sizeof(sig_recv), MSG_WAITALL);
-    return(int)sig_recv;
+    BTIF_TRACE_DEBUG("%s", __func__);
+
+    ssize_t r;
+    OSI_NO_INTR(r = recv(signal_fds[0], &sig_recv, sizeof(sig_recv),
+                         MSG_WAITALL));
+
+    return (int)sig_recv;
 }
 /*******************************************************************************
 **
@@ -4976,6 +4995,8 @@ static void *btif_hl_select_thread(void *arg){
         BTIF_TRACE_DEBUG("select unblocked ret=%d", ret);
         if (ret == -1)
         {
+            if (errno == EINTR)
+                continue;
             BTIF_TRACE_DEBUG("select() ret -1, exit the thread");
             btif_hl_thread_cleanup();
             select_thread_id = -1;
index cbb8d97..04bdf4d 100644 (file)
@@ -451,9 +451,10 @@ int btpan_tap_send(int tap_fd, const BD_ADDR src, const BD_ADDR dst, UINT16 prot
         memcpy(packet + sizeof(tETH_HDR), buf, len);
 
         /* Send data to network interface */
-        int ret = write(tap_fd, packet, len + sizeof(tETH_HDR));
+        ssize_t ret;
+        OSI_NO_INTR(ret = write(tap_fd, packet, len + sizeof(tETH_HDR)));
         BTIF_TRACE_DEBUG("ret:%d", ret);
-        return ret;
+        return (int)ret;
     }
     return -1;
 
@@ -740,7 +741,9 @@ static void btu_exec_tap_fd_read(void *p_param) {
         // We save it in the congest_packet right away in case we can't deliver it in this
         // attempt.
         if (!btpan_cb.congest_packet_size) {
-            ssize_t ret = read(fd, btpan_cb.congest_packet, sizeof(btpan_cb.congest_packet));
+            ssize_t ret;
+            OSI_NO_INTR(ret = read(fd, btpan_cb.congest_packet,
+                                   sizeof(btpan_cb.congest_packet)));
             switch (ret) {
                 case -1:
                     BTIF_TRACE_ERROR("%s unable to read from driver: %s", __func__, strerror(errno));
index 04c5b67..7f15bb9 100644 (file)
@@ -968,7 +968,9 @@ static BOOLEAN flush_incoming_que_on_wr_signal_l(l2cap_socket *sock)
     uint32_t len;
 
     while (packet_get_head_l(sock, &buf, &len)) {
-        int sent = send(sock->our_fd, buf, len, MSG_DONTWAIT);
+        ssize_t sent;
+        OSI_NO_INTR(sent = send(sock->our_fd, buf, len, MSG_DONTWAIT));
+        int saved_errno = errno;
 
         if (sent == (signed)len)
             osi_free(buf);
@@ -981,7 +983,7 @@ static BOOLEAN flush_incoming_que_on_wr_signal_l(l2cap_socket *sock)
         else {
             packet_put_head_l(sock, buf, len);
             osi_free(buf);
-            return errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN;
+            return saved_errno == EWOULDBLOCK || saved_errno == EAGAIN;
         }
     }
 
@@ -1028,8 +1030,9 @@ void btsock_l2cap_signaled(int fd, int flags, uint32_t user_id)
                          * UPDATE: Since we are responsible for freeing the buffer in the
                          * write_complete_ind, it is OK to use malloc. */
 
-                        int count = recv(fd, buffer, L2CAP_MAX_SDU_LENGTH,
-                                MSG_NOSIGNAL | MSG_DONTWAIT);
+                        ssize_t count;
+                        OSI_NO_INTR(count = recv(fd, buffer, L2CAP_MAX_SDU_LENGTH,
+                                                 MSG_NOSIGNAL | MSG_DONTWAIT));
                         APPL_TRACE_DEBUG("btsock_l2cap_signaled - %d bytes received from socket",
                                 count);
                         if (sock->fixed_chan) {
index ca83f83..c31c690 100644 (file)
@@ -720,10 +720,12 @@ static sent_status_t send_data_to_app(int fd, BT_HDR *p_buf) {
   if (p_buf->len == 0)
     return SENT_ALL;
 
-  ssize_t sent = send(fd, p_buf->data + p_buf->offset, p_buf->len, MSG_DONTWAIT);
+  ssize_t sent;
+  OSI_NO_INTR(sent = send(fd, p_buf->data + p_buf->offset, p_buf->len,
+                          MSG_DONTWAIT));
 
   if (sent == -1) {
-    if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
+    if (errno == EAGAIN || errno == EWOULDBLOCK)
       return SENT_NONE;
     LOG_ERROR("%s error writing RFCOMM data back to app: %s", __func__, strerror(errno));
     return SENT_FAILED;
@@ -878,7 +880,9 @@ int bta_co_rfc_data_outgoing(void *user_data, uint8_t *buf, uint16_t size) {
   if (!slot)
     goto out;
 
-  int received = recv(slot->fd, buf, size, 0);
+  ssize_t received;
+  OSI_NO_INTR(received = recv(slot->fd, buf, size, 0));
+
   if(received == size) {
     ret = true;
   } else {
index 459aeba..0905092 100644 (file)
@@ -161,7 +161,8 @@ static inline int accept_server_socket(int s)
 {
     struct sockaddr_un client_address;
     socklen_t clen;
-    int fd = accept(s, (struct sockaddr*)&client_address, &clen);
+    int fd;
+    OSI_NO_INTR(fd = accept(s, (struct sockaddr*)&client_address, &clen));
     APPL_TRACE_DEBUG("accepted fd:%d for server fd:%d", fd, s);
     return fd;
 }
@@ -325,7 +326,11 @@ int btsock_thread_add_fd(int h, int fd, int type, int flags, uint32_t user_id)
     }
     sock_cmd_t cmd = {CMD_ADD_FD, fd, type, flags, user_id};
     APPL_TRACE_DEBUG("adding fd:%d, flags:0x%x", fd, flags);
-    return send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd);
+
+    ssize_t ret;
+    OSI_NO_INTR(ret = send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0));
+
+    return ret == sizeof(cmd);
 }
 
 bool btsock_thread_remove_fd_and_close(int thread_handle, int fd)
@@ -342,7 +347,11 @@ bool btsock_thread_remove_fd_and_close(int thread_handle, int fd)
     }
 
     sock_cmd_t cmd = {CMD_REMOVE_FD, fd, 0, 0, 0};
-    return send(ts[thread_handle].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd);
+
+    ssize_t ret;
+    OSI_NO_INTR(ret = send(ts[thread_handle].cmd_fdw, &cmd, sizeof(cmd), 0));
+
+    return ret == sizeof(cmd);
 }
 
 int btsock_thread_post_cmd(int h, int type, const unsigned char* data, int size, uint32_t user_id)
@@ -376,7 +385,11 @@ int btsock_thread_post_cmd(int h, int type, const unsigned char* data, int size,
             return FALSE;
         }
     }
-    return send(ts[h].cmd_fdw, cmd_send, size_send, 0) == size_send;
+
+    ssize_t ret;
+    OSI_NO_INTR(ret = send(ts[h].cmd_fdw, cmd_send, size_send, 0));
+
+    return ret == size_send;
 }
 int btsock_thread_wakeup(int h)
 {
@@ -391,7 +404,11 @@ int btsock_thread_wakeup(int h)
         return FALSE;
     }
     sock_cmd_t cmd = {CMD_WAKEUP, 0, 0, 0, 0};
-    return send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd);
+
+    ssize_t ret;
+    OSI_NO_INTR(ret = send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0));
+
+    return ret == sizeof(cmd);
 }
 int btsock_thread_exit(int h)
 {
@@ -406,8 +423,11 @@ int btsock_thread_exit(int h)
         return FALSE;
     }
     sock_cmd_t cmd = {CMD_EXIT, 0, 0, 0, 0};
-    if(send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd))
-    {
+
+    ssize_t ret;
+    OSI_NO_INTR(ret = send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0));
+
+    if (ret == sizeof(cmd)) {
         pthread_join(ts[h].thread_id, 0);
         pthread_mutex_lock(&thread_slot_lock);
         free_thread_slot(h);
@@ -501,7 +521,11 @@ static int process_cmd_sock(int h)
 {
     sock_cmd_t cmd = {-1, 0, 0, 0, 0};
     int fd = ts[h].cmd_fdr;
-    if(recv(fd, &cmd, sizeof(cmd), MSG_WAITALL) != sizeof(cmd))
+
+    ssize_t ret;
+    OSI_NO_INTR(ret = recv(fd, &cmd, sizeof(cmd), MSG_WAITALL));
+
+    if (ret != sizeof(cmd))
     {
         APPL_TRACE_ERROR("recv cmd errno:%d", errno);
         return FALSE;
@@ -608,7 +632,8 @@ static void *sock_poll_thread(void *arg)
     for(;;)
     {
         prepare_poll_fds(h, pfds);
-        int ret = poll(pfds, ts[h].poll_count, -1);
+        int ret;
+        OSI_NO_INTR(ret = poll(pfds, ts[h].poll_count, -1));
         if(ret == -1)
         {
             APPL_TRACE_ERROR("poll ret -1, exit the thread, errno:%d, err:%s", errno, strerror(errno));
index baa3ed3..6063c85 100644 (file)
 int sock_send_all(int sock_fd, const uint8_t* buf, int len)
 {
     int s = len;
-    int ret;
+
     while(s)
     {
-        do ret = send(sock_fd, buf, s, 0);
-        while(ret < 0 && errno == EINTR);
+        ssize_t ret;
+        OSI_NO_INTR(ret = send(sock_fd, buf, s, 0));
         if(ret <= 0)
         {
             BTIF_TRACE_ERROR("sock fd:%d send errno:%d, ret:%d", sock_fd, errno, ret);
@@ -89,11 +89,11 @@ int sock_send_all(int sock_fd, const uint8_t* buf, int len)
 int sock_recv_all(int sock_fd, uint8_t* buf, int len)
 {
     int r = len;
-    int ret = -1;
+
     while(r)
     {
-        do ret = recv(sock_fd, buf, r, MSG_WAITALL);
-        while(ret < 0 && errno == EINTR);
+        ssize_t ret;
+        OSI_NO_INTR(ret = recv(sock_fd, buf, r, MSG_WAITALL));
         if(ret <= 0)
         {
             BTIF_TRACE_ERROR("sock fd:%d recv errno:%d, ret:%d", sock_fd, errno, ret);
@@ -107,7 +107,6 @@ int sock_recv_all(int sock_fd, uint8_t* buf, int len)
 
 int sock_send_fd(int sock_fd, const uint8_t* buf, int len, int send_fd)
 {
-    ssize_t ret;
     struct msghdr msg;
     unsigned char *buffer = (unsigned char *)buf;
     memset(&msg, 0, sizeof(msg));
@@ -139,10 +138,8 @@ int sock_send_fd(int sock_fd, const uint8_t* buf, int len, int send_fd)
         msg.msg_iov = &iv;
         msg.msg_iovlen = 1;
 
-        do {
-            ret = sendmsg(sock_fd, &msg, MSG_NOSIGNAL);
-        } while (ret < 0 && errno == EINTR);
-
+        ssize_t ret;
+        OSI_NO_INTR(ret = sendmsg(sock_fd, &msg, MSG_NOSIGNAL));
         if (ret < 0) {
             BTIF_TRACE_ERROR("fd:%d, send_fd:%d, sendmsg ret:%d, errno:%d, %s",
                               sock_fd, send_fd, (int)ret, errno, strerror(errno));
index c6a9cd6..77af3a7 100644 (file)
@@ -77,7 +77,10 @@ void btsnoop_net_write(const void *data, size_t length) {
 
   pthread_mutex_lock(&client_socket_lock_);
   if (client_socket_ != -1) {
-    if (send(client_socket_, data, length, 0) == -1 && errno == ECONNRESET) {
+    ssize_t ret;
+    OSI_NO_INTR(ret = send(client_socket_, data, length, 0));
+
+    if (ret == -1 && errno == ECONNRESET) {
       safe_close_(&client_socket_);
     }
   }
@@ -115,7 +118,8 @@ static void *listen_fn_(UNUSED_ATTR void *context) {
   }
 
   for (;;) {
-    int client_socket = accept(listen_socket_, NULL, NULL);
+    int client_socket;
+    OSI_NO_INTR(client_socket = accept(listen_socket_, NULL, NULL));
     if (client_socket == -1) {
       if (errno == EINVAL || errno == EBADF) {
         break;
@@ -129,7 +133,8 @@ static void *listen_fn_(UNUSED_ATTR void *context) {
     pthread_mutex_lock(&client_socket_lock_);
     safe_close_(&client_socket_);
     client_socket_ = client_socket;
-    send(client_socket_, "btsnoop\0\0\0\0\1\0\0\x3\xea", 16, 0);
+
+    OSI_NO_INTR(send(client_socket_, "btsnoop\0\0\0\0\1\0\0\x3\xea", 16, 0));
     pthread_mutex_unlock(&client_socket_lock_);
   }
 
index 7a48c69..f268f12 100644 (file)
@@ -153,7 +153,8 @@ static uint16_t transmit_data(serial_data_type_t type, uint8_t *data, uint16_t l
 
   uint16_t transmitted_length = 0;
   while (length > 0) {
-    ssize_t ret = write(uart_fd, data + transmitted_length, length);
+    ssize_t ret;
+    OSI_NO_INTR(ret = write(uart_fd, data + transmitted_length, length));
     switch (ret) {
       case -1:
         LOG_ERROR("In %s, error writing to the uart serial port: %s", __func__, strerror(errno));
index 9b3707c..4f712a1 100644 (file)
@@ -159,7 +159,8 @@ static uint16_t transmit_data_on(int fd, uint8_t *data, uint16_t length) {
 
   uint16_t transmitted_length = 0;
   while (length > 0) {
-    ssize_t ret = write(fd, data + transmitted_length, length);
+    ssize_t ret;
+    OSI_NO_INTR(ret = write(fd, data + transmitted_length, length));
     switch (ret) {
       case -1:
         LOG_ERROR("In %s, error writing to the serial port with fd %d: %s", __func__, fd, strerror(errno));
index c035bf8..61a9122 100644 (file)
@@ -1,5 +1,6 @@
 #pragma once
 
+#include <errno.h>
 #include <stdbool.h>
 #include <stdint.h>
 
@@ -20,3 +21,6 @@
 #define COMPILE_ASSERT(x) char * DUMMY_PTR = !(x)
 
 typedef uint32_t timeout_t;
+
+// Re-run |fn| system call until the system call doesn't cause EINTR.
+#define OSI_NO_INTR(fn)  do {} while ((fn) == -1 && errno == EINTR)
index 2833290..c5b2b25 100644 (file)
@@ -58,20 +58,24 @@ socket_t *socket_accept(const socket_t *socket);
 // block. This function returns a positive integer representing the number
 // of bytes copied into |buf| on success, 0 if the socket has disconnected,
 // and -1 on error. This function may return a value less than |count| if not
-// enough data is currently available. If this function returns -1, errno will also
-// be set (see recv(2) for possible errno values). If there were no bytes available
-// to be read, this function returns -1 and sets errno to EWOULDBLOCK. Neither
-// |socket| nor |buf| may be NULL.
+// enough data is currently available. If this function returns -1, errno will
+// also be set (see recv(2) for possible errno values). However, if the reading
+// system call was interrupted with errno of EINTR, the read operation is
+// restarted internally without propagating EINTR back to the caller. If there
+// were no bytes available to be read, this function returns -1 and sets errno
+// to EWOULDBLOCK. Neither |socket| nor |buf| may be NULL.
 ssize_t socket_read(const socket_t *socket, void *buf, size_t count);
 
 // Writes up to |count| bytes from |buf| into |socket|. This function will not
 // block. Returns a positive integer representing the number of bytes written
-// to |socket| on success, 0 if the socket has disconnected, and -1 on error. This
-// function may return a value less than |count| if writing more bytes would result
-// in blocking. If this function returns -1, errno will also be set (see send(2) for
-// possible errno values). If no bytes could be written without blocking, this
-// function will return -1 and set errno to EWOULDBLOCK. Neither |socket| nor |buf|
-// may be NULL.
+// to |socket| on success, 0 if the socket has disconnected, and -1 on error.
+// This function may return a value less than |count| if writing more bytes
+// would result in blocking. If this function returns -1, errno will also be
+// set (see send(2) for possible errno values). However, if the writing system
+// call was interrupted with errno of EINTR, the write operation is restarted
+// internally without propagating EINTR back to the caller. If no bytes could
+// be written without blocking, this function will return -1 and set errno to
+// EWOULDBLOCK. Neither |socket| nor |buf| may be NULL.
 ssize_t socket_write(const socket_t *socket, const void *buf, size_t count);
 
 // This function performs the same write operation as |socket_write| and also
index 3ca8ad1..bba9980 100644 (file)
@@ -220,15 +220,23 @@ static bool has_byte(const eager_reader_t *reader) {
   assert(reader != NULL);
 
   fd_set read_fds;
-  FD_ZERO(&read_fds);
-  FD_SET(reader->bytes_available_fd, &read_fds);
 
-  // Immediate timeout
-  struct timeval timeout;
-  timeout.tv_sec = 0;
-  timeout.tv_usec = 0;
+  for (;;) {
+    FD_ZERO(&read_fds);
+    FD_SET(reader->bytes_available_fd, &read_fds);
+
+    // Immediate timeout
+    struct timeval timeout;
+    timeout.tv_sec = 0;
+    timeout.tv_usec = 0;
+
+    int ret = select(reader->bytes_available_fd + 1, &read_fds, NULL, NULL,
+                     &timeout);
+    if (ret == -1 && errno == EINTR)
+      continue;
+    break;
+  }
 
-  select(reader->bytes_available_fd + 1, &read_fds, NULL, NULL, &timeout);
   return FD_ISSET(reader->bytes_available_fd, &read_fds);
 }
 
@@ -244,7 +252,9 @@ static void inbound_data_waiting(void *context) {
   buffer->length = 0;
   buffer->offset = 0;
 
-  int bytes_read = read(reader->inbound_fd, buffer->data, reader->buffer_size);
+  ssize_t bytes_read;
+  OSI_NO_INTR(bytes_read = read(reader->inbound_fd, buffer->data,
+                                reader->buffer_size));
   if (bytes_read > 0) {
     // Save the data for later
     buffer->length = bytes_read;
index 08b5098..4a1b828 100644 (file)
@@ -240,10 +240,7 @@ static reactor_status_t run_reactor(reactor_t *reactor, int iterations) {
     pthread_mutex_unlock(&reactor->list_lock);
 
     int ret;
-    do {
-      ret = epoll_wait(reactor->epoll_fd, events, MAX_EVENTS, -1);
-    } while (ret == -1 && errno == EINTR);
-
+    OSI_NO_INTR(ret = epoll_wait(reactor->epoll_fd, events, MAX_EVENTS, -1));
     if (ret == -1) {
       LOG_ERROR("%s error in epoll_wait: %s", __func__, strerror(errno));
       reactor->is_running = false;
index 91f084e..d9d268c 100644 (file)
@@ -121,7 +121,8 @@ bool socket_listen(const socket_t *socket, port_t port) {
 socket_t *socket_accept(const socket_t *socket) {
   assert(socket != NULL);
 
-  int fd = accept(socket->fd, NULL, NULL);
+  int fd;
+  OSI_NO_INTR(fd = accept(socket->fd, NULL, NULL));
   if (fd == INVALID_FD) {
     LOG_ERROR("%s unable to accept socket: %s", __func__, strerror(errno));
     return NULL;
@@ -142,14 +143,20 @@ ssize_t socket_read(const socket_t *socket, void *buf, size_t count) {
   assert(socket != NULL);
   assert(buf != NULL);
 
-  return recv(socket->fd, buf, count, MSG_DONTWAIT);
+  ssize_t ret;
+  OSI_NO_INTR(ret = recv(socket->fd, buf, count, MSG_DONTWAIT));
+
+  return ret;
 }
 
 ssize_t socket_write(const socket_t *socket, const void *buf, size_t count) {
   assert(socket != NULL);
   assert(buf != NULL);
 
-  return send(socket->fd, buf, count, MSG_DONTWAIT);
+  ssize_t ret;
+  OSI_NO_INTR(ret = send(socket->fd, buf, count, MSG_DONTWAIT));
+
+  return ret;
 }
 
 ssize_t socket_write_and_transfer_fd(const socket_t *socket, const void *buf, size_t count, int fd) {
@@ -179,7 +186,9 @@ ssize_t socket_write_and_transfer_fd(const socket_t *socket, const void *buf, si
   header->cmsg_len = CMSG_LEN(sizeof(int));
   *(int *)CMSG_DATA(header) = fd;
 
-  ssize_t ret = sendmsg(socket->fd, &msg, MSG_DONTWAIT);
+  ssize_t ret;
+  OSI_NO_INTR(ret = sendmsg(socket->fd, &msg, MSG_DONTWAIT));
+
   close(fd);
   return ret;
 }
index ae06400..d01622f 100644 (file)
@@ -176,7 +176,10 @@ static bool write_hci_command(hci_packet_t type, const void *packet, size_t leng
   addr.sin_family = AF_INET;
   addr.sin_addr.s_addr = htonl(0x7F000001);
   addr.sin_port = htons(8873);
-  if (connect(sock, (const struct sockaddr *)&addr, sizeof(addr)) == -1)
+  int ret;
+  OSI_NO_INTR(ret = connect(sock, (const struct sockaddr *)&addr,
+                            sizeof(addr)));
+  if (ret == -1)
     goto error;
 
   if (send(sock, &type, 1, 0) != 1)
index f3c746e..1f669bd 100644 (file)
@@ -46,6 +46,7 @@
 
 #include "gki.h"
 #include "bt_types.h"
+#include "osi/include/osi.h"
 #include "uipc.h"
 
 #include <cutils/sockets.h>
@@ -184,7 +185,9 @@ static int accept_server_socket(int sfd)
     pfd.fd = sfd;
     pfd.events = POLLIN;
 
-    if (poll(&pfd, 1, 0) == 0)
+    int poll_ret;
+    OSI_NO_INTR(poll_ret = poll(&pfd, 1, 0));
+    if (poll_ret == 0)
     {
         BTIF_TRACE_EVENT("accept poll timeout");
         return -1;
@@ -192,8 +195,8 @@ static int accept_server_socket(int sfd)
 
     //BTIF_TRACE_EVENT("poll revents 0x%x", pfd.revents);
 
-    if ((fd = accept(sfd, (struct sockaddr *)&remote, &len)) == -1)
-    {
+    OSI_NO_INTR(fd = accept(sfd, (struct sockaddr *)&remote, &len));
+    if (fd == -1) {
          BTIF_TRACE_ERROR("sock accept failed (%s)", strerror(errno));
          return -1;
     }
@@ -329,8 +332,8 @@ static void uipc_check_interrupt_locked(void)
     if (SAFE_FD_ISSET(uipc_main.signal_fds[0], &uipc_main.read_set))
     {
         char sig_recv = 0;
-        //BTIF_TRACE_EVENT("UIPC INTERRUPT");
-        recv(uipc_main.signal_fds[0], &sig_recv, sizeof(sig_recv), MSG_WAITALL);
+        OSI_NO_INTR(recv(uipc_main.signal_fds[0], &sig_recv, sizeof(sig_recv),
+                         MSG_WAITALL));
     }
 }
 
@@ -338,7 +341,8 @@ static inline void uipc_wakeup_locked(void)
 {
     char sig_on = 1;
     BTIF_TRACE_EVENT("UIPC SEND WAKE UP");
-    send(uipc_main.signal_fds[1], &sig_on, sizeof(sig_on), 0);
+
+    OSI_NO_INTR(send(uipc_main.signal_fds[1], &sig_on, sizeof(sig_on), 0));
 }
 
 static int uipc_setup_server_locked(tUIPC_CH_ID ch_id, char *name, tUIPC_RCV_CBACK *cback)
@@ -381,7 +385,6 @@ static void uipc_flush_ch_locked(tUIPC_CH_ID ch_id)
 {
     char buf[UIPC_FLUSH_BUFFER_SIZE];
     struct pollfd pfd;
-    int ret;
 
     pfd.events = POLLIN;
     pfd.fd = uipc_main.ch[ch_id].fd;
@@ -394,10 +397,10 @@ static void uipc_flush_ch_locked(tUIPC_CH_ID ch_id)
 
     while (1)
     {
-        ret = poll(&pfd, 1, 1);
+        int ret;
+        OSI_NO_INTR(ret = poll(&pfd, 1, 1));
         BTIF_TRACE_VERBOSE("%s() - polling fd %d, revents: 0x%x, ret %d",
                 __FUNCTION__, pfd.fd, pfd.revents, ret);
-
         if (pfd.revents & (POLLERR|POLLHUP))
         {
             BTIF_TRACE_EVENT("%s() - POLLERR or POLLHUP. Exiting", __FUNCTION__);
@@ -504,14 +507,13 @@ static void uipc_read_task(void *arg)
 
         result = select(uipc_main.max_fd+1, &uipc_main.read_set, NULL, NULL, NULL);
 
-        if (result == 0)
-        {
+        if (result == 0) {
             BTIF_TRACE_EVENT("select timeout");
             continue;
         }
-        else if (result < 0)
-        {
-            BTIF_TRACE_EVENT("select failed %s", strerror(errno));
+        if (result < 0) {
+            if (errno != EINTR)
+                BTIF_TRACE_EVENT("select failed %s", strerror(errno));
             continue;
         }
 
@@ -715,8 +717,9 @@ BOOLEAN UIPC_Send(tUIPC_CH_ID ch_id, UINT16 msg_evt, UINT8 *p_buf,
 
     UIPC_LOCK();
 
-    if (write(uipc_main.ch[ch_id].fd, p_buf, msglen) < 0)
-    {
+    ssize_t ret;
+    OSI_NO_INTR(ret = write(uipc_main.ch[ch_id].fd, p_buf, msglen));
+    if (ret < 0) {
         BTIF_TRACE_ERROR("failed to write (%s)", strerror(errno));
     }
 
@@ -756,7 +759,6 @@ void UIPC_ReadBuf(tUIPC_CH_ID ch_id, BT_HDR *p_msg)
 
 UINT32 UIPC_Read(tUIPC_CH_ID ch_id, UINT16 *p_msg_evt, UINT8 *p_buf, UINT32 len)
 {
-    int n;
     int n_read = 0;
     int fd = uipc_main.ch[ch_id].fd;
     struct pollfd pfd;
@@ -784,7 +786,11 @@ UINT32 UIPC_Read(tUIPC_CH_ID ch_id, UINT16 *p_msg_evt, UINT8 *p_buf, UINT32 len)
 
         /* make sure there is data prior to attempting read to avoid blocking
            a read for more than poll timeout */
-        if (poll(&pfd, 1, uipc_main.ch[ch_id].read_poll_tmo_ms) == 0)
+
+        int poll_ret;
+        OSI_NO_INTR(poll_ret = poll(&pfd, 1,
+                                    uipc_main.ch[ch_id].read_poll_tmo_ms));
+        if (poll_ret == 0)
         {
             BTIF_TRACE_EVENT("poll timeout (%d ms)", uipc_main.ch[ch_id].read_poll_tmo_ms);
             break;
@@ -801,7 +807,8 @@ UINT32 UIPC_Read(tUIPC_CH_ID ch_id, UINT16 *p_msg_evt, UINT8 *p_buf, UINT32 len)
             return 0;
         }
 
-        n = recv(fd, p_buf+n_read, len-n_read, 0);
+        ssize_t n;
+        OSI_NO_INTR(n = recv(fd, p_buf+n_read, len-n_read, 0));
 
         //BTIF_TRACE_EVENT("read %d bytes", n);