add_index() does not use locking
I'm using chainbase in Chronicle project in concurrent mode: one process opens the database in read-write mode and is constantly updating it as state history data arrives. Then, multiple read-only processes read from the same shared memory.
I define CHAINBASE_CHECK_LOCKING globally.
I get the following error when read-only client opens the database and defines the indexes:
May 25 01:05:46 sthist chronicle-receiver[5523]: warn 2019-05-25T01:05:46.141 chronicle receiver_plugin.cpp:1201 plugin_initialize ] 13 N5boost16exception_detail10clone_implINS0_19error_info_injectorISt11logic_errorEEEE: existing index for chronicle::received_block_object has an undo stack (revision range [-1, 23598015]) that is inconsistent with other indices in the database (revision range [23597735, 23597736]); corrupted database?
May 25 01:05:46 sthist chronicle-receiver[5523]: rethrow existing index for chronicle::received_block_object has an undo stack (revision range [-1, 23598015]) that is inconsistent with other indices in the database (revision range [23597735, 23597736]); corrupted database?:
May 25 01:05:46 sthist chronicle-receiver[5523]: {"what":"existing index for chronicle::received_block_object has an undo stack (revision range [-1, 23598015]) that is inconsistent with other indices in the database (revision range [23597735, 23597736]); corrupted database?"}
May 25 01:05:46 sthist chronicle-receiver[5523]: chronicle-recei receiver_plugin.cpp:1201 plugin_initialize
so, there should be a global lock wrapping around add_index(). For now I will wrap the locks around calling add_index in my program, but I think it makes sense to protect it inside chainbase.
actually I don't see how this is locking anything. It's not modifying the lock count and not using the read_lock object. Does it work at all?
void require_lock_fail( const char* method, const char* lock_type, const char* tname )const;
void require_read_lock( const char* method, const char* tname )const
{
if( BOOST_UNLIKELY( _enable_require_locking & _read_only & (_read_lock_count <= 0) ) )
require_lock_fail(method, "read", tname);
}
void require_write_lock( const char* method, const char* tname )
{
if( BOOST_UNLIKELY( _enable_require_locking & (_write_lock_count <= 0) ) )
require_lock_fail(method, "write", tname);
}
as Todd explained in Devs chat, chainbase is not made to be used in concurrent environment. So probably it makes sense to cleanup unused parts in the code to avoid confusion
Look like multi process trying to set_revision on same database.