fb-cpp 0.0.2
A modern C++ wrapper for the Firebird database API
Loading...
Searching...
No Matches
EventListener.h
1/*
2 * MIT License
3 *
4 * Copyright (c) 2025 Adriano dos Santos Fernandes
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in all
13 * copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
24#ifndef FBCPP_EVENT_LISTENER_H
25#define FBCPP_EVENT_LISTENER_H
26
27#include "Attachment.h"
28#include "Client.h"
29#include "Exception.h"
30#include "fb-cpp-export.h"
31#include "SmartPtrs.h"
32#include "fb-api.h"
33#include <condition_variable>
34#include <cstdint>
35#include <deque>
36#include <functional>
37#include <mutex>
38#include <string>
39#include <thread>
40#include <vector>
41
42
46namespace fbcpp
47{
51 struct EventCount final
52 {
56 std::string name;
57
61 unsigned count;
62 };
63
67 class FB_CPP_EXPORT EventListener final
68 {
69 public:
73 using Callback = std::function<void(const std::vector<EventCount>& counts)>;
74
75 private:
76 class FirebirdCallback final : public fb::IEventCallbackImpl<FirebirdCallback, impl::StatusWrapper>
77 {
78 public:
79 explicit FirebirdCallback(EventListener& owner) noexcept
80 : owner{&owner}
81 {
82 }
83
84 void eventCallbackFunction(unsigned length, const std::uint8_t* events) override
85 {
86 if (owner)
87 owner->handleEvent(length, events);
88 }
89
90 void addRef() override
91 {
92 // The listener owns this callback for its whole lifetime.
93 }
94
95 int release() override
96 {
97 // Prevent Firebird from attempting to destroy the stack-allocated callback.
98 return 1;
99 }
100
101 void detach() noexcept
102 {
103 owner = nullptr;
104 }
105
106 private:
107 EventListener* owner;
108 };
109
110 public:
114 explicit EventListener(Attachment& attachment, const std::vector<std::string>& eventNames, Callback callback);
115
119 ~EventListener() noexcept
120 {
121 try
122 {
123 stop();
124 }
125 catch (...)
126 {
127 // swallow
128 }
129 }
130
131 EventListener(const EventListener&) = delete;
132 EventListener& operator=(const EventListener&) = delete;
133
134 EventListener(EventListener&&) = delete;
135 EventListener& operator=(EventListener&&) = delete;
136
137 public:
141 bool isListening() noexcept;
142
146 void stop();
147
148 private:
149 void handleEvent(unsigned length, const std::uint8_t* events);
150 void dispatchLoop();
151 void cancelEventsHandle();
152 void decodeEventCounts();
153
154 private:
155 Attachment& attachment;
156 Client& client;
157 std::vector<std::string> eventNames;
158 Callback callback;
159 FbRef<fb::IEvents> eventsHandle;
160 FirebirdCallback firebirdCallback;
161 std::vector<std::uint8_t> eventBuffer;
162 std::vector<std::uint8_t> resultBuffer;
163 std::vector<std::uint32_t> rawCounts;
164 std::vector<unsigned> countOffsets;
165 std::deque<std::vector<EventCount>> pendingNotifications;
166 std::thread dispatcher;
167 std::mutex mutex;
168 std::condition_variable condition;
169 bool listening = false;
170 bool running = false;
171 bool first = false;
172 };
173} // namespace fbcpp
174
175
176#endif // FBCPP_EVENT_LISTENER_H
Represents a connection to a Firebird database.
Definition Attachment.h:219
Represents a Firebird client library instance.
Definition Client.h:54
Observes Firebird events and forwards aggregated counts to a callback on a background thread.
~EventListener() noexcept
Stops the listener and waits for any background work to finish.
std::function< void(const std::vector< EventCount > &counts)> Callback
Function invoked when new event counts are available.
Reference-counted smart pointer for Firebird objects using addRef/release semantics.
Definition SmartPtrs.h:70
fb-cpp namespace.
Definition Attachment.h:46
Represents the number of occurrences for a registered event delivered by Firebird.
std::string name
Name of the event reported by the database.
unsigned count
Number of times the event fired since the last notification.