AutoLock& operator = (const AutoLock&);
};
-class TLSDataContainer
+class CV_EXPORTS TLSDataContainer
{
private:
int key_;
protected:
- CV_EXPORTS TLSDataContainer();
- CV_EXPORTS ~TLSDataContainer(); // virtual is not required
+ TLSDataContainer();
+ virtual ~TLSDataContainer();
public:
virtual void* createDataInstance() const = 0;
virtual void deleteDataInstance(void* data) const = 0;
- CV_EXPORTS void* getData() const;
+ void* getData() const;
};
template <typename T>
bool useOpenCL()
{
- TLSData* data = TLSData::get();
+ CoreTLSData* data = coreTlsData.get();
if( data->useOpenCL < 0 )
data->useOpenCL = (int)haveOpenCL();
return data->useOpenCL > 0;
{
if( haveOpenCL() )
{
- TLSData* data = TLSData::get();
+ CoreTLSData* data = coreTlsData.get();
data->useOpenCL = flag ? 1 : 0;
}
}
const Device& Device::getDefault()
{
const Context2& ctx = Context2::getDefault();
- int idx = TLSData::get()->device;
+ int idx = coreTlsData.get()->device;
return ctx.device(idx);
}
Queue& Queue::getDefault()
{
- Queue& q = TLSData::get()->oclQueue;
+ Queue& q = coreTlsData.get()->oclQueue;
if( !q.p && haveOpenCL() )
q.create(Context2::getDefault());
return q;
#if defined WIN32 || defined _WIN32
void deleteThreadAllocData();
-void deleteThreadData();
#endif
template<typename T1, typename T2=T1, typename T3=T1> struct OpAdd
void convertAndUnrollScalar( const Mat& sc, int buftype, uchar* scbuf, size_t blocksize );
-struct TLSData
+struct CoreTLSData
{
- TLSData();
+ CoreTLSData() : device(0), useOpenCL(-1)
+ {}
+
RNG rng;
int device;
ocl::Queue oclQueue;
int useOpenCL; // 1 - use, 0 - do not use, -1 - auto/not initialized
-
- static TLSData* get();
};
+extern TLSData<CoreTLSData> coreTlsData;
+
#if defined(BUILD_SHARED_LIBS)
#if defined WIN32 || defined _WIN32 || defined WINCE
#define CL_RUNTIME_EXPORT __declspec(dllexport)
cv::RNG& cv::theRNG()
{
- return TLSData::get()->rng;
+ return coreTlsData.get()->rng;
}
void cv::randu(InputOutputArray dst, InputArray low, InputArray high)
BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID);
-BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID)
+BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID lpReserved)
{
if (fdwReason == DLL_THREAD_DETACH || fdwReason == DLL_PROCESS_DETACH)
{
+ if (lpReserved != NULL) // called after ExitProcess() call
+ cv::__termination = true;
cv::deleteThreadAllocData();
- cv::deleteThreadRNGData();
cv::deleteThreadData();
}
return TRUE;
tlsData_.clear();
}
-} // namespace cv
-
-//////////////////////////////// thread-local storage ////////////////////////////////
-
-namespace cv
-{
-
-TLSData::TLSData()
-{
- device = 0;
- useOpenCL = -1;
-}
-
-#ifdef WIN32
-
-#ifdef HAVE_WINRT
- // using C++11 thread attribute for local thread data
- static __declspec( thread ) TLSData* g_tlsdata = NULL;
-
- static void deleteThreadRNGData()
- {
- if (g_tlsdata)
- delete g_tlsdata;
- }
-
- TLSData* TLSData::get()
- {
- if (!g_tlsdata)
- {
- g_tlsdata = new TLSData;
- }
- return g_tlsdata;
- }
-#else
-#ifdef WINCE
-# define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF)
-#endif
- static DWORD tlsKey = TLS_OUT_OF_INDEXES;
-
- void deleteThreadData()
- {
- if( tlsKey != TLS_OUT_OF_INDEXES )
- delete (TLSData*)TlsGetValue( tlsKey );
- }
+TLSData<CoreTLSData> coreTlsData;
- TLSData* TLSData::get()
- {
- if( tlsKey == TLS_OUT_OF_INDEXES )
- {
- tlsKey = TlsAlloc();
- CV_Assert(tlsKey != TLS_OUT_OF_INDEXES);
- }
- TLSData* d = (TLSData*)TlsGetValue( tlsKey );
- if( !d )
- {
- d = new TLSData;
- TlsSetValue( tlsKey, d );
- }
- return d;
- }
-#endif //HAVE_WINRT
-#else
- static pthread_key_t tlsKey = 0;
- static pthread_once_t tlsKeyOnce = PTHREAD_ONCE_INIT;
-
- static void deleteTLSData(void* data)
- {
- delete (TLSData*)data;
- }
-
- static void makeKey()
- {
- int errcode = pthread_key_create(&tlsKey, deleteTLSData);
- CV_Assert(errcode == 0);
- }
-
- TLSData* TLSData::get()
- {
- pthread_once(&tlsKeyOnce, makeKey);
- TLSData* d = (TLSData*)pthread_getspecific(tlsKey);
- if( !d )
- {
- d = new TLSData;
- pthread_setspecific(tlsKey, d);
- }
- return d;
- }
-#endif
-}
+} // namespace cv
/* End of file. */