鸿蒙源码分析(六)

os_adapter.c代码分析

本篇主要分析模块一中trans_service目录下tcp_socket.c代码。
文件路径(模块一\communication_softbus_lite- master\trans_service\source\utils\message.c)

一、背景知识

os_adapter相关前缀理论部分已经在队友博客中解释(点击此处查看理论部分

二、代码分析

软总线模块中os_adapter目录为操作系统接口适配层,其中L0和L1两个目录下各有一个os_adapter.c文件,二者功能函数基本一致,不同点在于适用环境不同,下面主要分析L1下面os_adapter.c文件。
1.初始化互斥锁
mutexinit函数用来初始化互斥锁,基于pthread_mutex_init()函数。

MutexId MutexInit(void)//初始化互斥锁
{
    pthread_mutex_t *mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
    //使用malloc函数动态申请内存空间
    if (mutex == NULL) {
        return NULL;
        //申请失败函数返回NULL
    }
    (void)pthread_mutex_init(mutex, NULL);
    //该函数用于C函数的多线程编程中,互斥锁的初始化。
    return (MutexId)mutex;
}

2.互斥体加锁
MutexLock函数用来为互斥体进行加锁,将参数指定的对象进行加锁,避免被其他进程调用读取。
基于pthread_mutex_lock(),该函数锁住由mutex指定的mutex 对象。如果mutex已经被锁住,调用这个函数的线程阻塞直到mutex可用为止。这跟函数返回的时候参数mutex指定的mutex对象变成锁住状态, 同时该函数的调用线程成为该mutex对象的拥有者。

void MutexLock(MutexId mutex)
{
    if (mutex == NULL) {
        return;
    }
    pthread_mutex_lock((pthread_mutex_t *)mutex);
    //锁住由mutex指定的mutex 对象。
}

3.互斥体释放
MutexUnLock函数用来释放互斥体指向对象上面的锁,基于pthread_mutex_unlock() 函数。
pthread_mutex_unlock()可释放mutex引用的互斥锁对象。互斥锁的释放方式取决于互斥锁的类型属性。 如果调用pthread_mutex_unlock()时有多个线程被mutex对象阻塞,则互斥锁变为可用时调度策略可确定获取该互斥锁的线程。 对于PTHREAD_MUTEX_RECURSIVE类型的互斥锁,当计数达到零并且调用线程不再对该互斥锁进行任何锁定时,该互斥锁将变为可用。

void MutexUnlock(MutexId mutex)//释放互斥体
{
    if (mutex == NULL) {
        return;
    }
    pthread_mutex_unlock((pthread_mutex_t *)mutex);
    //释放有参数mutex指定的mutex对象的锁。
}

4.关闭套接字函数

void CloseSocket(int *fd)
{
    if (fd == NULL) {
        return;
    }
    if (*fd >= 0) {
        close(*fd);
        //传入的正值对应的套接字接口关闭
        *fd = -1;
    }
    //关闭socket中套接字连接
}

5.创建消息队列
CreateMsgQue() 函数用来创建一个消息队列。
参数详解

  • const char *queueName :队列名
  • unsigned short len:每个消息的最大字节数
  • unsigned int *queueID:队列的ID编号
  • unsigned int flags:消息队列标志,表示是否堵塞
  • unsigned short maxMsgSize:消息队列中每个消息的最大字节数
int CreateMsgQue(const char *queueName,//创建一个消息队列
    unsigned short len, unsigned int *queueID,
    unsigned int flags, unsigned short maxMsgSize)
{
    if (queueName == NULL || queueID == NULL) {
        return -1;
    }
    struct mq_attr newAttr = {0};
    newAttr.mq_flags = flags;
    newAttr.mq_maxmsg = len;
    newAttr.mq_msgsize = maxMsgSize;
    int mqd = mq_open(queueName, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR, &newAttr);
    //mq_open函数用来创建一个消息队列,成功返回队列描述符,失败-1
    if (mqd < 0) {
        return -1;
        //创建失败,函数返回-1推出
    }
    *queueID = mqd;//将队列id指向创建的消息队列
    return 0;
}

6.写消息队列(发送)
WriteMsgQue(unsigned int queueID, const void *bufferAddr , unsigned int bufferSize) 函数用来发送消息并将消息写进队列。基于mq_send()函数。
函数参数详解:

  • unsigned int queueID:队列编号ID
  • const void *bufferAddr:存放消息的缓冲区地址
  • unsigned int bufferSize:消息大小
int WriteMsgQue(unsigned int queueID,
    const void *bufferAddr, unsigned int bufferSize)
{
    if (bufferAddr == NULL) {
        return -1;
    }
    int ret = mq_send(queueID, bufferAddr, bufferSize, 0);
    //将bufferAddr指向的内容以bufferSize大小发送至对应消息队列,发送成功返回0,否则返回非0值
    //进程在打开消息队列后,可以使用mq_send函数发送消息。
    if (ret != 0) {
        return -1;
        //发送失败函数返回-1并退出
    }
    return 0;
}

7.读取消息队列
读取消息函数ReadMsgQue(),基于mq_receive()函数从消息队列中读取消息.
参数详解:

  • unsigned int queueID:队列编号ID
  • void *bufferAddr:存放消息的缓冲区地址
  • unsigned int bufferSize:消息大小
int ReadMsgQue(unsigned int queueID,//从消息队列中读取消息
    void *bufferAddr, unsigned int *bufferSize)
{
    if (bufferAddr == NULL || bufferSize == NULL) {
        return -1;
    }
    unsigned int readSize = *bufferSize;
    unsigned int receiveSize = mq_receive(queueID, bufferAddr, readSize, 0);//从消息队列中获取消息
    //调用 mq_receive 时总是返回队列中 最高优先级的最早消息。函数返回值为读取到的字节数
    if (receiveSize != readSize) {
        return -1;
        //读取字节数和传入字节数不相等就退出函数,返回-1
    }

    *bufferSize = receiveSize;//将缓冲区大小置为接受到的数据大小范围
    return 0;
}

8.删除消息队列
DeleteMsgQue(unsigned int queueID) 基于mq_close()函数关闭消息队列

int DeleteMsgQue(unsigned int queueID)//用来删除/关闭消息队列
{
    return mq_close(queueID);
    //函数会断开消息队列描述符 和 与之对应消息队列间的连接.
}

9.检查用户权限
SoftBusCheckPermission(const char* permissionName) 函数用来检查用户的权限许可。
该函数中用到安卓API中CheckSelfPermission()函数,专门用来检查用户权限

int SoftBusCheckPermission(const char* permissionName)
//用来检查用户权限
{
    if (permissionName == NULL) {
        return -1;
    }

    if (CheckSelfPermission(permissionName) != GRANTED) {
        //CheckSelfPermission用来检查权限,成功则返回GRANTED对应值
        SOFTBUS_PRINT("[SOFTBUS] CheckSelfPermission fail\n");
        return -1;
        //检查失败输出提示并返回-1
    }
    return 0;
}

以上为os_adapter.c代码的分析,感谢阅读和点赞。理论部分和头文件请戳这里

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值