#include <iostream>
#include "COperation.h"
#include "nsSysteme.h"
#include "CExc.h"
class CSemaphore
{
private :
bool m_Proprietaire;
protected :
int m_Id;
public :
// CSemaphore (const char * const Nom);
CSemaphore (const char * const Nom, const int NbreRessources = 1);
~CSemaphore (void);
void P (void);
void V (void);
bool P_WouldBlock (void);
}; // CSemaphore
inline CSemaphore::CSemaphore (const char * const Nom,
const int NbreRessources = 1)
{
try
{
m_Id = nsSysteme::semget
(atoi (Nom), 1, IPC_EXCL | IPC_CREAT | 0700);
nsSysteme::semctl (m_Id,
0, SETVAL, NbreRessources);
m_Proprietaire = true;
}
catch (const CExcFctSystIPC & Exc)
{
if (Exc.GetErrno ()
!= EEXIST) throw;
m_Id = nsSysteme::semget
(atoi (Nom), 1, IPC_PRIVATE);
m_Proprietaire = false;
}
} // CSemaphore()
inline CSemaphore::~CSemaphore (void)
{
if (m_Proprietaire) nsSysteme::semctl (m_Id);
} // ~CSemaphore()
inline void CSemaphore::P (void)
{
COperation Op (0, -1);
nsSysteme::semop (m_Id, & Op, 1);
} // P()
inline bool CSemaphore::P_WouldBlock (void)
{
try
{
COperation Op (0,
-1, IPC_NOWAIT);
nsSysteme::semop
(m_Id, & Op, 1);
return false;
}
catch (const CExcFctSystIPC & Exc)
{
if (EAGAIN != Exc.GetErrno
()) throw;
return true;
}
} // P_WouldBlock()
inline void CSemaphore::V (void)
{
COperation Op (0, 1);
nsSysteme::semop (m_Id, & Op, 1);
} // V()
class CSemaphoreUser : public CSemaphore
{
private :
int m_NbreMinimal;
public :
CSemaphoreUser (const char * const Nom,
const int NbreRessources,
const int NbreMinimal = 0);
void P (void);
bool P_WouldBlock (void);
}; // CSemaphoreUser
inline CSemaphoreUser::CSemaphoreUser (const char * const Nom,
const int NbreRessources,
const int NbreMinimal = 0)
: CSemaphore (Nom, NbreRessources), m_NbreMinimal
(NbreMinimal) {}
inline void CSemaphoreUser::P (void)
{
COperation Op [2];
Op [0].SetNum (0);
Op [0].SetOp (-1 - m_NbreMinimal);
Op [0].SetFlg (0);
Op [1].SetNum (0);
Op [1].SetOp (m_NbreMinimal);
Op [1].SetFlg (0);
nsSysteme::semop (m_Id, Op, 2);
} // P()
// Hors question
inline bool CSemaphoreUser::P_WouldBlock (void)
{
try
{
COperation Op [2];
Op [0].SetNum (0);
Op [0].SetOp (-1
- m_NbreMinimal);
Op [0].SetFlg (IPC_NOWAIT);
Op [1].SetNum (0);
Op [1].SetOp (m_NbreMinimal);
Op [1].SetFlg (0);
nsSysteme::semop (m_Id, Op, 2);
return false;
}
catch (const CExcFctSystIPC & Exc)
{
if (EAGAIN != Exc.GetErrno
()) throw;
return true;
}
} // P_WouldBlock()
int ppal (int argc, char * argv []) throw (CExc)
{
if (1 != argc) throw CExc (string ("Usage :
") + argv [0]);
// Test du semaphore "user" et de P_WouldBlock :
CSemaphoreUser SemUser ("123321", 5, 2);
if (SemUser.P_WouldBlock ())
cout << "Aurait
ete bloquant" << endl;
else
cout << "N'a pas
bloque" << endl;
if (SemUser.P_WouldBlock ())
cout << "Aurait
ete bloquant" << endl;
else
cout << "N'a pas
bloque" << endl;
if (SemUser.P_WouldBlock ())
cout << "Aurait
ete bloquant" << endl;
else
cout << "N'a pas
bloque" << endl;
if (SemUser.P_WouldBlock ())
cout << "Aurait
ete bloquant" << endl;
else
cout << "N'a pas
bloque" << endl;
if (SemUser.P_WouldBlock ())
cout << "Aurait
ete bloquant" << endl;
else
cout << "N'a pas
bloque" << endl;
return 0;
} // ppal()