struct unix_proto_data unix_datas[NSOCKETS_UNIX]
#define last_unix_data (unix_datas + NSOCKETS_UNIX - 1) // 数组的最大边界
unix_datas变量维护个数组,每个元素是unix_proto_data 结构。
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结构
// 分配一个没有被使用的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);
}
查找
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);
}
引用计数管理
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;
}