[RFC,v2,7/7] V4L: Events: Support all events

Message ID 1261500191-9441-7-git-send-email-sakari.ailus@maxwell.research.nokia.com (mailing list archive)
State RFC, archived
Headers

Commit Message

Sakari Ailus Dec. 22, 2009, 4:43 p.m. UTC
  Add support for subscribing V4L2_EVENT_ALL. After V4L2_EVENT_ALL is
subscribed, unsubscribing any event leads to unsubscription of all events.

Signed-off-by: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
---
 drivers/media/video/v4l2-event.c |   34 ++++++++++++++++++++++++----------
 1 files changed, 24 insertions(+), 10 deletions(-)
  

Patch

diff --git a/drivers/media/video/v4l2-event.c b/drivers/media/video/v4l2-event.c
index cc2bf57..95b3917 100644
--- a/drivers/media/video/v4l2-event.c
+++ b/drivers/media/video/v4l2-event.c
@@ -62,6 +62,22 @@  void v4l2_event_init_fh(struct v4l2_fh *fh)
 }
 EXPORT_SYMBOL_GPL(v4l2_event_init_fh);
 
+static void __v4l2_event_unsubscribe_all(struct v4l2_fh *fh)
+{
+	struct v4l2_events *events = &fh->events;
+
+	while (!list_empty(&events->subscribed)) {
+		struct v4l2_subscribed_event *sub;
+
+		sub = list_entry(events->subscribed.next,
+				struct v4l2_subscribed_event, list);
+
+		list_del(&sub->list);
+
+		kfree(sub);
+	}
+}
+
 void v4l2_event_exit_fh(struct v4l2_fh *fh)
 {
 	struct v4l2_events *events = &fh->events;
@@ -77,16 +93,7 @@  void v4l2_event_exit_fh(struct v4l2_fh *fh)
 		kmem_cache_free(event_kmem, ev);
 	}
 
-	while (!list_empty(&events->subscribed)) {
-		struct v4l2_subscribed_event *sub;
-
-		sub = list_entry(events->subscribed.next,
-				struct v4l2_subscribed_event, list);
-
-		list_del(&sub->list);
-
-		kfree(sub);
-	}
+	__v4l2_event_unsubscribe_all(fh);
 }
 EXPORT_SYMBOL_GPL(v4l2_event_exit_fh);
 
@@ -125,6 +132,11 @@  static struct v4l2_subscribed_event *__v4l2_event_subscribed(
 	struct v4l2_events *events = &fh->events;
 	struct v4l2_subscribed_event *ev;
 
+	ev = container_of(events->subscribed.next,
+			  struct v4l2_subscribed_event, list);
+	if (ev->type == V4L2_EVENT_ALL)
+		return ev;
+
 	list_for_each_entry(ev, &events->subscribed, list) {
 		if (ev->type == type)
 			return ev;
@@ -237,6 +249,8 @@  int v4l2_event_subscribe(struct v4l2_fh *fh,
 	INIT_LIST_HEAD(&ev->list);
 	ev->type = sub->type;
 
+	if (ev->type == V4L2_EVENT_ALL)
+		__v4l2_event_unsubscribe_all(fh);
 	list_add(&ev->list, &events->subscribed);
 
 out: