summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-11-14 03:16:30 +0100
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-11-15 10:49:41 +0100
commit2d6416324ca2dd1b8c885460e9f3944ba78e156e (patch)
tree3f4bbb724b4cd7e09e94f1fc81dbfe1974920791
parent619164a994c8d878249d6c1b8b16c27074a04209 (diff)
events: Safeguard against event deletion in event callbacks
Events callback can call events_unwatch_fd(), resulting in the event being deleted from the events list. Use list_for_each_entry_safe() to walk the list properly, and make sure the event isn't accessed after it's callback function returns. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-rw-r--r--events.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/events.c b/events.c
index 15d9535..4fb395c 100644
--- a/events.c
+++ b/events.c
@@ -115,16 +115,17 @@ static void events_dispatch(struct events *events, const fd_set *rfds,
const fd_set *wfds, const fd_set *efds)
{
struct event_fd *event;
+ struct event_fd *next;
- list_for_each_entry(event, &events->events, list) {
+ list_for_each_entry_safe(event, next, &events->events, list) {
if (event->type == OMAP3_ISP_EVENT_READ &&
FD_ISSET(event->fd, rfds))
event->callback(event->priv);
- if (event->type == OMAP3_ISP_EVENT_WRITE &&
- FD_ISSET(event->fd, wfds))
+ else if (event->type == OMAP3_ISP_EVENT_WRITE &&
+ FD_ISSET(event->fd, wfds))
event->callback(event->priv);
- if (event->type == OMAP3_ISP_EVENT_EXCEPTION &&
- FD_ISSET(event->fd, efds))
+ else if (event->type == OMAP3_ISP_EVENT_EXCEPTION &&
+ FD_ISSET(event->fd, efds))
event->callback(event->priv);
/* If the callback stopped events processing, we're done. */