diff --git a/lmdb.h b/lmdb.h index acff2609..db57d5ed 100644 --- a/lmdb.h +++ b/lmdb.h @@ -1671,12 +1671,14 @@ int mdb_reader_check(MDB_env *env, int *dead); int mdbx_txn_straggler(MDB_txn *txn, int *percent); /** @brief A callback function for killing a laggard readers, - * called in case of MDB_MAP_FULL error. + * but also could waiting ones. Called in case of MDB_MAP_FULL error. * * @param[in] env An environment handle returned by #mdb_env_create(). * @param[in] pid pid of the reader process. * @param[in] thread_id thread_id of the reader thread. * @param[in] txn Transaction number on which stalled. + * @param[in] gap a lag from the last commited txn. + * @param[in] retry a retry number, less that zero for notify end of OOM-loop. * @return -1 on failure (reader is not killed), * 0 on a race condition (no such reader), * 1 on success (reader was killed), diff --git a/mdb.c b/mdb.c index 9e0c902b..6744ac76 100644 --- a/mdb.c +++ b/mdb.c @@ -1990,43 +1990,49 @@ mdbx_oomkick(MDB_env *env, txnid_t oldest) break; snap = mdb_find_oldest(env, &reader); - if (oldest < snap) + if (oldest < snap || reader < 0) { + if (retry && env->me_oom_func) { + /* LY: notify end of oom-loop */ + env->me_oom_func(env, 0, 0, oldest, snap - oldest, -retry); + } return snap; + } - if (reader < 0) - return 0; + MDB_reader *r; + pthread_t tid; + pid_t pid; + int rc; - { - MDB_reader *r; - pthread_t tid; - pid_t pid; - int rc; + if (!env->me_oom_func) + break; - if (!env->me_oom_func) - break; + r = &env->me_txns->mti_readers[ reader ]; + pid = r->mr_pid; + tid = r->mr_tid; + if (r->mr_txnid != oldest || pid <= 0) + continue; - r = &env->me_txns->mti_readers[ reader ]; - pid = r->mr_pid; - tid = r->mr_tid; - if (r->mr_txnid != oldest || pid <= 0) - continue; + rc = env->me_oom_func(env, pid, (void*) tid, oldest, + mdb_meta_head_w(env)->mm_txnid - oldest, retry); + if (rc < 0) + break; - rc = env->me_oom_func(env, pid, (void*) tid, oldest, - mdb_meta_head_w(env)->mm_txnid - oldest, retry); - if (rc < 0) - break; - - if (rc) { - r->mr_txnid = ~(txnid_t)0; - if (rc > 1) { - r->mr_tid = 0; - r->mr_pid = 0; - mdbx_coherent_barrier(); - } + if (rc) { + r->mr_txnid = ~(txnid_t)0; + if (rc > 1) { + r->mr_tid = 0; + r->mr_pid = 0; + mdbx_coherent_barrier(); } } } + + if (retry && env->me_oom_func) { + /* LY: notify end of oom-loop */ + env->me_oom_func(env, 0, 0, oldest, 0, -retry); + } #else + (void) oldest; (void) mdb_reader_check(env, NULL); #endif /* MDBX_MODE_ENABLED */ return mdb_find_oldest(env, NULL);