media: v4l2-dev/event: add v4l2_event_wake_all()
When unregistering a V4L2 device node, make sure any filehandles that are waiting for an event are woken up. Add v4l2_event_wake_all() to v4l2-event.c and call it from video_unregister_device(). Otherwise userspace might never know that a device node was removed. [hverkuil: checkpatch: replaced 'if (vdev == NULL)' by 'if (!vdev)'] Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
This commit is contained in:
parent
726daf6baf
commit
28955a6156
@ -28,6 +28,7 @@
|
||||
#include <media/v4l2-common.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-ioctl.h>
|
||||
#include <media/v4l2-event.h>
|
||||
|
||||
#define VIDEO_NUM_DEVICES 256
|
||||
#define VIDEO_NAME "video4linux"
|
||||
@ -1086,6 +1087,8 @@ void video_unregister_device(struct video_device *vdev)
|
||||
*/
|
||||
clear_bit(V4L2_FL_REGISTERED, &vdev->flags);
|
||||
mutex_unlock(&videodev_lock);
|
||||
if (test_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags))
|
||||
v4l2_event_wake_all(vdev);
|
||||
device_unregister(&vdev->dev);
|
||||
}
|
||||
EXPORT_SYMBOL(video_unregister_device);
|
||||
|
@ -187,6 +187,23 @@ int v4l2_event_pending(struct v4l2_fh *fh)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(v4l2_event_pending);
|
||||
|
||||
void v4l2_event_wake_all(struct video_device *vdev)
|
||||
{
|
||||
struct v4l2_fh *fh;
|
||||
unsigned long flags;
|
||||
|
||||
if (!vdev)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&vdev->fh_lock, flags);
|
||||
|
||||
list_for_each_entry(fh, &vdev->fh_list, list)
|
||||
wake_up_all(&fh->wait);
|
||||
|
||||
spin_unlock_irqrestore(&vdev->fh_lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(v4l2_event_wake_all);
|
||||
|
||||
static void __v4l2_event_unsubscribe(struct v4l2_subscribed_event *sev)
|
||||
{
|
||||
struct v4l2_fh *fh = sev->fh;
|
||||
|
@ -101,7 +101,7 @@ int v4l2_event_dequeue(struct v4l2_fh *fh, struct v4l2_event *event,
|
||||
*
|
||||
* .. note::
|
||||
* The driver's only responsibility is to fill in the type and the data
|
||||
* fields.The other fields will be filled in by V4L2.
|
||||
* fields. The other fields will be filled in by V4L2.
|
||||
*/
|
||||
void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev);
|
||||
|
||||
@ -116,10 +116,19 @@ void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev);
|
||||
*
|
||||
* .. note::
|
||||
* The driver's only responsibility is to fill in the type and the data
|
||||
* fields.The other fields will be filled in by V4L2.
|
||||
* fields. The other fields will be filled in by V4L2.
|
||||
*/
|
||||
void v4l2_event_queue_fh(struct v4l2_fh *fh, const struct v4l2_event *ev);
|
||||
|
||||
/**
|
||||
* v4l2_event_wake_all - Wake all filehandles.
|
||||
*
|
||||
* Used when unregistering a video device.
|
||||
*
|
||||
* @vdev: pointer to &struct video_device
|
||||
*/
|
||||
void v4l2_event_wake_all(struct video_device *vdev);
|
||||
|
||||
/**
|
||||
* v4l2_event_pending - Check if an event is available
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user