// bslmt_muteximpl_win32.h -*-C++-*- // ---------------------------------------------------------------------------- // NOTICE // // This component is not up to date with current BDE coding standards, and // should not be used as an example for new development. // ---------------------------------------------------------------------------- #ifndef INCLUDED_BSLMT_MUTEXIMPL_WIN32 #define INCLUDED_BSLMT_MUTEXIMPL_WIN32 #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Provide a win32 implementation of 'bslmt::Mutex'. // //@CLASSES: // bslmt::MutexImpl<Platform::Win32Threads>: win32 specialization // //@SEE_ALSO: bslmt_mutex // //@DESCRIPTION: This component provides an implementation of 'bslmt::Mutex' for // Windows (win32), 'bslmt::MutexImpl<Platform::Win32Threads>', via the // template specialization: //.. // bslmt::MutexImpl<Platform::Win32Threads> //.. // This template class should not be used (directly) by client code. Clients // should instead use 'bslmt::Mutex'. // ///Usage ///----- // This component is an implementation detail of 'bslmt' and is *not* intended // for direct client use. It is subject to change without notice. As such, a // usage example is not provided. #include <bslscm_version.h> #include <bslmt_platform.h> #include <bsls_platform.h> #ifdef BSLMT_PLATFORM_WIN32_THREADS // Platform-specific implementation starts here. // Rather than setting 'WINVER' or 'NTDDI_VERSION', just forward declare the // Windows 2000 functions that are used. struct _RTL_CRITICAL_SECTION; typedef struct _RTL_CRITICAL_SECTION CRITICAL_SECTION, *LPCRITICAL_SECTION; typedef int BOOL; typedef unsigned long DWORD; extern "C" { __declspec(dllimport) BOOL __stdcall InitializeCriticalSectionAndSpinCount( LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount); __declspec(dllimport) void __stdcall DeleteCriticalSection( LPCRITICAL_SECTION lpCriticalSection); __declspec(dllimport) BOOL __stdcall TryEnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection); __declspec(dllimport) void __stdcall EnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection); __declspec(dllimport) void __stdcall LeaveCriticalSection( LPCRITICAL_SECTION lpCriticalSection); } // extern "C" namespace BloombergLP { namespace bslmt { template <class THREAD_POLICY> class MutexImpl; // ======================================= // class MutexImpl<Platform::Win32Threads> // ======================================= template <> class MutexImpl<Platform::Win32Threads> { // This class provides a full specialization of 'MutexImpl' for Windows. // It provides an efficient proxy for Windows critical sections, and // related operations. Note that the mutex implemented in this class is // *not* error checking, and is non-recursive. // TYPES public: enum { // Size of the buffer allocated for the critical section, in // pointer-sized elements. We have to make it public so we could // access it in a .cpp file to verify the size. #ifdef BSLS_PLATFORM_CPU_64_BIT // 5*8 = 40 bytes k_CRITICAL_SECTION_BUFFER_SIZE = 5 #else // 6*4 = 24 bytes k_CRITICAL_SECTION_BUFFER_SIZE = 6 #endif }; private: enum { // A Windows critical section has a configurable spin count. A lock // operation spins this many iterations (on, presumably, some atomic // integer) before sleeping on the underlying primitive. k_SPIN_COUNT = 30 }; // DATA void *d_lock[k_CRITICAL_SECTION_BUFFER_SIZE]; // NOT IMPLEMENTED MutexImpl(const MutexImpl&); MutexImpl& operator=(const MutexImpl&); public: // PUBLIC TYPES typedef _RTL_CRITICAL_SECTION NativeType; // The underlying OS-level type. Exposed so that other bslmt components // can operate directly on this mutex. // CREATORS MutexImpl(); // Create a mutex initialized to an unlocked state. ~MutexImpl(); // Destroy this mutex object. // MANIPULATORS void lock(); // Acquire a lock on this mutex object. If this object is currently // locked, then suspend execution of the current thread until a lock // can be acquired. Note that the behavior is undefined if the calling // thread already owns the lock on this mutex, and will likely result // in a deadlock. NativeType& nativeMutex(); // Return a reference to the modifiable OS-level mutex underlying this // object. This method is intended only to support other bslmt // components that must operate directly on this mutex. int tryLock(); // Attempt to acquire a lock on this mutex object. Return 0 on // success, and a non-zero value of this object is already locked, or // if an error occurs. void unlock(); // Release a lock on this mutex that was previously acquired through a // successful call to 'lock', or 'tryLock'. The behavior is undefined, // unless the calling thread currently owns the lock on this mutex. }; } // close package namespace // ============================================================================ // INLINE DEFINITIONS // ============================================================================ // --------------------------------------- // class MutexImpl<Platform::Win32Threads> // --------------------------------------- // CREATORS inline bslmt::MutexImpl<bslmt::Platform::Win32Threads>::MutexImpl() { InitializeCriticalSectionAndSpinCount( reinterpret_cast<_RTL_CRITICAL_SECTION *>(d_lock), k_SPIN_COUNT); } inline bslmt::MutexImpl<bslmt::Platform::Win32Threads>::~MutexImpl() { DeleteCriticalSection( reinterpret_cast<_RTL_CRITICAL_SECTION*>(d_lock)); } // MANIPULATORS inline void bslmt::MutexImpl<bslmt::Platform::Win32Threads>::lock() { EnterCriticalSection( reinterpret_cast<_RTL_CRITICAL_SECTION*>(d_lock)); } inline bslmt::MutexImpl<bslmt::Platform::Win32Threads>::NativeType& bslmt::MutexImpl<bslmt::Platform::Win32Threads>::nativeMutex() { return *reinterpret_cast<_RTL_CRITICAL_SECTION*>(d_lock); } inline int bslmt::MutexImpl<bslmt::Platform::Win32Threads>::tryLock() { return !TryEnterCriticalSection( reinterpret_cast<_RTL_CRITICAL_SECTION*>(d_lock)); } inline void bslmt::MutexImpl<bslmt::Platform::Win32Threads>::unlock() { LeaveCriticalSection( reinterpret_cast<_RTL_CRITICAL_SECTION*>(d_lock)); } } // close enterprise namespace #endif // BSLMT_PLATFORM_WIN32_THREADS #endif // ---------------------------------------------------------------------------- // Copyright 2015 Bloomberg Finance L.P. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ----------------------------- END-OF-FILE ----------------------------------