1
0
forked from GitHub/gf-core

cleanup transient revisions only after a transaction is opened

This commit is contained in:
Krasimir Angelov
2021-12-29 14:52:21 +01:00
parent f118e644d9
commit cd2c6aa32a
3 changed files with 39 additions and 36 deletions

View File

@@ -502,7 +502,6 @@ struct PGF_INTERNAL_DECL malloc_state
PGF_INTERNAL
PgfDB::PgfDB(const char* filepath, int flags, int mode) {
bool is_new = false;
bool is_first = false;
fd = -1;
ms = NULL;
@@ -655,34 +654,7 @@ PgfDB::PgfDB(const char* filepath, int flags, int mode) {
throw pgf_error("Invalid file content");
}
register_process(&is_first);
if (is_first) {
// We must make sure that left-over transient revisions are
// released. This may happen if a client process was killed
// or if the garbadge collector has not managed to run
// pgf_release_revision() before the process ended.
while (ms->transient_revisions != 0) {
pgf_free_revision(this, ms->transient_revisions.as_object());
ref<PgfPGF> pgf = ms->transient_revisions;
ref<PgfPGF> next = pgf->next;
PgfPGF::release(pgf);
PgfDB::free(pgf);
ms->transient_revisions = next;
}
while (ms->transient_concr_revisions != 0) {
ref<PgfConcr> concr = ms->transient_concr_revisions;
ref<PgfConcr> next = concr->next;
concr->ref_count -= concr->ref_count_ex;
if (!concr->ref_count) {
PgfConcr::release(concr);
PgfDB::free(concr);
}
ms->transient_concr_revisions = next;
}
}
register_process();
}
}
@@ -725,7 +697,7 @@ PgfDB::~PgfDB()
}
PGF_INTERNAL
void PgfDB::register_process(bool *is_first)
void PgfDB::register_process()
{
process_entry *pentry = &ms->p;
object *plast = NULL;
@@ -768,10 +740,7 @@ void PgfDB::register_process(bool *is_first)
}
}
if (plast == NULL) {
*is_first = true;
} else {
*is_first = false;
if (plast != NULL) {
*plast = malloc_internal(sizeof(process_entry));
pentry = (process_entry*) ptr(ms,*plast);
pentry->next = 0;
@@ -809,6 +778,37 @@ void PgfDB::unregister_process()
}
}
void PgfDB::cleanup_revisions()
{
if (ms->p.next == 0) {
// The first process that opens this file makes sure that
// left-over transient revisions are released.
// They may be left-over of a client process that was killed
// or if the garbadge collector has not managed to run
// pgf_release_revision() before the process ended.
while (ms->transient_revisions != 0) {
pgf_free_revision(this, ms->transient_revisions.as_object());
ref<PgfPGF> pgf = ms->transient_revisions;
ref<PgfPGF> next = pgf->next;
PgfPGF::release(pgf);
PgfDB::free(pgf);
ms->transient_revisions = next;
}
while (ms->transient_concr_revisions != 0) {
ref<PgfConcr> concr = ms->transient_concr_revisions;
ref<PgfConcr> next = concr->next;
concr->ref_count -= concr->ref_count_ex;
if (!concr->ref_count) {
PgfConcr::release(concr);
PgfDB::free(concr);
}
ms->transient_concr_revisions = next;
}
}
}
PGF_INTERNAL
ref<PgfPGF> PgfDB::get_revision(PgfText *name)
{

View File

@@ -90,6 +90,8 @@ public:
current_db->free_internal(o.as_object());
}
PGF_INTERNAL_DECL void cleanup_revisions();
static PGF_INTERNAL_DECL ref<PgfPGF> get_revision(PgfText *name);
static PGF_INTERNAL_DECL void set_revision(ref<PgfPGF> pgf);
@@ -111,10 +113,9 @@ private:
PGF_INTERNAL_DECL object malloc_internal(size_t bytes);
PGF_INTERNAL_DECL void free_internal(object o);
PGF_INTERNAL_DECL void register_process(bool *is_first);
PGF_INTERNAL_DECL void register_process();
PGF_INTERNAL_DECL void unregister_process();
PGF_INTERNAL_DECL void lock(DB_scope_mode m);
PGF_INTERNAL_DECL void unlock();

View File

@@ -144,6 +144,8 @@ PgfDB *pgf_read_ngf(const char *fpath,
{
DB_scope scope(db, WRITER_SCOPE);
db->cleanup_revisions();
ref<PgfPGF> pgf = PgfDB::get_revision(master);
Node<PgfPGF>::add_value_ref(pgf);
*revision = pgf.as_object();