TIP: Click on subject to list as thread! ANSI
echo: os2prog
to: All
from: Darin McBride
date: 1996-09-01 13:14:08
subject: question

C++ here, folks.  If you don't know/understand C++, you can skip this.  :-)

I have a simple pair of classes for locking (synchronization) under both
Win32 and OS/2, and was wondering if anyone here had some knowledge of this
that could help - if you know of any problems with the calls I'm making,
let me know, ok?

(This class should compile away to nothing under DOS where threads are non-existant.)

Thanks,

BTW - this code, for what it's worth, is declared to be in the public domain.

===lock.h===

//
// Lock class
// This class will use the appropriate locking mechanism for
// the operating system in question.  If your OS isn't here, please
// add it and send the modifications to:
//
// Darin McBride
// Fido: 1:342/708
// Email: mcbride{at}tower.alive.ampr.ab.ca
//

/*
 
 Example usage:
 
 class foo // accesses critical resources
 {
 private:
  LockSem m_ls;
 
  void AccessResource()
  {
   Lock locallock(m_ls);
   // do_stuff ... even with multiple "return"s!
  }
 }

 Be sure not to access other locked resources!
 */

/*
 
 Notes on implementations:
 
 WINNT:
 Critical sections are used.  I've heard that under NT, critical sections
 are the least overhead you can get.
 
 OS/2:
 Unnamed Mutual-Exclusion (mutex) semaphores are used.  Requesting the mutex
 is based on an unlimited timeout value (SEM_INDEFINATE_WAIT).
 
 */

#ifndef __cplusplus
#error C++ is required for these utilities
#endif

#if defined(__NT__)

#include 

#elif defined(__OS2__)

#ifndef INCL_DOSSEMAPHORE
#error You must include  with INCL_DOSSEMAPHORE before including LOCK.H!
#endif

#else
#error unknown OS
#endif

// This class must be in existance and available to all threads attempting
// to vie for the lockable resource.  For example, a class managing a
// resource would have a LockObject member variable, while each function
// that manipulates that resource would have a Lock variable
class LockSem
{
    friend class Lock;
    private:
#if defined(__NT__)
        CRITICALSECTION m_cs;
#elif defined(__OS2__)
        HMTX m_hmtx;
#elif defined(MSDOS) || defined(__DOS__)
        // nothing - this class becomes completely null
#else
#error LockSem not complete
#endif

    public:
        LockSem() : m_nLockCount(0)
        {
#if defined(__NT__)
            InitializeCriticalSection(&m_cs);
#elif defined(__OS2__)
            DosCreateMutexSem(NULL, &m_hmtx, 0L, FALSE);
#elif defined(MSDOS) || defined(__DOS__)
        // nothing - this class becomes completely null
#else
#error LockSem not complete
#endif
        }
        
        ~LockSem()
        {
#if defined(__NT__)
            DeleteCriticalSection(&m_cs);
#elif defined(__OS2__)
            DosReleaseMutexSem(m_hmtx);
#elif defined(MSDOS) || defined(__DOS__)
            // nothing - this class becomes completely null
#else
#error LockSem not complete
#endif
        }
        
        bool IsLocked()
        {
#if defined(__NT__)
            // This is _completely_ undocumented and may not even work...
            return m_cs.LockCount != 0;
#elif defined(__OS2__)
            PID pid;
            TID tid;
            ULONG ulCount;
            DosQueryMutexSem(m_hmtx, &pid, &tid, &ulCount);
            return ulCount != 0;
#elif defined(MSDOS) || defined(__DOS__)
            return false;
#else
#error LockSem not complete
#endif
        }
        
    private:
        // only for Lock to access
        void Lock()
        {
#if defined(__NT__)
            EnterCriticalSection(m_cs);
#elif defined(__OS2__)
            DosRequestMutexSem(m_hmtx,SEM_INDEFINITE_WAIT);
#elif defined(MSDOS) || defined(__DOS__)
        // nothing - this class becomes completely null
#else
#error LockSem not complete
#endif
            ++m_nLockCount;
        }
        
        void Unlock()
        {
#if defined(__NT__)
            LeaveCriticalSection(m_cs);
#elif defined(__OS2__)
            DosReleaseMutexSem(m_hmtx);
#elif defined(MSDOS) || defined(__DOS__)
        // nothing - this class becomes completely null
#else
#error LockSem not complete
#endif
            --m_nLockCount;
        }
};

class Lock
{
    private:
#if !defined(__DOS__) && !defined(MSDOS)
        LockSem& m_ls;
#endif
    public:
        Lock(LockSem& ls) : m_ls(ls)
        {
#if !defined(__DOS__) && !defined(MSDOS)
            m_ls.Lock();
#endif
        }
        ~Lock()
        {
#if !defined(__DOS__) && !defined(MSDOS)
            m_ls.Unlock();
#endif
        }
};

--- Maximus/2 3.01
* Origin: Tanktalus' Tower BBS (PVT) (1:342/708)
SEEN-BY: 50/99 270/101 620/243 625/100 711/401 409 410 413 430 808 809 934
SEEN-BY: 711/955 712/407 515 624 628 713/888 800/1
@PATH: 342/5015 61 3615/50 396/1 270/101 712/515 711/808 934

SOURCE: echomail via fidonet.ozzmosis.com

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.