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;
34class MdnsManager;
35PROMEKI_NAMESPACE_END
36
37PROMEKI_NAMESPACE_BEGIN
38
71class Application {
72 public:
82 Application(int argc, char **argv);
83
85 ~Application();
86
87 Application(const Application &) = delete;
88 Application(Application &&) = delete;
89 Application &operator=(const Application &) = delete;
90 Application &operator=(Application &&) = delete;
91
97 static const StringList &arguments();
98
103 static const UUID &appUUID();
104
109 static void setAppUUID(const UUID &uuid);
110
128 static int64_t pid();
129
134 static const String &appName();
135
140 static void setAppName(const String &name);
141
146 static Thread *mainThread();
147
153 static EventLoop *mainEventLoop();
154
164 static IODevice *stdinDevice();
165
175 static IODevice *stdoutDevice();
176
186 static IODevice *stderrDevice();
187
204 static void installSignalHandlers();
205
215 static void uninstallSignalHandlers();
216
225 static bool areSignalHandlersInstalled();
226
238 static void installCrashHandler();
239
248 static void uninstallCrashHandler();
249
258 static bool isCrashHandlerInstalled();
259
294 static void refreshCrashHandler();
295
309 static void writeTrace(const char *reason = nullptr);
310
329 static void quit(int exitCode = 0);
330
340 using QuitRequestHandler = Function<bool(int exitCode)>;
341
362 static void setQuitRequestHandler(QuitRequestHandler handler);
363
368 static bool shouldQuit();
369
374 static int exitCode();
375
387 static const char *DebugServerEnv;
388
406 static Error startDebugServer(const SocketAddress &address);
407
415 static Error startDebugServer(uint16_t port);
416
426 static void stopDebugServer();
427
435 static DebugServer *debugServer();
436
460 static Error startCpuMonitor(const Duration &interval);
461
471 static void stopCpuMonitor();
472
481 static CpuMonitor *cpuMonitor();
482
519 static MdnsManager *mdnsManager();
520
536 static void stopMdnsManager();
537
572 static Error startEventLoopMonitors(const Duration &interval,
573 EventLoop::ReportFunction fn = {});
574
588 static void stopEventLoopMonitors();
589
594 static bool eventLoopMonitorsEnabled();
595
612 static void installEventLoopMonitorIfEnabled(EventLoop *loop);
613
629 int exec();
630
631 private:
632 struct Data {
633 StringList arguments;
634 UUID appUUID;
635 String appName;
636 Thread *mainThread = nullptr;
637 // Atomic so the signal-watcher thread
638 // can latch a quit request while the
639 // main thread is polling
640 // @ref Application::shouldQuit.
641 Atomic<int> exitCode{0};
642 Atomic<bool> shouldQuit{false};
643 QuitRequestHandler quitHandler;
644 UniquePtr<DebugServer> debugServer;
645 UniquePtr<CpuMonitor> cpuMonitor;
646 UniquePtr<MdnsManager> mdnsManager;
647
648 // Auto-install hook for new
649 // EventLoops. Guarded by
650 // elMonitorMutex because
651 // ReportFunction is std::function
652 // and not safe to read across
653 // threads without a barrier; we
654 // copy the trio under the lock at
655 // every read site so the global
656 // mutex is never held while
657 // installMonitor (which takes its
658 // own mutex) runs.
659 bool elMonitorEnabled = false;
660 Duration elMonitorInterval;
661 EventLoop::ReportFunction elMonitorFn;
662 mutable Mutex elMonitorMutex;
663 };
664 static Data &data();
665
666 static void maybeStartDebugServerFromEnv();
667
668 // The main-thread EventLoop. Constructed as a member
669 // of Application so subsystems installed on the stack
670 // immediately after `Application app(argc, argv);`
671 // have a ready-made loop to register their I/O
672 // sources on. Declared after the static data accessor
673 // so it participates in member init order.
674 EventLoop _eventLoop;
675};
676
677PROMEKI_NAMESPACE_END
678
679#endif // PROMEKI_ENABLE_CORE