Česky
Kamil Dudka

Share Library (C++)

File detail

Name:DownloadMutexLock.cpp [Download]
Location: sharelib > src > sharelib
Size:2.7 KB
Last modification:2007-08-27 01:16

Source code

/**
 * @file MutexLock.cpp
 * @brief Platform-independent mutex representation
 * @author Kamil Dudka, xdudka00@gmail.com
 * @date 2007-05-15
 * @ingroup backend
 */
 
#include "MutexLock.h"
 
using namespace Share;
 
#ifdef _WIN32
 
Mutex::Mutex (RelocPtr<char> name) throw (ShareException):
  name_ (name)
{
}
 
Mutex::~Mutex() throw ()
{
}
 
void Mutex::lock(LockData *data) throw (ShareException)
{
    if (! (data-> m_hSemaphore = CreateSemaphoreA(0, 1L, LONG_MAX, name_)))
        throw ShareException ("Mutex: Unable to lock mutex - CreateSemaphoreA() failed");
 
    if( WaitForSingleObject(data-> m_hSemaphore, INFINITE) != WAIT_OBJECT_0 )
        throw ShareException ("Mutex: Unable to lock mutex - WaitForSingleObject() failed");
}
 
void Mutex::unlock(LockData *data) throw (ShareException)
{
    if( ReleaseSemaphore(data-> m_hSemaphore, 1L, NULL) == 0 )
        throw ShareException ("Mutex: Unable to unlock mutex - ReleaseSemaphore() failed");
 
    CloseHandle(data-> m_hSemaphore);
}
 
#endif // _WIN32
 
 
#ifdef _LINUX
 
/*
 * Copy-pasted from MDSTk
 */
#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
// Union semun defined in <sys/sem.h>
#else
union semun
{
    //! Value for SETVAL
    int val;
 
    //! Buffer for IPC_STAT and IPC_SET
    struct semid_ds *buf;
 
    //! Array for GETALL and SETALL
    unsigned short int *array;
 
    //! Buffer for IPC_INFO
    struct seminfo *__buf;
};
#endif
 
Mutex::Mutex (RelocPtr<char>) throw (ShareException)
{
    // Create a new unique semaphore
    m_iSemaphore = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | 0600);
    if( m_iSemaphore == -1 )
          throw ShareException ("Constructor Semaphore::Semaphore() failed");
 
    // Initialize the semaphore value
    unlock(0);
}
 
Mutex::~Mutex() throw ()
{
  // Close the semaphore
  semctl (m_iSemaphore, 0, IPC_RMID);
}
 
void Mutex::lock(LockData *) throw (ShareException)
{
    // Prepare semaphore operation
    struct sembuf LockSem;
    LockSem.sem_num = 0;
    LockSem.sem_op = -1;
    LockSem.sem_flg = 0;
 
    // Wait for the semaphore
    int iResult = 0;
    do {
        iResult = semop(m_iSemaphore, &LockSem, 1);
    } while( iResult == -1 && errno == EINTR );
 
    if( iResult == -1 )
        throw ShareException ("Mutex: Unable to lock mutex - semop() failed");
}
 
void Mutex::unlock(LockData *) throw (ShareException)
{
    // Prepare semaphore operation
    struct sembuf UnlockSem;
    UnlockSem.sem_num = 0;
    UnlockSem.sem_op = 1;//iValue;
    UnlockSem.sem_flg = 0;//SEM_UNDO;
 
    if( semop(m_iSemaphore, &UnlockSem, 1) == -1 )
        throw ShareException ("Mutex: Unable to unlock mutex - semop() failed");
}
 
#endif // _LINUX