Index: cpp/common/threads.h
===================================================================
--- cpp/common/threads.h	(revision 345)
+++ cpp/common/threads.h	(revision 346)
@@ -66,4 +66,28 @@
 };
 
+template<class T> class ThreadSingletonPtr
+{
+pthread_key_t mt_key;
+
+  public:
+
+ThreadSingletonPtr()
+ {
+ pthread_key_create(&mt_key,NULL);
+ }
+
+T* setptr(T* new_o)
+ {
+ T* o=(T*)pthread_getspecific(mt_key);
+ pthread_setspecific(mt_key,new_o);
+ return o;
+ }
+
+T* get()
+ {
+ return (T*)pthread_getspecific(mt_key);
+ }
+};
+
 #else
 
@@ -82,4 +106,7 @@
 ////////////////////////////////////
 
+// THREAD_LOCAL(cls) - behaves like object of class cls (automatic creation/destruction)
+// THREAD_LOCAL(cls)..._PTR - behaves like pointer to cls (initial NULL, no autocreation/destruction)
+// _PTR can only be accessed using tls...Ptr() variant of Get/Set, _ptr suffix is internally used in variable name to avoid mistakes
 #ifdef USE_CPP_TLS
 
@@ -88,4 +115,6 @@
 #define THREAD_LOCAL_DECL(cls,var) CPP_TLS cls* var
 #define THREAD_LOCAL_DEF(cls,var) CPP_TLS cls* var=NULL
+#define THREAD_LOCAL_DECL_PTR(cls,var) CPP_TLS cls* var ## _ptr
+#define THREAD_LOCAL_DEF_PTR(cls,var) CPP_TLS cls* var ## _ptr=NULL
 
 template<class T> T* tlsGet(T*& var)
@@ -93,4 +122,9 @@
 if (!var)
 	var=new T();
+return var;
+}
+
+template<class T> T* tlsGetPtr(T*& var)
+{
 return var;
 }
@@ -105,4 +139,6 @@
 }
 
+#define tlsGetSetPtr(var,o) tlsSet(var ## _ptr,o)
+
 #else
 
@@ -115,4 +151,9 @@
 #define tlsSet(var,o) var.set(o)
 
+#define THREAD_LOCAL_DECL_PTR(cls,var) ThreadSingletonPtr<cls> var ## _ptr
+#define THREAD_LOCAL_DEF_PTR(cls,var) ThreadSingletonPtr<cls> var ## _ptr
+#define tlsGetPtr(var) var ## _ptr.get()
+#define tlsSetPtr(var,o) var ## _ptr.setptr(o)
+
 #endif
 
Index: cpp/frams/genetics/geno.cpp
===================================================================
--- cpp/frams/genetics/geno.cpp	(revision 345)
+++ cpp/frams/genetics/geno.cpp	(revision 346)
@@ -7,6 +7,9 @@
 #include <frams/model/model.h>
 
-SListTempl<GenoValidator*> Geno::validators;
 GenoConvManager *Geno::converters = NULL;
+
+THREAD_LOCAL_DEF(Geno::Validators, geno_validators);
+
+Geno::Validators& Geno::getValidators() {return tlsGetRef(geno_validators);}
 
 void Geno::init(const SString& genstring, char genformat, const SString& genname, const SString& comment)
@@ -234,5 +237,6 @@
 	if (isvalid >= 0) return;
 	if (gen.len() == 0) { isvalid = 0; return; }
-	FOREACH(GenoValidator*, v, validators)
+	Validators& vals=getValidators();
+	FOREACH(GenoValidator*, v, vals)
 		if ((isvalid = v->testGenoValidity(*this)) >= 0)
 			return;
Index: cpp/frams/genetics/geno.h
===================================================================
--- cpp/frams/genetics/geno.h	(revision 345)
+++ cpp/frams/genetics/geno.h	(revision 346)
@@ -54,4 +54,6 @@
 
 public:
+	typedef SListTempl<GenoValidator*> Validators;
+
 	/// create a genotype object from primitives
 	/// @param genstring pure genotype, without any comments
@@ -116,11 +118,11 @@
 
 	// managing global Geno-related objects (used for validation and conversion)
-	static void addValidator(GenoValidator* gv) { validators += gv; }
-	static void removeValidator(GenoValidator* gv) { validators -= gv; }
+	static Validators& getValidators();
+	static void addValidator(GenoValidator* gv,int at_position=9999) { getValidators().insert(at_position,gv); }
+	static void removeValidator(GenoValidator* gv) { getValidators() -= gv; }
 	static void useConverters(GenoConvManager& gcm) { converters = &gcm; }
 	static GenoConvManager &getConverters() { return *converters; }
 protected:
 	static GenoConvManager *converters;
-	static SListTempl<GenoValidator*> validators;
 };
 
Index: cpp/frams/genetics/preconfigured.h
===================================================================
--- cpp/frams/genetics/preconfigured.h	(revision 345)
+++ cpp/frams/genetics/preconfigured.h	(revision 346)
@@ -30,4 +30,17 @@
 };
 
+/** Initialization procedure for applications adding their own validators */
+class PreconfiguredGenetics_NoValidators
+{
+  public:
+DefaultGenoConvManager gcm;
+
+PreconfiguredGenetics_NoValidators()
+	{
+	gcm.addDefaultConverters(); //without converters, the application would only handle "format 0" genotypes
+	Geno::useConverters(gcm);
+	}
+};
+
 #endif
 
