@@ -190,44 +190,62 @@ class KernelNotifications : public kernel::Notifications
190190 {
191191 }
192192
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+
193202 kernel::InterruptResult blockTip (SynchronizationState state, CBlockIndex& index, double verification_progress) override
194203 {
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);
196205 return {};
197206 }
198207 void headerTip (SynchronizationState state, int64_t height, int64_t timestamp, bool presync) override
199208 {
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 );
201210 }
202211 void progress (const bilingual_str& title, int progress_percent, bool resume_possible) override
203212 {
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 );
205214 }
206215 void warningSet (kernel::Warning id, const bilingual_str& message) override
207216 {
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 ());
209218 }
210219 void warningUnset (kernel::Warning id) override
211220 {
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));
213222 }
214223 void flushError (const bilingual_str& message) override
215224 {
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 ());
217226 }
218227 void fatalError (const bilingual_str& message) override
219228 {
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 ());
221230 }
222231};
223232
224233class KernelValidationInterface final : public CValidationInterface
225234{
226235public:
227- const btck_ValidationInterfaceCallbacks m_cbs;
236+ btck_ValidationInterfaceCallbacks m_cbs;
228237
229238 explicit KernelValidationInterface (const btck_ValidationInterfaceCallbacks vi_cbs) : m_cbs{vi_cbs} {}
230239
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+
231249protected:
232250 void BlockChecked (const CBlock& block, const BlockValidationState& stateIn) override
233251 {
@@ -242,24 +260,24 @@ class KernelValidationInterface final : public CValidationInterface
242260struct ContextOptions {
243261 mutable Mutex m_mutex;
244262 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);
247265};
248266
249267class Context
250268{
251269public:
252270 std::unique_ptr<kernel::Context> m_context;
253271
254- std::unique_ptr <KernelNotifications> m_notifications;
272+ std::shared_ptr <KernelNotifications> m_notifications;
255273
256274 std::unique_ptr<util::SignalInterrupt> m_interrupt;
257275
258276 std::unique_ptr<ValidationSignals> m_signals;
259277
260278 std::unique_ptr<const CChainParams> m_chainparams;
261279
262- std::unique_ptr <KernelValidationInterface> m_validation_interface;
280+ std::shared_ptr <KernelValidationInterface> m_validation_interface;
263281
264282 Context (const ContextOptions* options, bool & sane)
265283 : m_context{std::make_unique<kernel::Context>()},
@@ -272,20 +290,20 @@ class Context
272290 m_chainparams = std::make_unique<const CChainParams>(*options->m_chainparams );
273291 }
274292 if (options->m_notifications ) {
275- m_notifications = std::make_unique<KernelNotifications>(* options->m_notifications ) ;
293+ m_notifications = options->m_notifications ;
276294 }
277295 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);
280298 }
281299 }
282300
283301 if (!m_chainparams) {
284302 m_chainparams = CChainParams::Main ();
285303 }
286304 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 });
289307 }
290308
291309 if (!kernel::SanityChecks (*m_context)) {
@@ -295,7 +313,7 @@ class Context
295313
296314 ~Context ()
297315 {
298- m_signals->UnregisterValidationInterface (m_validation_interface. get () );
316+ m_signals->UnregisterSharedValidationInterface (m_validation_interface);
299317 }
300318};
301319
@@ -357,6 +375,15 @@ struct btck_ScriptPubkey {
357375
358376struct btck_LoggingConnection {
359377 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+ }
360387};
361388
362389struct btck_ContextOptions {
@@ -585,7 +612,8 @@ void btck_logging_disable()
585612}
586613
587614btck_LoggingConnection* btck_logging_connection_create (btck_LogCallback callback,
588- const void * user_data,
615+ void * user_data,
616+ btck_DestroyCallback user_data_destroy_callback,
589617 const btck_LoggingOptions options)
590618{
591619 LogInstance ().m_log_timestamps = options.log_timestamps ;
@@ -601,17 +629,19 @@ btck_LoggingConnection* btck_logging_connection_create(btck_LogCallback callback
601629 if (LogInstance ().NumConnections () == 1 && !LogInstance ().StartLogging ()) {
602630 LogError (" Logger start failed." );
603631 LogInstance ().DeleteCallback (connection);
632+ user_data_destroy_callback (user_data);
604633 return nullptr ;
605634 }
606635 } catch (std::exception& e) {
607636 LogError (" Logger start failed: %s" , e.what ());
608637 LogInstance ().DeleteCallback (connection);
638+ user_data_destroy_callback (user_data);
609639 return nullptr ;
610640 }
611641
612642 LogDebug (BCLog::KERNEL, " Logger connected." );
613643
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 };
615645}
616646
617647void btck_logging_connection_destroy (btck_LoggingConnection* connection)
@@ -677,13 +707,13 @@ void btck_context_options_set_notifications(btck_ContextOptions* options, btck_N
677707{
678708 // The KernelNotifications are copy-initialized, so the caller can free them again.
679709 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);
681711}
682712
683713void btck_context_options_set_validation_interface (btck_ContextOptions* options, btck_ValidationInterfaceCallbacks vi_cbs)
684714{
685715 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);
687717}
688718
689719void btck_context_options_destroy (btck_ContextOptions* options)
@@ -1155,17 +1185,6 @@ btck_BlockTreeEntry* btck_chain_get_by_height(const btck_Chain* chain, int heigh
11551185 return new btck_BlockTreeEntry{(*chain->m_chain )[height]};
11561186}
11571187
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-
11691188int btck_chain_contains (const btck_Chain* chain, const btck_BlockTreeEntry* entry)
11701189{
11711190 LOCK (::cs_main);
0 commit comments