/* * * Copyright (c) 1998-2002 * Dr John Maddock * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Dr John Maddock makes no representations * about the suitability of this software for any purpose. * It is provided "as is" without express or implied warranty. * */ /* * LOCATION: see http://www.boost.org for most recent version. * FILE regex_synch.hpp * VERSION see * DESCRIPTION: Thread synchronisation for regex code. * Note this is an internal header file included * by regex.hpp, do not include on its own. */ #ifndef BOOST_REGEX_SYNCH_HPP #define BOOST_REGEX_SYNCH_HPP #ifndef BOOST_REGEX_CONFIG_HPP #include #endif #if defined(BOOST_HAS_THREADS) # if defined(BOOST_HAS_WINTHREADS) # include # elif defined(BOOST_HAS_BETHREADS) # include # include # elif defined(BOOST_HAS_PTHREADS) # include # else # error "Unknown threading API" # endif #endif namespace boost{ namespace re_detail{ #ifdef __BORLANDC__ #pragma option push -a8 -b -Vx -Ve -pc #endif void BOOST_REGEX_CALL re_init_threads(); void BOOST_REGEX_CALL re_free_threads(); #ifdef BOOST_HAS_THREADS # ifdef BOOST_HAS_BETHREADS typedef sem_id CRITICAL_SECTION; inline void BOOST_REGEX_CALL InitializeCriticalSection(CRITICAL_SECTION* ps) { *ps = create_sem(1, "regex++"); assert(*ps > 0); } inline void BOOST_REGEX_CALL DeleteCriticalSection(CRITICAL_SECTION* ps) { int t = delete_sem(*ps); assert(t == B_NO_ERROR); } inline void BOOST_REGEX_CALL EnterCriticalSection(CRITICAL_SECTION* ps) { status_t t = acquire_sem(*ps); assert(t == B_NO_ERROR); } inline void BOOST_REGEX_CALL LeaveCriticalSection(CRITICAL_SECTION* ps) { status_t t = release_sem(*ps); assert(t == B_NO_ERROR); } # elif defined(BOOST_HAS_PTHREADS) typedef pthread_mutex_t CRITICAL_SECTION; inline void BOOST_REGEX_CALL InitializeCriticalSection(CRITICAL_SECTION* ps) { pthread_mutex_init(ps, 0); } inline void BOOST_REGEX_CALL DeleteCriticalSection(CRITICAL_SECTION* ps) { pthread_mutex_destroy(ps); } inline void BOOST_REGEX_CALL EnterCriticalSection(CRITICAL_SECTION* ps) { pthread_mutex_lock(ps); } inline void BOOST_REGEX_CALL LeaveCriticalSection(CRITICAL_SECTION* ps) { pthread_mutex_unlock(ps); } # elif !defined(BOOST_HAS_WINTHREADS) # error "Unknown threading API" # endif template class lock_guard { typedef Lock lock_type; public: lock_guard(lock_type& m, bool aq = true) : mut(m), owned(false){ acquire(aq); } ~lock_guard() { acquire(false); } void BOOST_REGEX_CALL acquire(bool aq = true) { if(aq && !owned) { mut.acquire(true); owned = true; } else if(!aq && owned) { mut.acquire(false); owned = false; } } private: lock_type& mut; bool owned; // VC6 warning suppression: lock_guard& operator=(const lock_guard&); }; class critical_section { public: critical_section() { InitializeCriticalSection(&hmutex);} critical_section(const critical_section&) { InitializeCriticalSection(&hmutex);} const critical_section& BOOST_REGEX_CALL operator=(const critical_section&) {return *this;} ~critical_section() {DeleteCriticalSection(&hmutex);} private: void BOOST_REGEX_CALL acquire(bool aq) { if(aq) EnterCriticalSection(&hmutex); else LeaveCriticalSection(&hmutex); } CRITICAL_SECTION hmutex; public: typedef lock_guard ro_guard; typedef lock_guard rw_guard; friend class lock_guard; }; inline bool BOOST_REGEX_CALL operator==(const critical_section&, const critical_section&) { return false; } inline bool BOOST_REGEX_CALL operator<(const critical_section&, const critical_section&) { return true; } typedef lock_guard cs_guard; BOOST_REGEX_DECL extern critical_section* p_re_lock; BOOST_REGEX_DECL extern unsigned int re_lock_count; #define BOOST_REGEX_GUARD(inst) boost::re_detail::critical_section::rw_guard g(inst); #else // BOOST_HAS_THREADS #define BOOST_REGEX_GUARD(inst) #endif // BOOST_HAS_THREADS #ifdef __BORLANDC__ #pragma option pop #endif } // namespace re_detail } // namespace boost #endif // sentry