Skip to content

Commit 9a83c4c

Browse files
committed
Merge commit '5fb5615c0ff40e78f896f8ccf10799069c55b2d2'
2 parents d5114cb + 5fb5615 commit 9a83c4c

File tree

5 files changed

+156
-147
lines changed

5 files changed

+156
-147
lines changed

depend/bitcoin/src/bitcoin-chainstate.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,8 @@ int main(int argc, char* argv[])
182182
ChainParams params{ChainType::MAINNET};
183183
options.SetChainParams(params);
184184

185-
TestKernelNotifications notifications{};
186-
options.SetNotifications(notifications);
187-
TestValidationInterface validation_interface{};
188-
options.SetValidationInterface(validation_interface);
185+
options.SetNotifications(std::make_shared<TestKernelNotifications>());
186+
options.SetValidationInterface(std::make_shared<TestValidationInterface>());
189187

190188
Context context{options};
191189

depend/bitcoin/src/kernel/bitcoinkernel.cpp

Lines changed: 52 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -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

224233
class KernelValidationInterface final : public CValidationInterface
225234
{
226235
public:
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+
231249
protected:
232250
void BlockChecked(const CBlock& block, const BlockValidationState& stateIn) override
233251
{
@@ -242,24 +260,24 @@ class KernelValidationInterface final : public CValidationInterface
242260
struct 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

249267
class Context
250268
{
251269
public:
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

358376
struct 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

362389
struct btck_ContextOptions {
@@ -585,7 +612,8 @@ void btck_logging_disable()
585612
}
586613

587614
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,
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

617647
void 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

683713
void 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

689719
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
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-
11691188
int btck_chain_contains(const btck_Chain* chain, const btck_BlockTreeEntry* entry)
11701189
{
11711190
LOCK(::cs_main);

depend/bitcoin/src/kernel/bitcoinkernel.h

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,12 @@ typedef uint8_t btck_Warning;
274274
typedef void (*btck_LogCallback)(void* user_data, const char* message, size_t message_len);
275275

276276
/**
277-
* Function signatures for the kernel notifications.
277+
* Function signature for freeing user data.
278+
*/
279+
typedef void (*btck_DestroyCallback)(void* user_data);
280+
281+
/**
282+
* Function signatures for the kernel notifications.
278283
*/
279284
typedef void (*btck_NotifyBlockTip)(void* user_data, btck_SynchronizationState state, btck_BlockTreeEntry* entry, double verification_progress);
280285
typedef void (*btck_NotifyHeaderTip)(void* user_data, btck_SynchronizationState state, int64_t height, int64_t timestamp, int presync);
@@ -324,8 +329,10 @@ typedef uint32_t btck_BlockValidationResult;
324329
* execution when they are called.
325330
*/
326331
typedef struct {
327-
const void* user_data; //!< Holds a user-defined opaque structure that is passed to the validation
328-
//!< interface callbacks.
332+
void* user_data; //!< Holds a user-defined opaque structure that is passed to the validation
333+
//!< interface callbacks. If user_data_destroy is also defined ownership of the
334+
//!< user_data is passed to the created context options and subsequently context.
335+
btck_DestroyCallback user_data_destroy; //!< Frees the provided user data structure.
329336
btck_ValidationInterfaceBlockChecked block_checked; //!< Called when a new block has been checked. Contains the
330337
//!< result of its validation.
331338
} btck_ValidationInterfaceCallbacks;
@@ -339,14 +346,17 @@ typedef struct {
339346
* safe unwinding.
340347
*/
341348
typedef struct {
342-
const void* user_data; //!< Holds a user-defined opaque structure that is passed to the notification callbacks.
343-
btck_NotifyBlockTip block_tip; //!< The chain's tip was updated to the provided block entry.
344-
btck_NotifyHeaderTip header_tip; //!< A new best block header was added.
345-
btck_NotifyProgress progress; //!< Reports on current block synchronization progress.
346-
btck_NotifyWarningSet warning_set; //!< A warning issued by the kernel library during validation.
347-
btck_NotifyWarningUnset warning_unset; //!< A previous condition leading to the issuance of a warning is no longer given.
348-
btck_NotifyFlushError flush_error; //!< An error encountered when flushing data to disk.
349-
btck_NotifyFatalError fatal_error; //!< A un-recoverable system error encountered by the library.
349+
void* user_data; //!< Holds a user-defined opaque structure that is passed to the notification callbacks.
350+
//!< If user_data_destroy is also defined ownership of the user_data is passed to the
351+
//!< created context options and subsequently context.
352+
btck_DestroyCallback user_data_destroy; //!< Frees the provided user data structure.
353+
btck_NotifyBlockTip block_tip; //!< The chain's tip was updated to the provided block entry.
354+
btck_NotifyHeaderTip header_tip; //!< A new best block header was added.
355+
btck_NotifyProgress progress; //!< Reports on current block synchronization progress.
356+
btck_NotifyWarningSet warning_set; //!< A warning issued by the kernel library during validation.
357+
btck_NotifyWarningUnset warning_unset; //!< A previous condition leading to the issuance of a warning is no longer given.
358+
btck_NotifyFlushError flush_error; //!< An error encountered when flushing data to disk.
359+
btck_NotifyFatalError fatal_error; //!< A un-recoverable system error encountered by the library.
350360
} btck_NotificationInterfaceCallbacks;
351361

352362
/**
@@ -699,15 +709,19 @@ BITCOINKERNEL_API void btck_logging_disable_category(btck_LogCategory category);
699709
* produced before this function is first called are buffered and on calling this
700710
* function are logged immediately.
701711
*
702-
* @param[in] callback Non-null, function through which messages will be logged.
703-
* @param[in] user_data Nullable, holds a user-defined opaque structure. Is passed back
704-
* to the user through the callback.
705-
* @param[in] options Sets formatting options of the log messages.
706-
* @return A new kernel logging connection, or null on error.
712+
* @param[in] log_callback Non-null, function through which messages will be logged.
713+
* @param[in] user_data Nullable, holds a user-defined opaque structure. Is passed back
714+
* to the user through the callback. If the user_data_destroy_callback
715+
* is also defined it is assumed that ownership of the user_data is passed
716+
* to the created logging connection.
717+
* @param[in] user_data_destroy_callback Nullable, function for freeing the user data.
718+
* @param[in] options Sets formatting options of the log messages.
719+
* @return A new kernel logging connection, or null on error.
707720
*/
708721
BITCOINKERNEL_API btck_LoggingConnection* BITCOINKERNEL_WARN_UNUSED_RESULT btck_logging_connection_create(
709-
btck_LogCallback callback,
710-
const void* user_data,
722+
btck_LogCallback log_callback,
723+
void* user_data,
724+
btck_DestroyCallback user_data_destroy_callback,
711725
const btck_LoggingOptions options
712726
) BITCOINKERNEL_ARG_NONNULL(1);
713727

@@ -1214,21 +1228,6 @@ BITCOINKERNEL_API btck_BlockTreeEntry* BITCOINKERNEL_WARN_UNUSED_RESULT btck_cha
12141228
int block_height
12151229
) BITCOINKERNEL_ARG_NONNULL(1);
12161230

1217-
/**
1218-
* @brief Return the next block index in the currently active chain, or null if
1219-
* the current block index is the tip, or is not in the currently active
1220-
* chain.
1221-
*
1222-
* @param[in] chain Non-null.
1223-
* @param[in] block_tree_entry Non-null.
1224-
* @return The next block index in the currently active chain, or null if
1225-
* the block tree entry is the chain tip, or not in the chain.
1226-
*/
1227-
BITCOINKERNEL_API btck_BlockTreeEntry* BITCOINKERNEL_WARN_UNUSED_RESULT btck_chain_get_next_block_tree_entry(
1228-
const btck_Chain* chain,
1229-
const btck_BlockTreeEntry* block_tree_entry
1230-
) BITCOINKERNEL_ARG_NONNULL(1, 2);
1231-
12321231
/**
12331232
* @brief Return true if the passed in chain contains the block tree entry.
12341233
*

0 commit comments

Comments
 (0)