以下代码基于linux 2.6.39.2首先从poll_wait开始 static inline
void poll_wait(
struct file * filp, wait_queue_head_t * wait_address, poll_table *p)
{
if (p && wait_address)
p->qproc(filp, wait_address, p);
}
从poll_initwait函数可以看出p->qproc实际上调用的是__pollwait
1: static void __pollwait(struct file *filp, wait_queue_head_t *wait_address, 2: poll_table *p) 3: { 4: struct poll_wqueues *pwq = container_of(p, struct poll_wqueues, pt); 5: struct poll_table_entry *entry = poll_get_entry(pwq);//获取空闲的poll_table_entry指针 6: if (!entry) 7: return; 8: get_file(filp);//增加引用计数 9: /*接下来初始化entry*/ 10: entry->filp = filp; 11: entry->wait_address = wait_address; 12: entry->key = p->key; 13: init_waitqueue_func_entry(&entry->wait, pollwake); 14: entry->wait.private = pwq; 15: add_wait_queue(wait_address, &entry->wait);//将wait加入到wait_address等待队列头链表上 16: }
其中上面的函数:poll_get_entry
1: static struct poll_table_entry *poll_get_entry(struct poll_wqueues *p) 2: { 3: struct poll_table_page *table = p->table; 4: 5: if (p->inline_index < N_INLINE_POLL_ENTRIES) 6: return p->inline_entries + p->inline_index++; 7: 8: if (!table || POLL_TABLE_FULL(table)) { 9: struct poll_table_page *new_table; 10: 11: new_table = (struct poll_table_page *) __get_free_page(GFP_KERNEL); 12: if (!new_table) { 13: p->error = -ENOMEM; 14: return NULL; 15: } 16: new_table->entry = new_table->entries; 17: new_table->next = table; 18: p->table = new_table; 19: table = new_table; 20: } 21: 22: return table->entry++; 23: }
很简单,首先判断index是否超过wqueue自身的entry长度,如果没有,直接返回wqueue->inline_entries[]的地址,否则
就分配一个poll_table_page,然后插入wqueue->table的头部,然后返回该地址。
(未完待续~~~)
阅读(1038) | 评论(0) | 转发(0) |