WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
Bug 150888
[GStreamer] Do not use GThreadSafeMainLoopSource to send notifications to the main thread in MediaPlayerPrivateGStreamer
https://bugs.webkit.org/show_bug.cgi?id=150888
Summary
[GStreamer] Do not use GThreadSafeMainLoopSource to send notifications to the...
Carlos Garcia Campos
Reported
2015-11-04 02:58:22 PST
Analyzing how the main loop sources were used in GST code I've noticed that in most of the cases they are used to send notifications to the main thread. The way it works in those cases is that some state is updated in whatever thread and we notify the main thread to use the new state. There's no data passed to the main thread, they are just notifications. I've also noticed that we are not doing this exactly as expected in several of those cases. GThreadSafeMainLoopSource cancels the current source when a new one is scheduled, and that was done this way because previous code in GST using GSources directly did it that way. But that's not what we want, if there's a notification pending, since the state is updated, we can just wait for it to happen instead of cancelling and scheduling a new one. I've also noticed that in most of the cases where we schedule notifications to the main thread, we can be already in the main thread, so we could avoid the schedule entirely.
Attachments
Patch
(29.75 KB, patch)
2015-11-04 03:09 PST
,
Carlos Garcia Campos
no flags
Details
Formatted Diff
Diff
Updated patch
(29.50 KB, patch)
2015-11-06 03:32 PST
,
Carlos Garcia Campos
zan
: review+
Details
Formatted Diff
Diff
Show Obsolete
(1)
View All
Add attachment
proposed patch, testcase, etc.
Carlos Garcia Campos
Comment 1
2015-11-04 03:09:05 PST
Created
attachment 264786
[details]
Patch We can use RunLoop::dispatch() to send notifications to the main thread, but there's no way to cancel those tasks. This patch adds a new helper class MainThreadNotifier that uses an enum of flags to handle different kind of notifications. It uses RunLoop::dispatch() to send notifications to the main thread, but only if there isn't one pending for the given type.
WebKit Commit Bot
Comment 2
2015-11-04 03:10:47 PST
Attachment 264786
[details]
did not pass style-queue: ERROR: Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:326: More than one command on the same line [whitespace/newline] [4] ERROR: Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:378: More than one command on the same line [whitespace/newline] [4] ERROR: Source/WebCore/platform/graphics/gstreamer/MainThreadNotifier.h:36: Extra space before ( in function call [whitespace/parens] [4] ERROR: Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:615: More than one command on the same line [whitespace/newline] [4] ERROR: Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:660: More than one command on the same line [whitespace/newline] [4] ERROR: Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:674: More than one command on the same line [whitespace/newline] [4] ERROR: Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:720: More than one command on the same line [whitespace/newline] [4] Total errors found: 7 in 6 files If any of these errors are false positives, please file a bug against check-webkit-style.
Zan Dobersek
Comment 3
2015-11-05 03:02:21 PST
Comment on
attachment 264786
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=264786&action=review
Again, please have Phil review the patch as well.
> Source/WebCore/platform/graphics/gstreamer/MainThreadNotifier.h:29 > +template <typename T> > +class MainThreadNotifier {
Neat implementation.
> Source/WebCore/platform/graphics/gstreamer/MainThreadNotifier.h:46 > + if (!weakThis) > + return; > + if (weakThis->removePendingNotitifation(notificationType)) > + callback();
Can this be a two-liner?
> if (weakThis && weakThis->removePendingNotification(notificationType)) > callback();
> Source/WebCore/platform/graphics/gstreamer/MainThreadNotifier.h:61 > + bool addPendingNotitifation(T notificationType)
Typo: notitifation.
> Source/WebCore/platform/graphics/gstreamer/MainThreadNotifier.h:70 > + bool removePendingNotitifation(T notificationType)
Ditto re: typo.
> Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:615 > + if (isMainThread()) > + player->notifyPlayerOfVideo(); > + else > + player->m_notifier.notify(MainThreadNotification::VideoChanged, [player] { player->notifyPlayerOfVideo(); });
This isMainThread() check and the conditional immediate execution could be rolled up into the notifier class. Would save some lines. MainThreadNotifier::notify() would accept a templated functor as the second parameter, invoke it immediately if on the main thread, or wrap it in std::function<> and dispatch it onto the main thread via RunLoop otherwise.
Carlos Garcia Campos
Comment 4
2015-11-05 04:19:47 PST
(In reply to
comment #3
)
> Comment on
attachment 264786
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=264786&action=review
> > Again, please have Phil review the patch as well.
Sure.
> > Source/WebCore/platform/graphics/gstreamer/MainThreadNotifier.h:29 > > +template <typename T> > > +class MainThreadNotifier { > > Neat implementation.
:-)
> > Source/WebCore/platform/graphics/gstreamer/MainThreadNotifier.h:46 > > + if (!weakThis) > > + return; > > + if (weakThis->removePendingNotitifation(notificationType)) > > + callback(); > > Can this be a two-liner?
Sure.
> > if (weakThis && weakThis->removePendingNotification(notificationType)) > > callback(); > > > Source/WebCore/platform/graphics/gstreamer/MainThreadNotifier.h:61 > > + bool addPendingNotitifation(T notificationType) > > Typo: notitifation.
Oops
> > Source/WebCore/platform/graphics/gstreamer/MainThreadNotifier.h:70 > > + bool removePendingNotitifation(T notificationType) > > Ditto re: typo. > > > Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:615 > > + if (isMainThread()) > > + player->notifyPlayerOfVideo(); > > + else > > + player->m_notifier.notify(MainThreadNotification::VideoChanged, [player] { player->notifyPlayerOfVideo(); }); > > This isMainThread() check and the conditional immediate execution could be > rolled up into the notifier class. Would save some lines. > > MainThreadNotifier::notify() would accept a templated functor as the second > parameter, invoke it immediately if on the main thread, or wrap it in > std::function<> and dispatch it onto the main thread via RunLoop otherwise.
I thought about that, but decided to do it in callers to avoid the function creation just to invoke a member method. But I'm not sure if creating the function would have any real impact in the end, what do you think?
Zan Dobersek
Comment 5
2015-11-06 00:55:45 PST
(In reply to
comment #4
)
> (In reply to
comment #3
) > > > Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:615 > > > + if (isMainThread()) > > > + player->notifyPlayerOfVideo(); > > > + else > > > + player->m_notifier.notify(MainThreadNotification::VideoChanged, [player] { player->notifyPlayerOfVideo(); }); > > > > This isMainThread() check and the conditional immediate execution could be > > rolled up into the notifier class. Would save some lines. > > > > MainThreadNotifier::notify() would accept a templated functor as the second > > parameter, invoke it immediately if on the main thread, or wrap it in > > std::function<> and dispatch it onto the main thread via RunLoop otherwise. > > I thought about that, but decided to do it in callers to avoid the function > creation just to invoke a member method. But I'm not sure if creating the > function would have any real impact in the end, what do you think?
You wouldn't create a std::function<> object until you know you're not on the main thread and have to use the RunLoop dispatch instead. template<typename F> void notify(T notificationType, const F& callbackFunctor) { if (!addPendingNotitifation(notificationType)) return; if (!isMainThread()) { auto weakThis = m_weakPtrFactory.createWeakPtr(); std::function<void ()> callback(callbackFunctor); RunLoop::main().dispatch([weakThis, notificationType, callback] { if (weakThis && weakThis->removePendingNotitifation(notificationType)) callback(); }); } else callbackFunctor(); }
Carlos Garcia Campos
Comment 6
2015-11-06 03:32:18 PST
Created
attachment 264932
[details]
Updated patch
WebKit Commit Bot
Comment 7
2015-11-06 03:33:50 PST
Attachment 264932
[details]
did not pass style-queue: ERROR: Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:323: More than one command on the same line [whitespace/newline] [4] ERROR: Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:372: More than one command on the same line [whitespace/newline] [4] ERROR: Source/WebCore/platform/graphics/gstreamer/MainThreadNotifier.h:50: Extra space before ( in function call [whitespace/parens] [4] ERROR: Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:612: More than one command on the same line [whitespace/newline] [4] ERROR: Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:654: More than one command on the same line [whitespace/newline] [4] ERROR: Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:665: More than one command on the same line [whitespace/newline] [4] ERROR: Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:708: More than one command on the same line [whitespace/newline] [4] Total errors found: 7 in 6 files If any of these errors are false positives, please file a bug against check-webkit-style.
Zan Dobersek
Comment 8
2015-11-06 04:12:25 PST
Comment on
attachment 264932
[details]
Updated patch View in context:
https://bugs.webkit.org/attachment.cgi?id=264932&action=review
r=me if Phil doesn't object.
> Source/WebCore/ChangeLog:38 > + (WebCore::MainThreadNotifier::addPendingNotitifation): > + (WebCore::MainThreadNotifier::removePendingNotitifation):
Update this.
Carlos Garcia Campos
Comment 9
2015-11-06 04:57:04 PST
Committed
r192099
: <
http://trac.webkit.org/changeset/192099
>
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug