diff options
author | Mike Isely <isely@pobox.com> | 2008-04-07 01:22:04 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-24 13:09:48 -0400 |
commit | e5be15c63804e05b5a94197524023702a259e308 (patch) | |
tree | 4223cab8016088a06d0423e1e41eacb646867c46 /drivers/media/video/pvrusb2/pvrusb2-context.h | |
parent | d913d6303072ca194919d851e6743ad8c3a7563d (diff) |
V4L/DVB (7711): pvrusb2: Fix race on module unload
The pvrusb2 driver - for basically forever - was not enforcing a
proper module tear-down. Kernel threads are used inside the driver
and all must be gone before the module can be safely removed. This
changeset reimplements a chunk of pvrusb2-context.c to enforce this
correctly. Unfortunately this is not a simple fix. The new
implementation also cuts back on kernel thread usage; instead of there
being 1 control thread per instance now it's just 1 control thread
shared by all instances. (By dropping to a single thread then the
module exit function can block on its shutdown and the thread itself
can monitor and cleanly shut down all of the other instances first.)
Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/pvrusb2/pvrusb2-context.h')
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-context.h | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.h b/drivers/media/video/pvrusb2/pvrusb2-context.h index 127ec53e0913..6fb6ab022851 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-context.h +++ b/drivers/media/video/pvrusb2/pvrusb2-context.h | |||
@@ -40,14 +40,17 @@ struct pvr2_context_stream { | |||
40 | struct pvr2_context { | 40 | struct pvr2_context { |
41 | struct pvr2_channel *mc_first; | 41 | struct pvr2_channel *mc_first; |
42 | struct pvr2_channel *mc_last; | 42 | struct pvr2_channel *mc_last; |
43 | struct pvr2_context *exist_next; | ||
44 | struct pvr2_context *exist_prev; | ||
45 | struct pvr2_context *notify_next; | ||
46 | struct pvr2_context *notify_prev; | ||
43 | struct pvr2_hdw *hdw; | 47 | struct pvr2_hdw *hdw; |
44 | struct pvr2_context_stream video_stream; | 48 | struct pvr2_context_stream video_stream; |
45 | struct mutex mutex; | 49 | struct mutex mutex; |
46 | int notify_flag; | 50 | int notify_flag; |
51 | int initialized_flag; | ||
47 | int disconnect_flag; | 52 | int disconnect_flag; |
48 | 53 | ||
49 | wait_queue_head_t wait_data; | ||
50 | |||
51 | /* Called after pvr2_context initialization is complete */ | 54 | /* Called after pvr2_context initialization is complete */ |
52 | void (*setup_func)(struct pvr2_context *); | 55 | void (*setup_func)(struct pvr2_context *); |
53 | 56 | ||
@@ -74,6 +77,8 @@ int pvr2_channel_claim_stream(struct pvr2_channel *, | |||
74 | struct pvr2_ioread *pvr2_channel_create_mpeg_stream( | 77 | struct pvr2_ioread *pvr2_channel_create_mpeg_stream( |
75 | struct pvr2_context_stream *); | 78 | struct pvr2_context_stream *); |
76 | 79 | ||
80 | int pvr2_context_global_init(void); | ||
81 | void pvr2_context_global_done(void); | ||
77 | 82 | ||
78 | #endif /* __PVRUSB2_CONTEXT_H */ | 83 | #endif /* __PVRUSB2_CONTEXT_H */ |
79 | /* | 84 | /* |