前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >uninx域基础数据结构及操作

uninx域基础数据结构及操作

原创
作者头像
theanarkh
修改2019-01-10 10:10:08
3510
修改2019-01-10 10:10:08
举报
文章被收录于专栏:原创分享原创分享
代码语言:javascript
复制

struct unix_proto_data unix_datas[NSOCKETS_UNIX]
#define last_unix_data        (unix_datas + NSOCKETS_UNIX - 1) // 数组的最大边界

unix_datas变量维护个数组,每个元素是unix_proto_data 结构。

代码语言:javascript
复制
struct unix_proto_data {
     int  refcnt; // 标记该结构是否已经被使用
     struct socket *socket; // 该节点对应的socket
     int  protocol; 
     struct sockaddr_un sockaddr_un; // 协议簇和路径名
     short  sockaddr_len;  //  sock_addr_un的长度
     char  *buf; // 读写缓冲区,实现全双工
     int  bp_head, // 可写空间的头指针
     int  bp_tail; // 可写空间的尾指针
     struct inode *inode; // 路径名对应的文件的inode
     struct unix_proto_data *peerupd; // 对端的结构
     struct wait_queue *wait;  // 因为拿不到lock_flag被阻塞的队列 
     int  lock_flag; // 互斥访问
};

分配一个unix_proto_data结构

代码语言:javascript
复制
// 分配一个没有被使用的unix_proto_data结构
static struct unix_proto_data *
unix_data_alloc(void)
{
    struct unix_proto_data *upd;
    cli();
    for(upd = unix_datas; upd <= last_unix_data; ++upd) 
    {    // 没有被使用
        if (!upd->refcnt) 
        {    // 初始化数据
            upd->refcnt = -1;    /* unix domain socket not yet initialised - bgm */
            sti();
            upd->socket = NULL;
            upd->sockaddr_len = 0;
            upd->sockaddr_un.sun_family = 0;
            upd->buf = NULL;
            upd->bp_head = upd->bp_tail = 0;
            upd->inode = NULL;
            upd->peerupd = NULL;
            return(upd);
        }
    }
    sti();
    return(NULL);
}

查找

代码语言:javascript
复制
static struct unix_proto_data *
unix_data_lookup(struct sockaddr_un *sockun, int sockaddr_len,
         struct inode *inode)
{
     struct unix_proto_data *upd;
     for(upd = unix_datas; upd <= last_unix_data; ++upd) 
     {
        if (upd->refcnt > 0 && upd->socket &&
            upd->socket->state == SS_UNCONNECTED &&
            upd->sockaddr_un.sun_family == sockun->sun_family &&
            upd->inode == inode) 
            return(upd);
    }
    return(NULL);
}

引用计数管理

代码语言:c
复制
static inline void unix_data_ref(struct unix_proto_data *upd)
{
    if (!upd) 
    {
        return;
    }
    ++upd->refcnt;
}
static void unix_data_deref(struct unix_proto_data *upd)
{
    if (!upd) 
    {
        return;
    }
    //引用数为1说明没人使用了,则释放该结构对应的内存
    if (upd->refcnt == 1) 
    {
        if (upd->buf) 
        {
            free_page((unsigned long)upd->buf);
            upd->buf = NULL;
            upd->bp_head = upd->bp_tail = 0;
        }
    }
    --upd->refcnt;
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档