📄 concrt.h
字号:
};
//
// This non-reentrant lock uses CRITICAL_SECTION and is intended for use in situations
// where it is known that the lock will not be taken recursively, and can thus be more
// efficiently implemented.
//
class _NonReentrantBlockingLock
{
public:
// Constructor for _NonReentrantBlockingLock
//
// The constructor is exported because of _NonReentrantLock's
// inclusion in DevUnitTests. It is also used in RM.
_CRTIMP _NonReentrantBlockingLock();
// Constructor for _NonReentrantBlockingLock
_CRTIMP ~_NonReentrantBlockingLock();
// Acquire the lock, spin if necessary
_CRTIMP void _Acquire();
// Tries to acquire the lock, does not spin
// Returns true if the lock is taken, false otherwise
_CRTIMP bool _TryAcquire();
// Releases the lock
_CRTIMP void _Release();
// An exception safe RAII wrapper.
class _Scoped_lock
{
public:
// Constructs a holder and acquires the specified lock
explicit _Scoped_lock(_NonReentrantBlockingLock& _Lock) : _M_lock(_Lock)
{
_M_lock._Acquire();
}
// Destroys the holder and releases the lock
~_Scoped_lock()
{
_M_lock._Release();
}
private:
_NonReentrantBlockingLock& _M_lock;
_Scoped_lock(const _Scoped_lock&); // no copy constructor
_Scoped_lock const & operator=(const _Scoped_lock&); // no assignment operator
};
private:
// Critical section requires windows.h. Hide the implementation so that
// user code need not include windows.h
_CONCRT_BUFFER _M_criticalSection[(4 * sizeof(void *) + 2 * sizeof(long) + sizeof(_CONCRT_BUFFER) - 1) / sizeof(_CONCRT_BUFFER)];
};
//
// A Reader-Writer Lock is intended for use in situations with many readers and rare
// writers.
//
// A writer request immediately blocks future readers and then waits until all current
// readers drain. A reader request does not block future writers and must wait until
// all writers are done, even those that cut in front of it. In any race between a
// reader and a writer, the writer always wins.
//
class _ReaderWriterLock
{
public:
// Constructor for _ReaderWriterLock
//
// The constructor and destructor are exported because of _ReaderWriterLock's
// inclusion in DevUnitTests. We may want to revisit whether we actually want
// to export this in the future.
_CRTIMP _ReaderWriterLock();
// Acquire lock for reading. Spins until all writers finish, new writers
// can cut in front of a waiting reader.
_CRTIMP void _AcquireRead();
// Release lock for reading. The last reader changes m_state to State.kFree
_CRTIMP void _ReleaseRead();
// Acquire lock for writing. Spin until no readers exist, then acquire lock
// and prevent new readers.
_CRTIMP void _AcquireWrite();
// Release lock for writing.
_CRTIMP void _ReleaseWrite();
// Try to acquire the write lock, do not spin if unable to acquire.
// Returns true if the acquisition worked, false otherwise
_CRTIMP bool _TryAcquireWrite();
// Returns true if it is in write state, false otherwise
bool _HasWriteLock() const
{
return (_M_state == _Write);
}
// Guarantees that all writers are out of the lock. This does nothing if there are no pending writers.
void _FlushWriteOwners();
// An exception safe RAII wrapper.
class _Scoped_lock
{
public:
// Constructs a holder and acquires the writer lock
explicit _Scoped_lock(_ReaderWriterLock& _Lock) : _M_lock(_Lock)
{
_M_lock._AcquireWrite();
}
// Destroys the holder and releases the writer lock
~_Scoped_lock()
{
_M_lock._ReleaseWrite();
}
private:
_ReaderWriterLock& _M_lock;
_Scoped_lock(const _Scoped_lock&); // no copy constructor
_Scoped_lock const & operator=(const _Scoped_lock&); // no assignment operator
};
// An exception safe RAII wrapper for reads.
class _Scoped_lock_read
{
public:
// Constructs a holder and acquires the reader lock
explicit _Scoped_lock_read(_ReaderWriterLock& _Lock) : _M_lock(_Lock)
{
_M_lock._AcquireRead();
}
// Destroys the holder and releases the reader lock
~_Scoped_lock_read()
{
_M_lock._ReleaseRead();
}
private:
_ReaderWriterLock& _M_lock;
_Scoped_lock_read(const _Scoped_lock_read&); // no copy constructor
_Scoped_lock_read const & operator=(const _Scoped_lock_read&); // no assignment operator
};
private:
// State enum where:
// -1 --> write mode
// 0 --> free
// n > 0 --> n readers have locked in read mode.
enum _State
{
_Write = -1,
_Free = 0,
_Read = 1
};
// The current state of the lock, mapping to the State enum. This is also
// an indicator of the number of readers holding the lock, for any number > 0.
volatile long _M_state;
// A writer increments this as soon as it wants to lock and decrements this
// after releasing the lock. To prevent writers from starving, a reader will
// wait until this counter is zero, and only then will try to obtain the lock.
volatile long _M_numberOfWriters;
// Spin-Wait-Until variant
static void __cdecl _WaitEquals(volatile const long& _Location, long _Value, long _Mask = 0xFFFFFFFF);
};
//
// An exception safe RAII wrapper for _malloca()
//
class _MallocaHolder
{
public:
_MallocaHolder(void *pMemory) : m_pMemory(pMemory)
{
}
~_MallocaHolder()
{
_freea(m_pMemory);
}
private:
void *m_pMemory;
};
// Forward declarations
class _StructuredTaskCollection;
class _TaskCollection;
class _UnrealizedChore;
} // namespace details
//**************************************************************************
// Public Namespace:
//
// Anything in the Concurrency namespace is intended for direct client consumption.
//
//**************************************************************************
//
// Forward declarations:
//
class Scheduler;
/// <summary>
/// This class describes an exception that is thrown due to failure to acquire a critical resource in the Concurrency Runtime.
/// </summary>
/// <remarks>
/// This exception is typically thrown when a call to the operating system from within the Concurrency Runtime
/// fails. The error code which would normally be returned from a call to the Win32 method <c>GetLastError</c> is
/// converted to a value of type <c>HRESULT</c> and can be retrieved via the <c>get_error_code</c> method.
/// </remarks>
/**/
class scheduler_resource_allocation_error : public std::exception
{
public:
/// <summary>
/// Constructs a <c>scheduler_resource_allocation_error</c> object.
/// </summary>
/// <param name="_Message">
/// A descriptive message of the error.
/// </param>
/// <param name="_Hresult">
/// The <c>HRESULT</c> value of the error that caused the exception.
/// </param>
/**/
_CRTIMP scheduler_resource_allocation_error(const char * _Message, HRESULT _Hresult) throw();
/// <summary>
/// Constructs a <c>scheduler_resource_allocation_error</c> object.
/// </summary>
/// <param name="_Hresult">
/// The <c>HRESULT</c> value of the error that caused the exception.
/// </param>
/**/
explicit _CRTIMP scheduler_resource_allocation_error(HRESULT _Hresult) throw();
/// <summary>
/// Returns the error code that caused the exception.
/// </summary>
/// <returns>
/// The <c>HRESULT</c> value of the error that caused the exception.
/// </returns>
/**/
_CRTIMP HRESULT get_error_code() const throw();
private:
HRESULT _Hresult;
};
/// <summary>
/// This class describes an exception that is thrown whenever an unsupported operating system is used.
/// The Concurrency Runtime does not support operating systems earlier than Windows XP with Service Pack 3.
/// </summary>
/**/
class unsupported_os : public std::exception
{
public:
/// <summary>
/// Constructs an <c>unsupported_os</c> object.
/// </summary>
/// <param name="_Message">
/// A descriptive message of the error.
/// </param>
/**/
explicit _CRTIMP unsupported_os(const char * _Message) throw();
/// <summary>
/// Constructs an <c>unsupported_os</c> object.
/// </summary>
/**/
_CRTIMP unsupported_os() throw();
};
/// <summary>
/// This class describes an exception that is thrown whenever an operation is performed which requires a scheduler
/// to be attached to the current context and one is not.
/// </summary>
/// <seealso cref="Scheduler Class"/>
/// <seealso cref="Scheduler::Attach Method"/>
/**/
class scheduler_not_attached : public std::exception
{
public:
/// <summary>
/// Constructs a <c>scheduler_not_attached</c> object.
/// </summary>
/// <param name="_Message">
/// A descriptive message of the error.
/// </param>
/**/
explicit _CRTIMP scheduler_not_attached(const char * _Message) throw();
/// <summary>
/// Constructs a <c>scheduler_not_attached</c> object.
/// </summary>
/**/
_CRTIMP scheduler_not_attached() throw();
};
/// <summary>
/// This class describes an exception that is thrown whenever the <c>Attach</c> method is called on a <c>Scheduler</c>
/// object which is already attached to the current context.
/// </summary>
/// <seealso cref="Scheduler Class"/>
/// <seealso cref="Scheduler::Attach Method"/>
/**/
class improper_scheduler_attach : public std::exception
{
public:
/// <summary>
/// Constructs an <c>improper_scheduler_attach</c> object.
/// </summary>
/// <param name="_Message">
/// A descriptive message of the error.
/// </param>
/**/
explicit _CRTIMP improper_scheduler_attach(const char * _Message) throw();
/// <summary>
/// Constructs an <c>improper_scheduler_attach</c> object.
/// </summary>
/**/
_CRTIMP improper_scheduler_attach() throw();
};
/// <summary>
/// This class describes an exception that is thrown whenever the <c>CurrentScheduler::Detach</c> method is called on
/// a context which has not been attached to any scheduler via the <c>Attach</c> method of a <c>Scheduler</c> object.
/// </summary>
/// <seealso cref="Scheduler Class"/>
/// <seealso cref="CurrentScheduler::Detach Method"/>
/// <seealso cref="Scheduler::Attach Method"/>
/**/
class improper_scheduler_detach : public std::exception
{
public:
/// <summary>
/// Constructs an <c>improper_scheduler_detach</c> object.
/// </summary>
/// <param name="_Message">
/// A descriptive message of the error.
/// </param>
/**/
explicit _CRTIMP improper_scheduler_detach(const char * _Message) throw();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -