@@ -190,44 +190,62 @@ class KernelNotifications : public kernel::Notifications
190
190
{
191
191
}
192
192
193
+ ~KernelNotifications ()
194
+ {
195
+ if (m_cbs.user_data && m_cbs.user_data_destroy ) {
196
+ m_cbs.user_data_destroy (m_cbs.user_data );
197
+ }
198
+ m_cbs.user_data_destroy = nullptr ;
199
+ m_cbs.user_data = nullptr ;
200
+ }
201
+
193
202
kernel::InterruptResult blockTip (SynchronizationState state, CBlockIndex& index, double verification_progress) override
194
203
{
195
- if (m_cbs.block_tip ) m_cbs.block_tip (( void *) m_cbs.user_data , cast_state (state), new btck_BlockTreeEntry{&index}, verification_progress);
204
+ if (m_cbs.block_tip ) m_cbs.block_tip (m_cbs.user_data , cast_state (state), new btck_BlockTreeEntry{&index}, verification_progress);
196
205
return {};
197
206
}
198
207
void headerTip (SynchronizationState state, int64_t height, int64_t timestamp, bool presync) override
199
208
{
200
- if (m_cbs.header_tip ) m_cbs.header_tip (( void *) m_cbs.user_data , cast_state (state), height, timestamp, presync ? 1 : 0 );
209
+ if (m_cbs.header_tip ) m_cbs.header_tip (m_cbs.user_data , cast_state (state), height, timestamp, presync ? 1 : 0 );
201
210
}
202
211
void progress (const bilingual_str& title, int progress_percent, bool resume_possible) override
203
212
{
204
- if (m_cbs.progress ) m_cbs.progress (( void *) m_cbs.user_data , title.original .c_str (), title.original .length (), progress_percent, resume_possible ? 1 : 0 );
213
+ if (m_cbs.progress ) m_cbs.progress (m_cbs.user_data , title.original .c_str (), title.original .length (), progress_percent, resume_possible ? 1 : 0 );
205
214
}
206
215
void warningSet (kernel::Warning id, const bilingual_str& message) override
207
216
{
208
- if (m_cbs.warning_set ) m_cbs.warning_set (( void *) m_cbs.user_data , cast_btck_warning (id), message.original .c_str (), message.original .length ());
217
+ if (m_cbs.warning_set ) m_cbs.warning_set (m_cbs.user_data , cast_btck_warning (id), message.original .c_str (), message.original .length ());
209
218
}
210
219
void warningUnset (kernel::Warning id) override
211
220
{
212
- if (m_cbs.warning_unset ) m_cbs.warning_unset (( void *) m_cbs.user_data , cast_btck_warning (id));
221
+ if (m_cbs.warning_unset ) m_cbs.warning_unset (m_cbs.user_data , cast_btck_warning (id));
213
222
}
214
223
void flushError (const bilingual_str& message) override
215
224
{
216
- if (m_cbs.flush_error ) m_cbs.flush_error (( void *) m_cbs.user_data , message.original .c_str (), message.original .length ());
225
+ if (m_cbs.flush_error ) m_cbs.flush_error (m_cbs.user_data , message.original .c_str (), message.original .length ());
217
226
}
218
227
void fatalError (const bilingual_str& message) override
219
228
{
220
- if (m_cbs.fatal_error ) m_cbs.fatal_error (( void *) m_cbs.user_data , message.original .c_str (), message.original .length ());
229
+ if (m_cbs.fatal_error ) m_cbs.fatal_error (m_cbs.user_data , message.original .c_str (), message.original .length ());
221
230
}
222
231
};
223
232
224
233
class KernelValidationInterface final : public CValidationInterface
225
234
{
226
235
public:
227
- const btck_ValidationInterfaceCallbacks m_cbs;
236
+ btck_ValidationInterfaceCallbacks m_cbs;
228
237
229
238
explicit KernelValidationInterface (const btck_ValidationInterfaceCallbacks vi_cbs) : m_cbs{vi_cbs} {}
230
239
240
+ ~KernelValidationInterface ()
241
+ {
242
+ if (m_cbs.user_data && m_cbs.user_data_destroy ) {
243
+ m_cbs.user_data_destroy (m_cbs.user_data );
244
+ }
245
+ m_cbs.user_data = nullptr ;
246
+ m_cbs.user_data_destroy = nullptr ;
247
+ }
248
+
231
249
protected:
232
250
void BlockChecked (const CBlock& block, const BlockValidationState& stateIn) override
233
251
{
@@ -242,24 +260,24 @@ class KernelValidationInterface final : public CValidationInterface
242
260
struct ContextOptions {
243
261
mutable Mutex m_mutex;
244
262
std::unique_ptr<const CChainParams> m_chainparams GUARDED_BY (m_mutex);
245
- std::unique_ptr< const KernelNotifications> m_notifications GUARDED_BY (m_mutex);
246
- std::unique_ptr< const KernelValidationInterface> m_validation_interface GUARDED_BY (m_mutex);
263
+ std::shared_ptr< KernelNotifications> m_notifications GUARDED_BY (m_mutex);
264
+ std::shared_ptr< KernelValidationInterface> m_validation_interface GUARDED_BY (m_mutex);
247
265
};
248
266
249
267
class Context
250
268
{
251
269
public:
252
270
std::unique_ptr<kernel::Context> m_context;
253
271
254
- std::unique_ptr <KernelNotifications> m_notifications;
272
+ std::shared_ptr <KernelNotifications> m_notifications;
255
273
256
274
std::unique_ptr<util::SignalInterrupt> m_interrupt;
257
275
258
276
std::unique_ptr<ValidationSignals> m_signals;
259
277
260
278
std::unique_ptr<const CChainParams> m_chainparams;
261
279
262
- std::unique_ptr <KernelValidationInterface> m_validation_interface;
280
+ std::shared_ptr <KernelValidationInterface> m_validation_interface;
263
281
264
282
Context (const ContextOptions* options, bool & sane)
265
283
: m_context{std::make_unique<kernel::Context>()},
@@ -272,20 +290,20 @@ class Context
272
290
m_chainparams = std::make_unique<const CChainParams>(*options->m_chainparams );
273
291
}
274
292
if (options->m_notifications ) {
275
- m_notifications = std::make_unique<KernelNotifications>(* options->m_notifications ) ;
293
+ m_notifications = options->m_notifications ;
276
294
}
277
295
if (options->m_validation_interface ) {
278
- m_validation_interface = std::make_unique<KernelValidationInterface>(* options->m_validation_interface ) ;
279
- m_signals->RegisterValidationInterface (m_validation_interface. get () );
296
+ m_validation_interface = options->m_validation_interface ;
297
+ m_signals->RegisterSharedValidationInterface (m_validation_interface);
280
298
}
281
299
}
282
300
283
301
if (!m_chainparams) {
284
302
m_chainparams = CChainParams::Main ();
285
303
}
286
304
if (!m_notifications) {
287
- m_notifications = std::make_unique <KernelNotifications>(btck_NotificationInterfaceCallbacks{
288
- nullptr , nullptr , nullptr , nullptr , nullptr , nullptr , nullptr , nullptr });
305
+ m_notifications = std::make_shared <KernelNotifications>(btck_NotificationInterfaceCallbacks{
306
+ nullptr , nullptr , nullptr , nullptr , nullptr , nullptr , nullptr , nullptr , nullptr });
289
307
}
290
308
291
309
if (!kernel::SanityChecks (*m_context)) {
@@ -295,7 +313,7 @@ class Context
295
313
296
314
~Context ()
297
315
{
298
- m_signals->UnregisterValidationInterface (m_validation_interface. get () );
316
+ m_signals->UnregisterSharedValidationInterface (m_validation_interface);
299
317
}
300
318
};
301
319
@@ -357,6 +375,15 @@ struct btck_ScriptPubkey {
357
375
358
376
struct btck_LoggingConnection {
359
377
std::unique_ptr<std::list<std::function<void (const std::string&)>>::iterator> m_connection;
378
+ void * user_data;
379
+ std::function<void (void * user_data)> m_deleter;
380
+
381
+ ~btck_LoggingConnection ()
382
+ {
383
+ if (user_data && m_deleter) {
384
+ m_deleter (user_data);
385
+ }
386
+ }
360
387
};
361
388
362
389
struct btck_ContextOptions {
@@ -585,7 +612,8 @@ void btck_logging_disable()
585
612
}
586
613
587
614
btck_LoggingConnection* btck_logging_connection_create (btck_LogCallback callback,
588
- const void * user_data,
615
+ void * user_data,
616
+ btck_DestroyCallback user_data_destroy_callback,
589
617
const btck_LoggingOptions options)
590
618
{
591
619
LogInstance ().m_log_timestamps = options.log_timestamps ;
@@ -601,17 +629,19 @@ btck_LoggingConnection* btck_logging_connection_create(btck_LogCallback callback
601
629
if (LogInstance ().NumConnections () == 1 && !LogInstance ().StartLogging ()) {
602
630
LogError (" Logger start failed." );
603
631
LogInstance ().DeleteCallback (connection);
632
+ user_data_destroy_callback (user_data);
604
633
return nullptr ;
605
634
}
606
635
} catch (std::exception& e) {
607
636
LogError (" Logger start failed: %s" , e.what ());
608
637
LogInstance ().DeleteCallback (connection);
638
+ user_data_destroy_callback (user_data);
609
639
return nullptr ;
610
640
}
611
641
612
642
LogDebug (BCLog::KERNEL, " Logger connected." );
613
643
614
- return new btck_LoggingConnection{std::make_unique<std::list<std::function<void (const std::string&)>>::iterator>(connection)};
644
+ return new btck_LoggingConnection{std::make_unique<std::list<std::function<void (const std::string&)>>::iterator>(connection), user_data, user_data_destroy_callback };
615
645
}
616
646
617
647
void btck_logging_connection_destroy (btck_LoggingConnection* connection)
@@ -677,13 +707,13 @@ void btck_context_options_set_notifications(btck_ContextOptions* options, btck_N
677
707
{
678
708
// The KernelNotifications are copy-initialized, so the caller can free them again.
679
709
LOCK (options->m_opts ->m_mutex );
680
- options->m_opts ->m_notifications = std::make_unique< const KernelNotifications>(notifications);
710
+ options->m_opts ->m_notifications = std::make_shared< KernelNotifications>(notifications);
681
711
}
682
712
683
713
void btck_context_options_set_validation_interface (btck_ContextOptions* options, btck_ValidationInterfaceCallbacks vi_cbs)
684
714
{
685
715
LOCK (options->m_opts ->m_mutex );
686
- options->m_opts ->m_validation_interface = std::make_unique <KernelValidationInterface>(KernelValidationInterface ( vi_cbs) );
716
+ options->m_opts ->m_validation_interface = std::make_shared <KernelValidationInterface>(vi_cbs);
687
717
}
688
718
689
719
void btck_context_options_destroy (btck_ContextOptions* options)
@@ -1155,17 +1185,6 @@ btck_BlockTreeEntry* btck_chain_get_by_height(const btck_Chain* chain, int heigh
1155
1185
return new btck_BlockTreeEntry{(*chain->m_chain )[height]};
1156
1186
}
1157
1187
1158
- btck_BlockTreeEntry* btck_chain_get_next_block_tree_entry (const btck_Chain* chain, const btck_BlockTreeEntry* entry)
1159
- {
1160
- auto next_block_index{chain->m_chain ->Next (entry->m_block_index )};
1161
-
1162
- if (!next_block_index) {
1163
- LogTrace (BCLog::KERNEL, " The block index is the tip of the current chain, it does not have a next." );
1164
- }
1165
-
1166
- return new btck_BlockTreeEntry{next_block_index};
1167
- }
1168
-
1169
1188
int btck_chain_contains (const btck_Chain* chain, const btck_BlockTreeEntry* entry)
1170
1189
{
1171
1190
LOCK (::cs_main);
0 commit comments