Skip to content

Commit 36d32fb

Browse files
authored
Merge pull request #33 from rok4/develop
Release 1.2.4
2 parents 8a2f09d + 071139d commit 36d32fb

3 files changed

Lines changed: 92 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## 1.2.4
2+
3+
### [Fixed]
4+
5+
* `Cache` : les modifications dans le cache quand il n'est pas par thread (index des dalles, TMS et styles) se font en xxclusion mutuelle (mutex lock et unlock)
6+
17
## 1.2.3
28

39
### [Fixed]

include/rok4/utils/Cache.h

Lines changed: 83 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@
5656
#include <sstream>
5757
#include <curl/curl.h>
5858
#include <proj.h>
59+
#include <thread>
60+
#include <mutex>
5961

6062

6163
#include "rok4/utils/TileMatrixSet.h"
@@ -470,6 +472,14 @@ class IndexCache {
470472
*/
471473
static int validity;
472474

475+
/**
476+
* \~french \brief Exclusion mutuelle
477+
* \details Pour éviter les modifications concurrentes du cache des index
478+
* \~english \brief Mutual exclusion
479+
* \details To avoid concurrent index cache updates
480+
*/
481+
static std::mutex mtx;
482+
473483
/**
474484
* \~french
475485
* \brief Constructeur
@@ -533,14 +543,16 @@ class IndexCache {
533543
// mais c'est via cette dalle symbolique que la donnée est a priori requêtée
534544
// donc c'est ce nom qu'on utilisera pour l'interrogation du cache
535545

546+
mtx.lock();
547+
536548
IndexElement* elem = new IndexElement(origin_slab_name, data_context, data_slab_name, tiles_number, offsets, sizes);
537549

538550
// L'information n'est a priori pas dans le cache car
539-
// Soit elle était dans le cache et valide, alors on aurait utiliser ce cahe et on n'aurait pas fait appel à cet ajout
551+
// Soit elle était dans le cache et valide, alors on aurait utilisé ce cache et on n'aurait pas fait appel à cet ajout
540552
// Soit elle était dans le cache mais obsolète, alors on l'aurait déjà supprimé du cache
541553

542554
if (cache.size() == size) {
543-
// On réupcère le dernier élément du cache
555+
// On récupère le dernier élément du cache
544556
IndexElement* last = cache.back();
545557
// On le vire du cache
546558
cache.pop_back();
@@ -552,6 +564,8 @@ class IndexCache {
552564
// update reference
553565
cache.push_front(elem);
554566
map[origin_slab_name] = cache.begin();
567+
568+
mtx.unlock();
555569
};
556570

557571
/** \~french
@@ -579,9 +593,19 @@ class IndexCache {
579593
// Gestion de la péremption du cache (une heure max)
580594
std::time_t now = std::time(NULL);
581595
if (now - (*(it->second))->date > validity) {
582-
delete *(it->second);
583-
cache.erase(it->second);
584-
map.erase(it);
596+
mtx.lock();
597+
598+
// on le cherche à nouveau pour vérifier qu'il n'a pas déjà été supprimé par un thread concurrent
599+
it = map.find ( key );
600+
601+
if ( it != map.end() ) {
602+
delete *(it->second);
603+
cache.erase(it->second);
604+
map.erase(it);
605+
}
606+
607+
mtx.unlock();
608+
585609
return false;
586610
}
587611

@@ -605,11 +629,13 @@ class IndexCache {
605629
* \~english \brief Clean all element from the cache
606630
*/
607631
static void cleanCache () {
632+
mtx.lock();
608633
std::list<IndexElement*>::iterator it;
609634
for (it = cache.begin(); it != cache.end(); ++it) {
610635
delete *it;
611636
}
612637
cache.clear();
638+
mtx.unlock();
613639
}
614640
};
615641

@@ -654,6 +680,14 @@ class TmsBook {
654680
*/
655681
static std::vector<TileMatrixSet*> trash;
656682

683+
/**
684+
* \~french \brief Exclusion mutuelle
685+
* \details Pour éviter les modifications concurrentes du cache de TMS
686+
* \~english \brief Mutual exclusion
687+
* \details To avoid concurrent TMS cache updates
688+
*/
689+
static std::mutex mtx;
690+
657691
public:
658692

659693

@@ -662,22 +696,26 @@ class TmsBook {
662696
* \~english \brief Empty book and put content into trash
663697
*/
664698
static void send_to_trash () {
699+
mtx.lock();
665700
std::map<std::string, TileMatrixSet*>::iterator it;
666701
for (it = book.begin(); it != book.end(); ++it) {
667702
trash.push_back(it->second);
668703
}
669704
book.empty();
705+
mtx.unlock();
670706
}
671707

672708
/**
673709
* \~french \brief Vide la corbeille
674710
* \~english \brief Empty trash
675711
*/
676712
static void empty_trash () {
713+
mtx.lock();
677714
for (int i = 0; i < trash.size(); i++) {
678715
delete trash.at(i);
679716
}
680717
trash.empty();
718+
mtx.unlock();
681719
}
682720

683721

@@ -694,7 +732,7 @@ class TmsBook {
694732
}
695733

696734
/**
697-
* \~french \brief Renseigne l'ensemble de l'annuaire
735+
* \~french \brief Retourne l'ensemble de l'annuaire
698736
* \~english \brief Return the book
699737
*/
700738
static std::map<std::string,TileMatrixSet*> get_book () {
@@ -731,20 +769,32 @@ class TmsBook {
731769

732770
std::string tms_path = d + "/" + id;
733771

772+
mtx.lock();
773+
// Si on fait du cache de TMS, on revérifie que ce TMS n'a pas déjà été ajouté par un thread concurrent entre temps
774+
if(getenv (ROK4_TMS_NO_CACHE) == NULL) {
775+
if ( it != book.end() ) {
776+
// On a effectivement depuis déjà enregistré ce TMS
777+
return it->second;
778+
}
779+
}
780+
734781
TileMatrixSet* tms = new TileMatrixSet(tms_path);
735782
if ( ! tms->isOk() ) {
736783
BOOST_LOG_TRIVIAL(error) << tms->getErrorMessage();
737784
delete tms;
785+
mtx.unlock();
738786
return NULL;
739787
}
740788

741-
if(getenv (ROK4_STYLES_NO_CACHE) == NULL) {
742-
// On veut utiliser le cache, on met donc ce nouveau TMS dans l'annuaire pour le trouver la porchaine fois
789+
if(getenv (ROK4_TMS_NO_CACHE) == NULL) {
790+
// On veut utiliser le cache, on met donc ce nouveau TMS dans l'annuaire pour le trouver la prochaine fois
743791
book.insert ( std::pair<std::string, TileMatrixSet*>(id, tms) );
744792
} else {
745793
// On met le TMS directement dans la corbeille, pour que le nettoyage se fasse bien
746794
trash.push_back(tms);
747795
}
796+
797+
mtx.unlock();
748798

749799
return tms;
750800
}
@@ -816,6 +866,14 @@ class StyleBook {
816866
*/
817867
static std::vector<Style*> trash;
818868

869+
/**
870+
* \~french \brief Exclusion mutuelle
871+
* \details Pour éviter les modifications concurrentes du cache de TMS
872+
* \~english \brief Mutual exclusion
873+
* \details To avoid concurrent TMS cache updates
874+
*/
875+
static std::mutex mtx;
876+
819877
public:
820878

821879

@@ -824,22 +882,26 @@ class StyleBook {
824882
* \~english \brief Empty book and put content into trash
825883
*/
826884
static void send_to_trash () {
885+
mtx.lock();
827886
std::map<std::string, Style*>::iterator it;
828887
for (it = book.begin(); it != book.end(); ++it) {
829888
trash.push_back(it->second);
830889
}
831890
book.empty();
891+
mtx.unlock();
832892
}
833893

834894
/**
835895
* \~french \brief Vide la corbeille
836896
* \~english \brief Empty trash
837897
*/
838898
static void empty_trash () {
899+
mtx.lock();
839900
for (int i = 0; i < trash.size(); i++) {
840901
delete trash.at(i);
841902
}
842903
trash.empty();
904+
mtx.unlock();
843905
}
844906

845907

@@ -866,7 +928,7 @@ class StyleBook {
866928

867929

868930
/**
869-
* \~french \brief Renseigne l'ensemble de l'annuaire
931+
* \~french \brief Retourne l'ensemble de l'annuaire
870932
* \~english \brief Return the book
871933
*/
872934
static std::map<std::string,Style*> get_book () {
@@ -904,16 +966,27 @@ class StyleBook {
904966

905967
std::string style_path = d + "/" + id;
906968

969+
mtx.lock();
970+
// Si on fait du cache de style, on revérifie que ce style n'a pas déjà été ajouté par un thread concurrent entre temps
971+
if(getenv (ROK4_STYLES_NO_CACHE) == NULL) {
972+
if ( it != book.end() ) {
973+
// On a effectivement depuis déjà enregistré ce style
974+
return it->second;
975+
}
976+
}
977+
907978
Style* style = new Style(style_path, inspire);
908979
if ( ! style->isOk() ) {
909980
BOOST_LOG_TRIVIAL(error) << style->getErrorMessage();
910981
delete style;
982+
mtx.unlock();
911983
return NULL;
912984
}
913985

914986
if ( containForbiddenChars(style->getIdentifier()) ) {
915987
BOOST_LOG_TRIVIAL(error) << "Style identifier contains forbidden chars" ;
916988
delete style;
989+
mtx.unlock();
917990
return NULL;
918991
}
919992

@@ -925,6 +998,7 @@ class StyleBook {
925998
trash.push_back(style);
926999
}
9271000

1001+
mtx.unlock();
9281002
return style;
9291003
}
9301004

src/utils/Cache.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,18 @@ std::list<IndexElement *> IndexCache::cache;
6161
std::unordered_map<std::string, std::list<IndexElement *>::iterator> IndexCache::map;
6262
int IndexCache::size = 100;
6363
int IndexCache::validity = 300;
64+
std::mutex IndexCache::mtx;
6465

6566
std::map<std::string, TileMatrixSet*> TmsBook::book;
6667
std::vector<TileMatrixSet*> TmsBook::trash;
6768
std::string TmsBook::directory = "";
69+
std::mutex TmsBook::mtx;
6870

6971
std::map<std::string, Style*> StyleBook::book;
7072
std::vector<Style*> StyleBook::trash;
7173
std::string StyleBook::directory = "";
7274
bool StyleBook::inspire = false;
75+
std::mutex StyleBook::mtx;
7376

7477
Context * StoragePool::get_context(ContextType::eContextType type,std::string tray) {
7578
Context* ctx;

0 commit comments

Comments
 (0)