//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
//******************************************************************************
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//******************************************************************************

#pragma once

#include <windows.h>

/////////////////////////////////////////////////////////////////////////////
// AFXMT - MFC Multithreaded Extensions (Syncronization Objects)

// Classes declared in this file

//CObject
    class CSyncObject;
//        class CSemaphore; Do not supported by WinCE
        class CMutex;
        class CEvent;
        class CCriticalSection;

class CSingleLock;
//class CMultiLock; Unsupported by WinCE


/////////////////////////////////////////////////////////////////////////////
// Basic synchronization object

class CSyncObject 
{

// Constructor
public:
    CSyncObject(LPCTSTR pstrName);

// Attributes
public:
    operator HANDLE() const;
    HANDLE  m_hObject;

// Operations
    virtual BOOL Lock(DWORD dwTimeout = INFINITE);
    virtual BOOL Unlock() = 0;
    virtual BOOL Unlock(LONG /* lCount */, LPLONG /* lpPrevCount=NULL */)
        { return TRUE; }

// Implementation
public:
    virtual ~CSyncObject();
    friend class CSingleLock;
//    friend class CMultiLock; Unsupported by WinCE
};

/////////////////////////////////////////////////////////////////////////////
// CSemaphore
/*  Not supported by WinCE */
class CSemaphore : public CSyncObject
{

// Constructor
public:
    CSemaphore(LONG lInitialCount = 1, LONG lMaxCount = 1,
        LPCTSTR pstrName=NULL, LPSECURITY_ATTRIBUTES lpsaAttributes = NULL);
    DWORD GetLockedCount() { return dw_Locked; };
// Implementation
public:
    virtual ~CSemaphore();
    virtual BOOL Lock(DWORD dwTimeout = INFINITE) {
        dw_Locked++;
        BOOL bReturn=CSyncObject::Lock(dwTimeout);
        dw_Locked--;
        return bReturn;
    }
    virtual BOOL Unlock() { return Unlock(1); };
    virtual BOOL Unlock(LONG lCount, LPLONG lprevCount = NULL);
private:
    DWORD dw_Locked;
};

/////////////////////////////////////////////////////////////////////////////
// CMutex

class CMutex : public CSyncObject
{

// Constructor
public:
    CMutex(BOOL bInitiallyOwn = FALSE, LPCTSTR lpszName = NULL,
        LPSECURITY_ATTRIBUTES lpsaAttribute = NULL);

// Implementation
public:
    virtual ~CMutex();
    BOOL Unlock();
};

/////////////////////////////////////////////////////////////////////////////
// CEvent

class CEvent : public CSyncObject
{

// Constructor
public:
    CEvent(BOOL bInitiallyOwn = FALSE, BOOL bManualReset = FALSE,
        LPCTSTR lpszNAme = NULL, LPSECURITY_ATTRIBUTES lpsaAttribute = NULL);

// Operations
public:
    BOOL Unlock();
    BOOL SetEvent()
    { ASSERT(m_hObject != NULL); return ::SetEvent(m_hObject); }
    BOOL PulseEvent()
    { ASSERT(m_hObject != NULL); return ::PulseEvent(m_hObject); }
    BOOL ResetEvent()
    { ASSERT(m_hObject != NULL); return ::ResetEvent(m_hObject); }

// Implementation
public:
    virtual ~CEvent();
};

/////////////////////////////////////////////////////////////////////////////
// CCriticalSection


class CCriticalSection : public CSyncObject
{

// Constructor
public:
    CCriticalSection(): CSyncObject(NULL)
    { ::InitializeCriticalSection(&m_sect); };

// Attributes
public:
    operator CRITICAL_SECTION*() { return &m_sect; };
    CRITICAL_SECTION m_sect;

// Operations
public:
    BOOL Unlock()
    { ::LeaveCriticalSection(&m_sect); return TRUE; };
    BOOL Lock()
    { ::EnterCriticalSection(&m_sect); return TRUE; };
    BOOL Lock(DWORD /*dwTimeout*/) { return Lock();};

// Implementation
public:
    virtual ~CCriticalSection()
    { ::DeleteCriticalSection(&m_sect); };
};

