1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 #include "mozilla/WidgetTraceEvent.h"
6 
7 #include <glib.h>
8 #include <mozilla/CondVar.h>
9 #include <mozilla/Mutex.h>
10 #include <stdio.h>
11 
12 using mozilla::CondVar;
13 using mozilla::Mutex;
14 using mozilla::MutexAutoLock;
15 
16 namespace {
17 
18 Mutex* sMutex = nullptr;
19 CondVar* sCondVar = nullptr;
20 bool sTracerProcessed = false;
21 
22 // This function is called from the main (UI) thread.
TracerCallback(gpointer data)23 gboolean TracerCallback(gpointer data) {
24   mozilla::SignalTracerThread();
25   return FALSE;
26 }
27 
28 }  // namespace
29 
30 namespace mozilla {
31 
InitWidgetTracing()32 bool InitWidgetTracing() {
33   sMutex = new Mutex("Event tracer thread mutex");
34   sCondVar = new CondVar(*sMutex, "Event tracer thread condvar");
35   return true;
36 }
37 
CleanUpWidgetTracing()38 void CleanUpWidgetTracing() {
39   delete sMutex;
40   delete sCondVar;
41   sMutex = nullptr;
42   sCondVar = nullptr;
43 }
44 
45 // This function is called from the background tracer thread.
FireAndWaitForTracerEvent()46 bool FireAndWaitForTracerEvent() {
47   MOZ_ASSERT(sMutex && sCondVar, "Tracing not initialized!");
48 
49   // Send a default-priority idle event through the
50   // event loop, and wait for it to finish.
51   MutexAutoLock lock(*sMutex);
52   MOZ_ASSERT(!sTracerProcessed, "Tracer synchronization state is wrong");
53   g_idle_add_full(G_PRIORITY_DEFAULT, TracerCallback, nullptr, nullptr);
54   while (!sTracerProcessed) sCondVar->Wait();
55   sTracerProcessed = false;
56   return true;
57 }
58 
SignalTracerThread()59 void SignalTracerThread() {
60   if (!sMutex || !sCondVar) return;
61   MutexAutoLock lock(*sMutex);
62   if (!sTracerProcessed) {
63     sTracerProcessed = true;
64     sCondVar->Notify();
65   }
66 }
67 
68 }  // namespace mozilla
69