Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b0b583a1 authored by Pavlin Radoslavov's avatar Pavlin Radoslavov Committed by Zach Johnson
Browse files

DO NOT MERGE ANYWHERE Restart failed system calls interrupted with errno of EINTR

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
parent 743e1827
Loading
Loading
Loading
Loading
+19 −35
Original line number Diff line number Diff line
@@ -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,14 +298,9 @@ 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);
    if (ret < 0)
    {
        ERROR("ack failed (%s)", strerror(errno));
        if (errno == EINTR)
        {
            /* retry again */
            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));
@@ -317,15 +308,6 @@ static int a2dp_ctrl_receive(struct a2dp_stream_common *common, void* buffer, in
        common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
        return -1;
    }
        }
        else
        {
               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);
+5 −3
Original line number Diff line number Diff line
@@ -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;
+5 −2
Original line number Diff line number Diff line
@@ -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)
                {
+34 −13
Original line number Diff line number Diff line
@@ -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,8 +4925,12 @@ 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);
    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;
+6 −3
Original line number Diff line number Diff line
@@ -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));
Loading