starting to come together

git-svn-id: svn://svn.code.sf.net/p/libkqueue/code/trunk@222 fb4e3144-bc1c-4b72-a658-5bcd248dd7f7
This commit is contained in:
mheily 2010-02-28 00:25:36 +00:00
parent 182b3de789
commit d231f92742
3 changed files with 83 additions and 15 deletions

View File

@ -29,6 +29,7 @@ clean:
update: all
rmmod kqueue
insmod ./kqueue.ko
sleep 2
chmod 777 /dev/kqueue
modtest: test.c

View File

@ -31,6 +31,7 @@
/* Portions based on
$FreeBSD: src/sys/kern/kern_event.c,v 1.126.2.1.2.1 2009/10/25 01:10:29 kensmith Exp $
$FreeBSD: src/sys/sys/eventvar.h,v 1.6.30.1.2.1 2009/10/25 01:10:29 kensmith Exp $
*/
#include <linux/cdev.h>
@ -40,12 +41,17 @@
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/rbtree.h>
#include <linux/syscalls.h>
#include <linux/uaccess.h>
#include "../include/sys/event.h"
#include "queue.h"
struct kqueue;
struct kfilter;
struct knote;
static int kqueue_open (struct inode *inode, struct file *file);
static int kqueue_release (struct inode *inode, struct file *file);
static int kqueue_ioctl(struct inode *inode, struct file *file,
@ -64,14 +70,54 @@ struct file_operations fops = {
.write = kqueue_write,
};
struct kqueue_data {
spinlock_t kq_lock;
struct kfilter {
struct rb_root kf_note;
};
struct kqueue {
spinlock_t kq_lock;
int kq_count; /* number of pending events */
struct kfilter kq_filt[EVFILT_SYSCOUNT];
};
#ifdef TODO
struct filterops {
int f_isfd; /* true if ident == filedescriptor */
int (*f_attach)(struct knote *kn);
void (*f_detach)(struct knote *kn);
int (*f_event)(struct knote *kn, long hint);
};
static struct kfilter {
struct filterops kf_fop;
int for_refcnt;
} sysfilt_ops[EVFILT_SYSCOUNT];
= {
{ &file_filtops }, /* EVFILT_READ */
{ &file_filtops }, /* EVFILT_WRITE */
{ &null_filtops }, /* EVFILT_AIO */
{ &file_filtops }, /* EVFILT_VNODE */
{ &proc_filtops }, /* EVFILT_PROC */
{ &sig_filtops }, /* EVFILT_SIGNAL */
{ &timer_filtops }, /* EVFILT_TIMER */
{ &file_filtops }, /* EVFILT_NETDEV */
{ &fs_filtops }, /* EVFILT_FS */
{ &null_filtops }, /* EVFILT_LIO */
};
#endif
static int major;
static struct class *kqueue_class;
static struct task_struct *kq_thread;
static struct kfilter *
kfilter_lookup(struct kqueue *kq, int filt)
{
if (filt > 0 || filt + EVFILT_SYSCOUNT < 0)
return NULL;
return &kq->kq_filt[~filt];
}
//only for sleeping during testing
#include <linux/delay.h>
static int kqueue_main(void *arg)
@ -88,7 +134,8 @@ static int kqueue_main(void *arg)
static int kqueue_open (struct inode *inode, struct file *file)
{
struct kqueue_data *kq;
struct kqueue *kq;
int i;
printk("kqueue_open\n");
@ -98,11 +145,9 @@ static int kqueue_open (struct inode *inode, struct file *file)
return -1;
}
spin_lock_init(&kq->kq_lock);
for (i = 0; i < EVFILT_SYSCOUNT; i++)
kq->kq_filt[i].kf_note = RB_ROOT;
file->private_data = kq;
/* FIXME Unresolved symbols
kq->kq_fd[0] = epoll_create1(0);
kq->kq_fd[0] = sys_inotify_init();
*/
return 0;
}
@ -131,7 +176,7 @@ static int kqueue_ioctl(struct inode *inode, struct file *file,
static ssize_t kqueue_read(struct file *file, char __user *buf,
size_t lbuf, loff_t *ppos)
{
struct kqueue_data *kq = file->private_data;
struct kqueue *kq = file->private_data;
spin_lock(&kq->kq_lock);
//STUB
@ -143,14 +188,31 @@ static ssize_t kqueue_read(struct file *file, char __user *buf,
static ssize_t kqueue_write(struct file *file, const char __user *buf,
size_t lbuf, loff_t *ppos)
{
struct kqueue_data *kq = file->private_data;
struct kqueue *kq = file->private_data;
struct kevent kev;
struct kfilter *filt;
size_t i, nchanges;
char kbuf[4];
if ((lbuf % sizeof(struct kevent)) != 0)
return -EINVAL;
nchanges = lbuf / sizeof(struct kevent);
spin_lock(&kq->kq_lock);
copy_from_user(kbuf, buf, 4);
printk("%zu bytes: %s", lbuf, kbuf);
spin_unlock(&kq->kq_lock);
for (i = 0; i < nchanges; i++) {
if (copy_from_user(&kev, (struct kevent *) buf, sizeof(kev)))
return -EFAULT;
filt = kfilter_lookup(kq, kev.filter);
if (filt == NULL)
return -EINVAL;
#ifdef DEADWOOD
spin_lock(&kq->kq_lock);
printk("%zu bytes, nchanges=%zu", lbuf, nchanges);
spin_unlock(&kq->kq_lock);
#endif
buf += sizeof(kev);
}
return sizeof(struct kevent);
}

View File

@ -22,9 +22,12 @@
#include <stdlib.h>
#include <unistd.h>
#include "../include/sys/event.h"
int
main(int argc, char **argv)
{
struct kevent kev;
int fd;
fd = open("/dev/kqueue", O_RDWR);
@ -32,6 +35,7 @@ main(int argc, char **argv)
err(1, "open()");
printf("kqfd = %d\n", fd);
EV_SET(&kev, 1, EVFILT_READ, EV_ADD, 0, 0, NULL);
#if OLD
int x;
@ -42,7 +46,8 @@ main(int argc, char **argv)
if (ioctl(fd, 1234, (char *) &x) < 0)
err(1, "ioctl");
#endif
write(fd, "hi\n", 3);
if (write(fd, &kev, sizeof(kev)) < 0)
err(1, "write");
close(fd);
puts("ok");