It is not easy to write a proc file module, or a char device, or other similar fs related stuffs with non-blocking I/O support. But if it happens that you have full control of both userspace and kernel space code, a tricky approach can be made to do the non-blocking thing.
Simply, return -EAGAIN in the read syscall implementation immediately once the data is unavailable. Like here:
Simply, return -EAGAIN in the read syscall implementation immediately once the data is unavailable. Like here:
static int reqfs_read(char *buf, char **bufloc,
off_t offset, int buflen,
int *eof, void *data)
{
int ret;
struct list_head *r;
struct kgpu_req *req = NULL;
ret = 0;
spin_lock(&reqlock);
if (!list_empty(&reqs)) {
r = reqs.next;
list_del(r);
req = list_entry(r, struct kgpu_req, list);
if (req) {
copy_to_user(buf, (char*)&(req->kureq), sizeof(struct ku_request));
ret = sizeof(struct ku_request);
}
} else {
ret = -EAGAIN;
}
spin_unlock(&reqlock);
if (ret > 0 && req) {
spin_lock(&rtdreqlock);
INIT_LIST_HEAD(&req->list);
list_add_tail(&req->list, &rtdreqs);
spin_unlock(&rtdreqlock);
}
return ret;
}
Ignore the lock and list stuffs. If no data available, which is indicated by an empty list, the read of a proc fs item will return -EAGAIN to let the userspace code try again. In the userspace, read syscall will return -1, and the errno will be EAGAIN, the return value and errno must be checked explicitly to ensure the try-again response not to be treated as a fault error.
No comments:
Post a Comment