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

Commit 4fa095e6 authored by Ian Coolidge's avatar Ian Coolidge
Browse files

Fix non-standard pthread mutex interactions.

pthread_mutex_t is intended to be opaque.
pthread_attr_t is intended to be opaque.

Change-Id: I9b4f32b695783a4391851269977aa748dcc4f241
parent 4d7e4a98
Loading
Loading
Loading
Loading
+0 −27
Original line number Diff line number Diff line
@@ -27,35 +27,8 @@
#ifndef BTIF_SOCK_UTIL_H
#define BTIF_SOCK_UTIL_H

#include <pthread.h>
#include <cutils/log.h>

/*******************************************************************************
**  Functions
********************************************************************************/

static inline void init_slot_lock( pthread_mutex_t* mutex)
{
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
    pthread_mutex_init(mutex, &attr);
}

static inline void lock_slot(pthread_mutex_t* mutex)
{
    if(mutex->value)
        pthread_mutex_lock(mutex);
    else ALOGE("mutex: %p is not initialized", mutex);
}

static inline void unlock_slot(pthread_mutex_t* mutex)
{
   if(mutex->value)
        pthread_mutex_unlock(mutex);
   else ALOGE("mutex: %p is not initialized", mutex);
}

void dump_bin(const char* title, const char* data, int size);

int sock_send_fd(int sock_fd, const uint8_t* buffer, int len, int send_fd);
+27 −28
Original line number Diff line number Diff line
@@ -85,7 +85,7 @@ typedef struct cfg_node_s
    short flag;
} cfg_node;

static pthread_mutex_t slot_lock;
static pthread_mutex_t slot_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
static int pth = -1; //poll thread handle
static cfg_node root;
static int cached_change;
@@ -133,14 +133,13 @@ int btif_config_init()
        if(stat(CFG_PATH, &st) != 0)
            bdle("%s does not exist, need provision", CFG_PATH);
        btsock_thread_init();
        init_slot_lock(&slot_lock);
        lock_slot(&slot_lock);
        pthread_mutex_lock(&slot_lock);
        root.name = "Bluedroid";
        alloc_node(&root, CFG_GROW_SIZE);
        dump_node("root", &root);
        pth = btsock_thread_create(NULL, cfg_cmd_callback);
        load_cfg();
        unlock_slot(&slot_lock);
        pthread_mutex_unlock(&slot_lock);
        #ifdef UNIT_TEST
            cfg_test_write();
            //cfg_test_read();
@@ -176,9 +175,9 @@ int btif_config_exist(const char* section, const char* key, const char* name)
    int ret = FALSE;
    if(section && *section && key && *key)
    {
        lock_slot(&slot_lock);
        pthread_mutex_lock(&slot_lock);
        ret = find_node(section, key, name) != NULL;
        unlock_slot(&slot_lock);
        pthread_mutex_unlock(&slot_lock);
    }
    return ret;
}
@@ -190,7 +189,7 @@ int btif_config_get(const char* section, const char* key, const char* name, char
                section, key, name, value, *bytes, *type);
    if(section && *section && key && *key && name && *name && bytes && type)
    {
        lock_slot(&slot_lock);
        pthread_mutex_lock(&slot_lock);
        const cfg_node* node = find_node(section, key, name);
        dump_node("found node", node);
        if(node)
@@ -213,7 +212,7 @@ int btif_config_get(const char* section, const char* key, const char* name, char
                                      name, node->used, *bytes);
            }
        }
        unlock_slot(&slot_lock);
        pthread_mutex_unlock(&slot_lock);
    }
    return ret;
}
@@ -224,11 +223,11 @@ int btif_config_set(const char* section, const char* key, const char* name, cons
    bdla(bytes < MAX_NODE_BYTES);
    if(section && *section && key && *key && name && *name && bytes < MAX_NODE_BYTES)
    {
        lock_slot(&slot_lock);
        pthread_mutex_lock(&slot_lock);
        ret = set_node(section, key, name, value, (short)bytes, (short)type);
        if(ret && !(type & BTIF_CFG_TYPE_VOLATILE))
            cached_change++;
        unlock_slot(&slot_lock);
        pthread_mutex_unlock(&slot_lock);
    }
    return ret;
}
@@ -239,11 +238,11 @@ int btif_config_remove(const char* section, const char* key, const char* name)
    int ret = FALSE;
    if(section && *section && key && *key)
    {
         lock_slot(&slot_lock);
         pthread_mutex_lock(&slot_lock);
         ret = remove_node(section, key, name);
         if(ret)
            cached_change++;
         unlock_slot(&slot_lock);
         pthread_mutex_unlock(&slot_lock);
    }
    return ret;
}
@@ -256,11 +255,11 @@ int btif_config_filter_remove(const char* section, const char* filter[], int fil
    int ret = FALSE;
    if(section && *section && max_allowed > 0)
    {
         lock_slot(&slot_lock);
         pthread_mutex_lock(&slot_lock);
         ret = remove_filter_node(section, filter, filter_count, max_allowed);
         if(ret)
            cached_change++;
         unlock_slot(&slot_lock);
         pthread_mutex_unlock(&slot_lock);
    }
    return ret;
}
@@ -273,20 +272,20 @@ typedef struct {
short btif_config_next_key(short pos, const char* section, char * name, int* bytes)
{
    int next = -1;
    lock_slot(&slot_lock);
    pthread_mutex_lock(&slot_lock);
    short si = find_inode(&root, section);
    if(si >= 0)
    {
        const cfg_node* section_node = &root.child[si];
        next = find_next_node(section_node, pos, name, bytes);
    }
    unlock_slot(&slot_lock);
    pthread_mutex_unlock(&slot_lock);
    return next;
}
short btif_config_next_value(short pos, const char* section, const char* key, char* name, int* bytes)
{
    int next = -1;
    lock_slot(&slot_lock);
    pthread_mutex_lock(&slot_lock);
    short si = find_inode(&root, section);
    if(si >= 0)
    {
@@ -298,7 +297,7 @@ short btif_config_next_value(short pos, const char* section, const char* key, ch
            next = find_next_node(key_node, pos, name, bytes);
        }
    }
    unlock_slot(&slot_lock);
    pthread_mutex_unlock(&slot_lock);
    return next;
}
int btif_config_enum(btif_config_enum_callback cb, void* user_data)
@@ -306,7 +305,7 @@ int btif_config_enum(btif_config_enum_callback cb, void* user_data)
    bdla(cb);
    if(!cb)
        return FALSE;
    lock_slot(&slot_lock);
    pthread_mutex_lock(&slot_lock);
    int si, ki, vi;
    cfg_node *section_node, *key_node, *value_node;
    for(si = 0; si < GET_CHILD_COUNT(&root); si++)
@@ -332,13 +331,13 @@ int btif_config_enum(btif_config_enum_callback cb, void* user_data)
            }
        }
    }
    unlock_slot(&slot_lock);
    pthread_mutex_unlock(&slot_lock);
    return TRUE;
}
int btif_config_save()
{
    int post_cmd = 0;
    lock_slot(&slot_lock);
    pthread_mutex_lock(&slot_lock);
    bdld("save_cmds_queued:%d, cached_change:%d", save_cmds_queued, cached_change);
    if((save_cmds_queued == 0) && (cached_change > 0))
    {
@@ -346,7 +345,7 @@ int btif_config_save()
        save_cmds_queued++;
        bdld("post_cmd set to 1, save_cmds_queued:%d", save_cmds_queued);
    }
    unlock_slot(&slot_lock);
    pthread_mutex_unlock(&slot_lock);
    /* don't hold lock when invoking send or else a deadlock could
     * occur when the socket thread tries to do the actual saving.
     */
@@ -357,10 +356,10 @@ int btif_config_save()
}
void btif_config_flush()
{
    lock_slot(&slot_lock);
    pthread_mutex_lock(&slot_lock);
    if(cached_change > 0)
        save_cfg();
    unlock_slot(&slot_lock);
    pthread_mutex_unlock(&slot_lock);
}
/////////////////////////////////////////////////////////////////////////////////////////////
static inline short alloc_node(cfg_node* p, short grow)
@@ -798,7 +797,7 @@ static void cfg_cmd_callback(int cmd_fd, int type, int size, uint32_t user_id)
            int last_cached_change;

            // grab lock while accessing cached_change.
            lock_slot(&slot_lock);
            pthread_mutex_lock(&slot_lock);
            bdla(save_cmds_queued > 0);
            save_cmds_queued--;
            last_cached_change = cached_change;
@@ -810,9 +809,9 @@ static void cfg_cmd_callback(int cmd_fd, int type, int size, uint32_t user_id)
                if(cached_change == 0)
                    break;
                // release lock during sleep
                unlock_slot(&slot_lock);
                pthread_mutex_unlock(&slot_lock);
                sleep(3);
                lock_slot(&slot_lock);
                pthread_mutex_lock(&slot_lock);
                if(last_cached_change == cached_change)
                    break;
                last_cached_change = cached_change;
@@ -820,7 +819,7 @@ static void cfg_cmd_callback(int cmd_fd, int type, int size, uint32_t user_id)
            bdld("writing the bt_config.xml now, cached change:%d", cached_change);
            if(cached_change > 0)
                save_cfg();
            unlock_slot(&slot_lock);
            pthread_mutex_unlock(&slot_lock);
            break;
        }
    }
+36 −36
Original line number Diff line number Diff line
@@ -105,7 +105,7 @@ static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data);
static void cleanup_rfc_slot(rfc_slot_t* rs);
static void *rfcomm_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data);
static inline BOOLEAN send_app_scn(rfc_slot_t* rs);
static pthread_mutex_t slot_lock;
static pthread_mutex_t slot_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
#define is_init_done() (pth != -1)
static inline void clear_slot_flag(flags_t* f)
{
@@ -135,7 +135,6 @@ static void init_rfc_slots()
        assert(rfc_slots[i].incoming_queue != NULL);
    }
    BTA_JvEnable(jv_dm_cback);
    init_slot_lock(&slot_lock);
}
bt_status_t btsock_rfc_init(int poll_thread_handle)
{
@@ -148,7 +147,7 @@ void btsock_rfc_cleanup()
    int curr_pth = pth;
    pth = -1;
    btsock_thread_exit(curr_pth);
    lock_slot(&slot_lock);
    pthread_mutex_lock(&slot_lock);
    int i;
    for(i = 0; i < MAX_RFC_CHANNEL; i++)
    {
@@ -157,7 +156,7 @@ void btsock_rfc_cleanup()
            list_free(rfc_slots[i].incoming_queue);
        }
    }
    unlock_slot(&slot_lock);
    pthread_mutex_unlock(&slot_lock);
}
static inline rfc_slot_t* find_free_slot()
{
@@ -315,7 +314,7 @@ bt_status_t btsock_rfc_listen(const char* service_name, const uint8_t* service_u
        }
    }
    int status = BT_STATUS_FAIL;
    lock_slot(&slot_lock);
    pthread_mutex_lock(&slot_lock);
    rfc_slot_t* rs = alloc_rfc_slot(NULL, service_name, service_uuid, channel, flags, TRUE);
    if(rs)
    {
@@ -331,7 +330,7 @@ bt_status_t btsock_rfc_listen(const char* service_name, const uint8_t* service_u
            cleanup_rfc_slot(rs);
        }
    }
    unlock_slot(&slot_lock);
    pthread_mutex_unlock(&slot_lock);
    return status;
}
bt_status_t btsock_rfc_connect(const bt_bdaddr_t *bd_addr, const uint8_t* service_uuid,
@@ -347,7 +346,7 @@ bt_status_t btsock_rfc_connect(const bt_bdaddr_t *bd_addr, const uint8_t* servic
    if(!is_init_done())
        return BT_STATUS_NOT_READY;
    int status = BT_STATUS_FAIL;
    lock_slot(&slot_lock);
    pthread_mutex_lock(&slot_lock);
    rfc_slot_t* rs = alloc_rfc_slot(bd_addr, NULL, service_uuid, channel, flags, FALSE);
    if(rs)
    {
@@ -393,7 +392,7 @@ bt_status_t btsock_rfc_connect(const bt_bdaddr_t *bd_addr, const uint8_t* servic
            btsock_thread_add_fd(pth, rs->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_RD, rs->id);
        }
    }
    unlock_slot(&slot_lock);
    pthread_mutex_unlock(&slot_lock);
    return status;
}

@@ -543,7 +542,7 @@ static BOOLEAN send_app_connect_signal(int fd, const bt_bdaddr_t* addr, int chan
}
static void on_cl_rfc_init(tBTA_JV_RFCOMM_CL_INIT *p_init, uint32_t id)
{
   lock_slot(&slot_lock);
    pthread_mutex_lock(&slot_lock);
    rfc_slot_t* rs = find_rfc_slot_by_id(id);
    if(rs)
    {
@@ -554,11 +553,11 @@ static void on_cl_rfc_init(tBTA_JV_RFCOMM_CL_INIT *p_init, uint32_t id)
            rs->rfc_handle = p_init->handle;
        }
    }
    unlock_slot(&slot_lock);
    pthread_mutex_unlock(&slot_lock);
}
static void  on_srv_rfc_listen_started(tBTA_JV_RFCOMM_START *p_start, uint32_t id)
{
    lock_slot(&slot_lock);
    pthread_mutex_lock(&slot_lock);
    rfc_slot_t* rs = find_rfc_slot_by_id(id);
    if(rs)
    {
@@ -576,12 +575,12 @@ static void on_srv_rfc_listen_started(tBTA_JV_RFCOMM_START *p_start, uint32_t i
            }
        }
    }
    unlock_slot(&slot_lock);
    pthread_mutex_unlock(&slot_lock);
}
static uint32_t on_srv_rfc_connect(tBTA_JV_RFCOMM_SRV_OPEN *p_open, uint32_t id)
{
    uint32_t new_listen_slot_id = 0;
    lock_slot(&slot_lock);
    pthread_mutex_lock(&slot_lock);
    rfc_slot_t* srv_rs = find_rfc_slot_by_id(id);
    if(srv_rs)
    {
@@ -600,12 +599,12 @@ static uint32_t on_srv_rfc_connect(tBTA_JV_RFCOMM_SRV_OPEN *p_open, uint32_t id)
            new_listen_slot_id = srv_rs->id;
        }
    }
    unlock_slot(&slot_lock);
    pthread_mutex_unlock(&slot_lock);
    return new_listen_slot_id;
}
static void on_cli_rfc_connect(tBTA_JV_RFCOMM_OPEN *p_open, uint32_t id)
{
    lock_slot(&slot_lock);
    pthread_mutex_lock(&slot_lock);
    rfc_slot_t* rs = find_rfc_slot_by_id(id);
    if(rs && p_open->status == BTA_JV_SUCCESS)
    {
@@ -625,12 +624,12 @@ static void on_cli_rfc_connect(tBTA_JV_RFCOMM_OPEN *p_open, uint32_t id)
    }
    else if(rs)
        cleanup_rfc_slot(rs);
    unlock_slot(&slot_lock);
    pthread_mutex_unlock(&slot_lock);
}
static void on_rfc_close(tBTA_JV_RFCOMM_CLOSE * p_close, uint32_t id)
{
    UNUSED(p_close);
    lock_slot(&slot_lock);
    pthread_mutex_lock(&slot_lock);
    rfc_slot_t* rs = find_rfc_slot_by_id(id);
    if(rs)
    {
@@ -641,24 +640,24 @@ static void on_rfc_close(tBTA_JV_RFCOMM_CLOSE * p_close, uint32_t id)
        rs->f.connected = FALSE;
        cleanup_rfc_slot(rs);
    }
    unlock_slot(&slot_lock);
    pthread_mutex_unlock(&slot_lock);
}
static void on_rfc_write_done(tBTA_JV_RFCOMM_WRITE *p, uint32_t id)
{
    UNUSED(p);

    lock_slot(&slot_lock);
    pthread_mutex_lock(&slot_lock);
    rfc_slot_t* rs = find_rfc_slot_by_id(id);
    if(rs && !rs->f.outgoing_congest)
    {
        //mointer the fd for any outgoing data
        btsock_thread_add_fd(pth, rs->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_RD, rs->id);
    }
    unlock_slot(&slot_lock);
    pthread_mutex_unlock(&slot_lock);
}
static void on_rfc_outgoing_congest(tBTA_JV_RFCOMM_CONG *p, uint32_t id)
{
    lock_slot(&slot_lock);
    pthread_mutex_lock(&slot_lock);
    rfc_slot_t* rs = find_rfc_slot_by_id(id);
    if(rs)
    {
@@ -667,7 +666,7 @@ static void on_rfc_outgoing_congest(tBTA_JV_RFCOMM_CONG *p, uint32_t id)
        if(!rs->f.outgoing_congest)
            btsock_thread_add_fd(pth, rs->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_RD, rs->id);
    }
    unlock_slot(&slot_lock);
    pthread_mutex_unlock(&slot_lock);
}

static void *rfcomm_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data)
@@ -730,7 +729,7 @@ static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data)
    {
        case BTA_JV_CREATE_RECORD_EVT:
            {
                lock_slot(&slot_lock);
                pthread_mutex_lock(&slot_lock);
                rfc_slot_t* rs = find_rfc_slot_by_id(id);
                if(rs && create_server_sdp_record(rs))
                {
@@ -743,13 +742,13 @@ static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data)
                    APPL_TRACE_ERROR("jv_dm_cback: cannot start server, slot found:%p", rs);
                    cleanup_rfc_slot(rs);
                }
                unlock_slot(&slot_lock);
                pthread_mutex_unlock(&slot_lock);
                break;
            }
        case BTA_JV_DISCOVERY_COMP_EVT:
            {
                rfc_slot_t* rs = NULL;
                lock_slot(&slot_lock);
                pthread_mutex_lock(&slot_lock);
                if(p_data->disc_comp.status == BTA_JV_SUCCESS && p_data->disc_comp.scn)
                {
                    APPL_TRACE_DEBUG("BTA_JV_DISCOVERY_COMP_EVT, slot id:%d, status:%d, scn:%d",
@@ -795,7 +794,7 @@ static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data)
                    rs->f.pending_sdp_request = FALSE;
                    rs->f.doing_sdp_request = TRUE;
                }
                unlock_slot(&slot_lock);
                pthread_mutex_unlock(&slot_lock);
                break;
            }
        default:
@@ -866,7 +865,7 @@ static BOOLEAN flush_incoming_que_on_wr_signal(rfc_slot_t* rs)
}
void btsock_rfc_signaled(int fd, int flags, uint32_t user_id)
{
    lock_slot(&slot_lock);
    pthread_mutex_lock(&slot_lock);
    rfc_slot_t* rs = find_rfc_slot_by_id(user_id);
    if(rs)
    {
@@ -886,8 +885,9 @@ void btsock_rfc_signaled(int fd, int flags, uint32_t user_id)
                    {
                        int rfc_handle = rs->rfc_handle;
                        UINT32 rs_id = rs->id;
                        //unlock before BTA_JvRfcommWrite to avoid deadlock on concurrnet multi rfcomm connectoins
                        unlock_slot(&slot_lock);
                        // unlock before BTA_JvRfcommWrite to avoid
                        // deadlock on concurrent multi-rfcomm connections.
                        pthread_mutex_unlock(&slot_lock);
                        BTA_JvRfcommWrite(rfc_handle, rs_id);
                        return;
                    }
@@ -926,14 +926,14 @@ void btsock_rfc_signaled(int fd, int flags, uint32_t user_id)
                                flags, need_close, size);
        }
    }
    unlock_slot(&slot_lock);
    pthread_mutex_unlock(&slot_lock);
}

int bta_co_rfc_data_incoming(void *user_data, BT_HDR *p_buf)
{
    uint32_t id = (uintptr_t)user_data;
    int ret = 0;
    lock_slot(&slot_lock);
    pthread_mutex_lock(&slot_lock);
    rfc_slot_t* rs = find_rfc_slot_by_id(id);
    if(rs)
    {
@@ -962,7 +962,7 @@ int bta_co_rfc_data_incoming(void *user_data, BT_HDR *p_buf)
            }
        }
     }
    unlock_slot(&slot_lock);
    pthread_mutex_unlock(&slot_lock);
    return ret;//return 0 to disable data flow
}
int bta_co_rfc_data_outgoing_size(void *user_data, int *size)
@@ -970,7 +970,7 @@ int bta_co_rfc_data_outgoing_size(void *user_data, int *size)
    uint32_t id = (uintptr_t)user_data;
    int ret = FALSE;
    *size = 0;
    lock_slot(&slot_lock);
    pthread_mutex_lock(&slot_lock);
    rfc_slot_t* rs = find_rfc_slot_by_id(id);
    if(rs)
    {
@@ -986,14 +986,14 @@ int bta_co_rfc_data_outgoing_size(void *user_data, int *size)
        }
    }
    else APPL_TRACE_ERROR("bta_co_rfc_data_outgoing_size, invalid slot id:%d", id);
    unlock_slot(&slot_lock);
    pthread_mutex_unlock(&slot_lock);
    return ret;
}
int bta_co_rfc_data_outgoing(void *user_data, UINT8* buf, UINT16 size)
{
    uint32_t id = (uintptr_t)user_data;
    int ret = FALSE;
    lock_slot(&slot_lock);
    pthread_mutex_lock(&slot_lock);
    rfc_slot_t* rs = find_rfc_slot_by_id(id);
    if(rs)
    {
@@ -1008,7 +1008,7 @@ int bta_co_rfc_data_outgoing(void *user_data, UINT8* buf, UINT16 size)
        }
    }
    else APPL_TRACE_ERROR("bta_co_rfc_data_outgoing, invalid slot id:%d", id);
    unlock_slot(&slot_lock);
    pthread_mutex_unlock(&slot_lock);
    return ret;
}
+5 −7
Original line number Diff line number Diff line
@@ -109,8 +109,7 @@ static inline void close_cmd_fd(int h);

static inline void add_poll(int h, int fd, int type, int flags, uint32_t user_id);

static pthread_mutex_t thread_slot_lock;

static pthread_mutex_t thread_slot_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;

static inline pthread_t create_thread(void *(*start_routine)(void *), void * arg)
{
@@ -158,7 +157,6 @@ int btsock_thread_init()
    if(!initialized)
    {
        initialized = 1;
        init_slot_lock(&thread_slot_lock);
        int h;
        for(h = 0; h < MAX_THREAD; h++)
        {
@@ -175,9 +173,9 @@ int btsock_thread_init()
int btsock_thread_create(btsock_signaled_cb callback, btsock_cmd_cb cmd_callback)
{
    asrt(callback || cmd_callback);
    lock_slot(&thread_slot_lock);
    pthread_mutex_lock(&thread_slot_lock);
    int h = alloc_thread_slot();
    unlock_slot(&thread_slot_lock);
    pthread_mutex_unlock(&thread_slot_lock);
    APPL_TRACE_DEBUG("alloc_thread_slot ret:%d", h);
    if(h >= 0)
    {
@@ -323,9 +321,9 @@ int btsock_thread_exit(int h)
    if(send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd))
    {
        pthread_join(ts[h].thread_id, 0);
        lock_slot(&thread_slot_lock);
        pthread_mutex_lock(&thread_slot_lock);
        free_thread_slot(h);
        unlock_slot(&thread_slot_lock);
        pthread_mutex_unlock(&thread_slot_lock);
        return TRUE;
    }
    return FALSE;
+3 −1
Original line number Diff line number Diff line
@@ -208,7 +208,9 @@ static int accept_server_socket(int sfd)
static int uipc_main_init(void)
{
    int i;
    const pthread_mutexattr_t attr = PTHREAD_MUTEX_RECURSIVE;
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
    pthread_mutex_init(&uipc_main.mutex, &attr);

    BTIF_TRACE_EVENT("### uipc_main_init ###");