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;}复制代码