libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
application.h
Go to the documentation of this file.
1
9#pragma once
10
11
12#include <promeki/config.h>
13#if PROMEKI_ENABLE_CORE
14#include <functional>
15
16#include <promeki/function.h>
17#include <promeki/namespace.h>
18#include <promeki/atomic.h>
19#include <promeki/duration.h>
20#include <promeki/eventloop.h>
21#include <promeki/error.h>
22#include <promeki/mutex.h>
23#include <promeki/string.h>
24#include <promeki/stringlist.h>
25#include <promeki/uniqueptr.h>
26#include <promeki/uuid.h>
27
28PROMEKI_NAMESPACE_BEGIN
29class Thread;
30class IODevice;
31class DebugServer;
32class SocketAddress;
33class CpuMonitor;
34PROMEKI_NAMESPACE_END
35
36PROMEKI_NAMESPACE_BEGIN
37
70class Application {
71 public:
81 Application(int argc, char **argv);
82
84 ~Application();
85
86 Application(const Application &) = delete;
87 Application(Application &&) = delete;
88 Application &operator=(const Application &) = delete;
89 Application &operator=(Application &&) = delete;
90
96 static const StringList &arguments();
97
102 static const UUID &appUUID();
103
108 static void setAppUUID(const UUID &uuid);
109
127 static int64_t pid();
128
133 static const String &appName();
134
139 static void setAppName(const String &name);
140
145 static Thread *mainThread();
146
152 static EventLoop *mainEventLoop();
153
163 static IODevice *stdinDevice();
164
174 static IODevice *stdoutDevice();
175
185 static IODevice *stderrDevice();
186
203 static void installSignalHandlers();
204
214 static void uninstallSignalHandlers();
215
224 static bool areSignalHandlersInstalled();
225
237 static void installCrashHandler();
238
247 static void uninstallCrashHandler();
248
257 static bool isCrashHandlerInstalled();
258
293 static void refreshCrashHandler();
294
308 static void writeTrace(const char *reason = nullptr);
309
328 static void quit(int exitCode = 0);
329
339 using QuitRequestHandler = Function<bool(int exitCode)>;
340
361 static void setQuitRequestHandler(QuitRequestHandler handler);
362
367 static bool shouldQuit();
368
373 static int exitCode();
374
386 static const char *DebugServerEnv;
387
405 static Error startDebugServer(const SocketAddress &address);
406
414 static Error startDebugServer(uint16_t port);
415
425 static void stopDebugServer();
426
434 static DebugServer *debugServer();
435
459 static Error startCpuMonitor(const Duration &interval);
460
470 static void stopCpuMonitor();
471
480 static CpuMonitor *cpuMonitor();
481
516 static Error startEventLoopMonitors(const Duration &interval,
517 EventLoop::ReportFunction fn = {});
518
532 static void stopEventLoopMonitors();
533
538 static bool eventLoopMonitorsEnabled();
539
556 static void installEventLoopMonitorIfEnabled(EventLoop *loop);
557
573 int exec();
574
575 private:
576 struct Data {
577 StringList arguments;
578 UUID appUUID;
579 String appName;
580 Thread *mainThread = nullptr;
581 // Atomic so the signal-watcher thread
582 // can latch a quit request while the
583 // main thread is polling
584 // @ref Application::shouldQuit.
585 Atomic<int> exitCode{0};
586 Atomic<bool> shouldQuit{false};
587 QuitRequestHandler quitHandler;
588 UniquePtr<DebugServer> debugServer;
589 UniquePtr<CpuMonitor> cpuMonitor;
590
591 // Auto-install hook for new
592 // EventLoops. Guarded by
593 // elMonitorMutex because
594 // ReportFunction is std::function
595 // and not safe to read across
596 // threads without a barrier; we
597 // copy the trio under the lock at
598 // every read site so the global
599 // mutex is never held while
600 // installMonitor (which takes its
601 // own mutex) runs.
602 bool elMonitorEnabled = false;
603 Duration elMonitorInterval;
604 EventLoop::ReportFunction elMonitorFn;
605 mutable Mutex elMonitorMutex;
606 };
607 static Data &data();
608
609 static void maybeStartDebugServerFromEnv();
610
611 // The main-thread EventLoop. Constructed as a member
612 // of Application so subsystems installed on the stack
613 // immediately after `Application app(argc, argv);`
614 // have a ready-made loop to register their I/O
615 // sources on. Declared after the static data accessor
616 // so it participates in member init order.
617 EventLoop _eventLoop;
618};
619
620PROMEKI_NAMESPACE_END
621
622#endif // PROMEKI_ENABLE_CORE