Refactor database cleanups to take the same path for #close and ruby's garbage collection.
FossilOrigin-Name: a2a8d99136cfa9e98e75cc262b8f9aefa5ed576d7af804416b8c8c7f4d4f4bdb
This commit is contained in:
parent
2b745bc756
commit
0093c49b91
2 changed files with 42 additions and 12 deletions
|
|
@ -45,19 +45,36 @@ static const rb_data_type_t rmdbx_db_data = {
|
||||||
VALUE
|
VALUE
|
||||||
rmdbx_alloc( VALUE klass )
|
rmdbx_alloc( VALUE klass )
|
||||||
{
|
{
|
||||||
int *data = malloc( sizeof(rmdbx_db_t) );
|
rmdbx_db_t *data;
|
||||||
return TypedData_Wrap_Struct( klass, &rmdbx_db_data, data );
|
return TypedData_Make_Struct( klass, rmdbx_db_t, &rmdbx_db_data, data );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensure all database file descriptors are collected and
|
||||||
|
* removed.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
rmdbx_destroy( rmdbx_db_t* db )
|
||||||
|
{
|
||||||
|
if ( db->cursor ) mdbx_cursor_close( db->cursor );
|
||||||
|
if ( db->txn ) mdbx_txn_abort( db->txn );
|
||||||
|
if ( db->dbi ) mdbx_dbi_close( db->env, db->dbi );
|
||||||
|
if ( db->env ) mdbx_env_close( db->env );
|
||||||
|
db->open = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cleanup a previously allocated DB environment.
|
* Cleanup a previously allocated DB environment.
|
||||||
* FIXME: ... this should also close if not already closed?
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
rmdbx_free( void *db )
|
rmdbx_free( void *db )
|
||||||
{
|
{
|
||||||
if ( db ) free( db );
|
if ( db ) {
|
||||||
|
rmdbx_destroy( db );
|
||||||
|
free( db );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -68,14 +85,7 @@ VALUE
|
||||||
rmdbx_close( VALUE self )
|
rmdbx_close( VALUE self )
|
||||||
{
|
{
|
||||||
UNWRAP_DB( self, db );
|
UNWRAP_DB( self, db );
|
||||||
if ( db->cursor ) mdbx_cursor_close( db->cursor );
|
rmdbx_destroy( db );
|
||||||
if ( db->txn ) mdbx_txn_abort( db->txn );
|
|
||||||
if ( db->dbi ) mdbx_dbi_close( db->env, db->dbi );
|
|
||||||
if ( db->env ) mdbx_env_close( db->env );
|
|
||||||
db->open = 0;
|
|
||||||
|
|
||||||
// FIXME: or rather, maybe free() from here?
|
|
||||||
|
|
||||||
return Qtrue;
|
return Qtrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,5 +17,25 @@ RSpec.describe( MDBX::Database ) do
|
||||||
expect( db.closed? ).to be_truthy
|
expect( db.closed? ).to be_truthy
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'an opened database' do
|
||||||
|
|
||||||
|
before( :each ) do
|
||||||
|
@db = described_class.open( TEST_DATABASE.to_s )
|
||||||
|
end
|
||||||
|
|
||||||
|
after( :each ) do
|
||||||
|
@db.close
|
||||||
|
end
|
||||||
|
|
||||||
|
it "fails if opened again within the same process" do
|
||||||
|
# This is a function of libmdbx internals, just testing
|
||||||
|
# here for behaviorals.
|
||||||
|
expect {
|
||||||
|
described_class.open( TEST_DATABASE.to_s )
|
||||||
|
}.
|
||||||
|
to raise_exception( MDBX::DatabaseError, /environment is already used/ )
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue