22
22
#include < string>
23
23
#include < memory>
24
24
25
+ #include < pthread.h>
26
+
25
27
#include " modsecurity/variable_value.h"
26
28
#include " src/utils/regex.h"
27
29
#include " src/variables/variable.h"
@@ -36,21 +38,22 @@ namespace backend {
36
38
#ifdef WITH_LMDB
37
39
38
40
LMDB::LMDB (std::string name) :
39
- Collection(name), m_env(NULL ) {
40
- MDB_txn *txn;
41
- mdb_env_create (&m_env);
42
- mdb_env_open (m_env, " ./modsec-shared-collections" ,
43
- MDB_WRITEMAP | MDB_NOSUBDIR, 0664 );
44
- mdb_txn_begin (m_env, NULL , 0 , &txn);
45
- mdb_dbi_open (txn, NULL , MDB_CREATE | MDB_DUPSORT, &m_dbi);
46
- mdb_txn_commit (txn);
47
- }
41
+ Collection(name), m_env(NULL ), isOpen(false ) {}
48
42
49
43
50
44
LMDB::~LMDB () {
51
45
mdb_env_close (m_env);
52
46
}
53
47
48
+ int LMDB::txn_begin (unsigned int flags, MDB_txn **ret) {
49
+ if (!isOpen) {
50
+ MDBEnvProvider* provider = MDBEnvProvider::GetInstance ();
51
+ m_env = provider->GetEnv ();
52
+ m_dbi = *(provider->GetDBI ());
53
+ isOpen = true ;
54
+ }
55
+ return mdb_txn_begin (m_env, NULL , flags, ret);
56
+ }
54
57
55
58
void LMDB::string2val (const std::string& str, MDB_val *val) {
56
59
val->mv_size = sizeof (char )*(str.size ());
@@ -159,7 +162,7 @@ std::unique_ptr<std::string> LMDB::resolveFirst(const std::string& var) {
159
162
160
163
string2val (var, &mdb_key);
161
164
162
- rc = mdb_txn_begin (m_env, NULL , MDB_RDONLY, &txn);
165
+ rc = txn_begin ( MDB_RDONLY, &txn);
163
166
lmdb_debug (rc, " txn" , " resolveFirst" );
164
167
if (rc != 0 ) {
165
168
goto end_txn;
@@ -192,7 +195,7 @@ bool LMDB::storeOrUpdateFirst(const std::string &key,
192
195
string2val (key, &mdb_key);
193
196
string2val (value, &mdb_value);
194
197
195
- rc = mdb_txn_begin (m_env, NULL , 0 , &txn);
198
+ rc = txn_begin ( 0 , &txn);
196
199
lmdb_debug (rc, " txn" , " storeOrUpdateFirst" );
197
200
if (rc != 0 ) {
198
201
goto end_txn;
@@ -240,7 +243,7 @@ void LMDB::resolveSingleMatch(const std::string& var,
240
243
MDB_val mdb_value_ret;
241
244
MDB_cursor *cursor;
242
245
243
- rc = mdb_txn_begin (m_env, NULL , MDB_RDONLY, &txn);
246
+ rc = txn_begin ( MDB_RDONLY, &txn);
244
247
lmdb_debug (rc, " txn" , " resolveSingleMatch" );
245
248
if (rc != 0 ) {
246
249
goto end_txn;
@@ -271,7 +274,7 @@ void LMDB::store(std::string key, std::string value) {
271
274
int rc;
272
275
MDB_stat mst;
273
276
274
- rc = mdb_txn_begin (m_env, NULL , 0 , &txn);
277
+ rc = txn_begin ( 0 , &txn);
275
278
lmdb_debug (rc, " txn" , " store" );
276
279
if (rc != 0 ) {
277
280
goto end_txn;
@@ -310,7 +313,7 @@ bool LMDB::updateFirst(const std::string &key,
310
313
MDB_val mdb_value;
311
314
MDB_val mdb_value_ret;
312
315
313
- rc = mdb_txn_begin (m_env, NULL , 0 , &txn);
316
+ rc = txn_begin ( 0 , &txn);
314
317
lmdb_debug (rc, " txn" , " updateFirst" );
315
318
if (rc != 0 ) {
316
319
goto end_txn;
@@ -364,7 +367,7 @@ void LMDB::del(const std::string& key) {
364
367
MDB_val mdb_value_ret;
365
368
MDB_stat mst;
366
369
367
- rc = mdb_txn_begin (m_env, NULL , 0 , &txn);
370
+ rc = txn_begin ( 0 , &txn);
368
371
lmdb_debug (rc, " txn" , " del" );
369
372
if (rc != 0 ) {
370
373
goto end_txn;
@@ -411,7 +414,7 @@ void LMDB::resolveMultiMatches(const std::string& var,
411
414
size_t keySize = var.size ();
412
415
MDB_cursor *cursor;
413
416
414
- rc = mdb_txn_begin (m_env, NULL , MDB_RDONLY, &txn);
417
+ rc = txn_begin ( MDB_RDONLY, &txn);
415
418
lmdb_debug (rc, " txn" , " resolveMultiMatches" );
416
419
if (rc != 0 ) {
417
420
goto end_txn;
@@ -465,7 +468,7 @@ void LMDB::resolveRegularExpression(const std::string& var,
465
468
466
469
Utils::Regex r (var, true );
467
470
468
- rc = mdb_txn_begin (m_env, NULL , MDB_RDONLY, &txn);
471
+ rc = txn_begin ( MDB_RDONLY, &txn);
469
472
lmdb_debug (rc, " txn" , " resolveRegularExpression" );
470
473
if (rc != 0 ) {
471
474
goto end_txn;
@@ -503,6 +506,61 @@ void LMDB::resolveRegularExpression(const std::string& var,
503
506
return ;
504
507
}
505
508
509
+
510
+ MDBEnvProvider* MDBEnvProvider::provider_ = nullptr ;;
511
+
512
+ MDBEnvProvider* MDBEnvProvider::GetInstance () {
513
+ if (provider_==nullptr ) {
514
+ provider_ = new MDBEnvProvider ();
515
+ }
516
+ return provider_;
517
+ }
518
+
519
+ void MDBEnvProvider::Finalize () {
520
+ if (provider_!=nullptr ) {
521
+ provider_->close ();
522
+ provider_ = nullptr ;
523
+ }
524
+ }
525
+
526
+ MDBEnvProvider::MDBEnvProvider () :
527
+ m_env(NULL ), initialized(false ) {
528
+ pthread_mutex_init (&m_lock, NULL );
529
+ }
530
+
531
+ MDB_env* MDBEnvProvider::GetEnv () {
532
+ init ();
533
+ return m_env;
534
+ }
535
+
536
+ MDB_dbi* MDBEnvProvider::GetDBI () {
537
+ init ();
538
+ return &m_dbi;
539
+ }
540
+
541
+ void MDBEnvProvider::init () {
542
+ pthread_mutex_lock (&m_lock);
543
+ if (!initialized) {
544
+ MDB_txn *txn;
545
+ mdb_env_create (&m_env);
546
+ mdb_env_open (m_env, " ./modsec-shared-collections" ,
547
+ MDB_WRITEMAP | MDB_NOSUBDIR, 0664 );
548
+ mdb_txn_begin (m_env, NULL , 0 , &txn);
549
+ mdb_dbi_open (txn, NULL , MDB_CREATE | MDB_DUPSORT, &m_dbi);
550
+ mdb_txn_commit (txn);
551
+ }
552
+ pthread_mutex_unlock (&m_lock);
553
+ }
554
+
555
+ void MDBEnvProvider::close () {
556
+ pthread_mutex_lock (&m_lock);
557
+ if (initialized) {
558
+ mdb_dbi_close (m_env, m_dbi);
559
+ mdb_env_close (m_env);
560
+ }
561
+ pthread_mutex_unlock (&m_lock);
562
+ }
563
+
506
564
#endif
507
565
508
566
} // namespace backend
0 commit comments