@@ -56,6 +56,8 @@ void v4l2_event_init_fh(struct v4l2_fh *fh)
INIT_LIST_HEAD(&events->available);
INIT_LIST_HEAD(&events->subscribed);
+
+ atomic_set(&events->navailable, 0);
}
EXPORT_SYMBOL_GPL(v4l2_event_init_fh);
@@ -103,7 +105,8 @@ int v4l2_event_dequeue(struct v4l2_fh *fh, struct v4l2_event *event)
ev = list_first_entry(&events->available, struct _v4l2_event, list);
list_del(&ev->list);
- ev->event.count = !list_empty(&events->available);
+ atomic_dec(&events->navailable);
+ ev->event.count = atomic_read(&events->navailable);
spin_unlock_irqrestore(&events->lock, flags);
@@ -159,6 +162,9 @@ void v4l2_event_queue(struct video_device *vdev, struct v4l2_event *ev)
if (!v4l2_event_subscribed(fh, ev->type))
continue;
+ if (atomic_read(&fh->events.navailable) >= V4L2_MAX_EVENTS)
+ continue;
+
_ev = kmem_cache_alloc(event_kmem, GFP_ATOMIC);
if (!_ev)
continue;
@@ -169,6 +175,8 @@ void v4l2_event_queue(struct video_device *vdev, struct v4l2_event *ev)
list_add_tail(&_ev->list, &fh->events.available);
spin_unlock(&fh->events.lock);
+ atomic_inc(&fh->events.navailable);
+
wake_up_all(&fh->events.wait);
}
@@ -28,6 +28,10 @@
#include <linux/types.h>
#include <linux/videodev2.h>
+#include <asm/atomic.h>
+
+#define V4L2_MAX_EVENTS 1024 /* Ought to be enough for everyone. */
+
struct v4l2_fh;
struct video_device;
@@ -39,6 +43,7 @@ struct _v4l2_event {
struct v4l2_events {
spinlock_t lock; /* Protect everything here. */
struct list_head available;
+ atomic_t navailable;
wait_queue_head_t wait;
struct list_head subscribed; /* Subscribed events. */
};