fclt Logo
Mutex and Event classes
Classe Mutex et Event

1. Mutex class Classe Mutex
A mutex is a synchronisation object. It state is signaled when it's not owned by any thread and not signaled when a thread owns it. A mutex object can only be owned by one and only one thread at a time.
Un mutex est un objet servant à la synchronisation. Il est dans un état signalé lorsque aucun thread ne possède le mutex et non-signalé quand un thread le possède. Un objet mutex ne peut appartenir qu'à un et unseul thread à la fois. 

#ifndef MUTEX_H
#define MUTEX_H

#include <windows.h>
//------------------------------------------------------------
namespace mlLib
{

class Mutex
{
  private:
    HANDLE MutexHandle_;
    bool AlreadyExists_;
    Mutex(const Mutex&);
    Mutex& operator=(const Mutex&);
  public:
    /*
     * If a mutex is created with a given name and a mutex with
     * this name already exists, Windows doesn't report an error,
     * instead CreateMutex() returns the same handle as the previously
     * created one. If the mutex already exists, GetLastError()
     * returns ERROR_ALREADY_EXISTS.
     * An alternative is to first open the mutex, if it doesn't exist
     * OpenMutex() returns NULL. If it's the case, we create it.
     *
     * Mutex(const std::string& name):AlreadyExists_(false),
     *  MutexHandle_(OpenMutex(MUTEX_ALL_ACCESS,TRUE,name.c_str()))
     * {
     * if(MutexHandle_ == NULL)
     *    MutexHandle_ = CreateMutex(NULL,TRUE,name.c_str());
     *  else AlreadyExists_=true;
     * }
     *
     * AlreadyExists() yields true if the mutex already existed
     * when we tried to create it.
     */
    Mutex(const std::string& name):AlreadyExists_(false),
        MutexHandle_(CreateMutex(NULL,TRUE,name.c_str()))
    {
      if(GetLastError() == ERROR_ALREADY_EXISTS)
        AlreadyExists_ = true;
    }
    ~Mutex()
    {
      ReleaseMutex(MutexHandle_);
      CloseHandle(MutexHandle_);
    }
    bool AlreadyExists()const{return AlreadyExists_;}
    operator bool()const{return MutexHandle_!=HANDLE(NULL);}
    HANDLE GetHandle(){return MutexHandle_;}
};
//------------------------------------------------------------
//end namspace mlLib
#endif

Since a mutex can only be owned by one thread, it is frequently used to prevent an application from being launched more than one time. Here is a sample:
Etant donné qu'un mutex ne peut appartenir qu'à un seul thread, il est souvent utilisé pour empêcher le lancement multiple d'une même application. Voici un exemple:

#include <windows.h>
#include <iostream>
#include "mutex.h"

int main()
{
  mlLib::Mutex mutex("A unique name");
  if(mutex)
  {
    if(mutex.AlreadyExists())
    {
      MessageBox(NULL,
                 "This application is already running",
                 "Mutex test",
                 MB_OK | MB_ICONWARNING);
      return -1;
    }
  }
  else
  {
    std::cout<<"Unable to create mutex"<<std::endl;
    return -1;
  }
  std::cout<<"Press ctrl-C to quit"<<std::endl;
  for(;;);
  return 0;
}


2. Event class Classe Event
An event is also a synchronization object. The difference with the mutex object is that you can explicitly set or reset the event with SetEvent() or ResetEvent(). Note that resetting the event may be automatic depending on the way you created the event. It is often used with thread to send a signal to a thread. Here is an implementation of the Event class:
Un event (événement) est aussi un objet utilisé pour la synchronisation de thread. La différence avec un mutex est que l'event, vous pouvez le resetté ou le mettre à l'état signalé explicitement. Le reset peut aussi être automatique dépendant de la façon dont vous créez l'event. Voici mon implémentation d'une classe Event:

#ifndef EVENT_H
#define EVENT_H

#include <windows.h>
//------------------------------------------------------------
namespace mlLib
{

class Event
{
  private:
    HANDLE handle_;
    Event(const Event&);
    Event& operator=(const Event&);
  public:
      Event()
      {
        // Create event in non-signaled state and manual reset
        // after every Wait

        handle_=CreateEvent(NULL,true,false,NULL);
      }
      ~Event()
      {
        CloseHandle(handle_);
      }
      // Put event into signaled state
      bool Set(){return SetEvent(handle_);}
      // Put event into non-signaled state
      bool Reset(){return ResetEvent(handle_;}
      // Wait until event is in signaled state
      DWORD WaitFor(DWORD delay=INFINITE)
      {
        // Wait until event is in signaled state
        DWORD res=WaitForSingleObject(handle_,delay);
        ResetEvent(handle_);
        return res;
      }
      HANDLE Handle()const{return handle_;}
      operator bool()const{return handle_!=HANDLE(NULL);}
};

//end namespace mlLib
#endif

You can download the classes shown above and the mutex test application here.
Vous pouvez télécharger ici les deux classes ci-dessus ainsi que l'exemple d'application utilisant un mutex.