//***************************************************************************
// Mutexes are global objects that can be accessed by other processes
// When two processes open a mutex with the same name, they refer to the
// same mutex. This allows multiple processes to be synchronized.
//
// This file gives a simple example of the implementation
// of a mutex that is used to read/write a common boolean 
// variable called "stop_streaming". I compiled it with Borland C++
// but it must be compatible with any other compiler.
// It is based on the standard Microsoft Windows library.
//
//
// Copyright OMP-CNRS Jean-Louis Prieur
// JLP Version 10/10/2007
//***************************************************************************
# include <stdlib.h>
# include <stdio.h>

// Prototypes included here: 
int Create_StopStreamingMutex();
int Delete_StopStreamingMutex();
int Read_StopStreamingMutex(BOOL &stop_streaming);
int Write_StopStreamingMutex(BOOL stop_streaming);

// Mutex for handling "Stop" button:
static HANDLE hStopStreamingMutex = NULL;
static BOOL stop_streaming_saved_value = TRUE;
static char sss[120];

////////////////////////////////////////////////////////////////////////
/////////////////// Summary: ////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// Create a mutex with:
//  hStopStreamingMutex = CreateMutex(NULL,      // No security attributes
//                                    FALSE,     // Initially not owned
//                                    "StopStreamingMutex");   // Name
// Once created the mutex can be accessed by (wait time in milliseconds)
//  if(WaitForSingleObject(hStopStreamingMutex, 10000) == WAIT_TIMEOUT)
//     {
// When access is ended, release it to other threads with
//     ReleaseMutex(hStopStreamingMutex);
//     }
////////////////////////////////////////////////////////////////////////

/**************************************************************************
* Routine to create the StopStreaming Mutex:
**************************************************************************/
int Create_StopStreamingMutex() {
int status = -1;

  hStopStreamingMutex = CreateMutex(NULL,      // No security attributes
                                    FALSE,     // Initially not owned
                                    "StopStreamingMutex");   // Name

 if(hStopStreamingMutex == NULL) {
   MessageBox(NULL, "Error creating mutex", "CreateStopStreamingMutex",
                 MB_OK | MB_ICONEXCLAMATION | MB_SETFOREGROUND);
   return(-1);
   }
 else {
   status = 0;
 }

return(status);
}
/**************************************************************************
* Routine to delete the StopStreaming Mutex:
**************************************************************************/
int Delete_StopStreamingMutex() {
int status = -1;
 if(hStopStreamingMutex != NULL) {
   CloseHandle(hStopStreamingMutex);
   hStopStreamingMutex = NULL;
   status = 0;
   } else {
   status = -1;
   }

return (status);
}
/**************************************************************************
* Routine to access the StopStreaming Mutex and read the current status:
**************************************************************************/
int Read_StopStreamingMutex(BOOL &stop_streaming) {
DWORD WaitResult;
int status = -1;
 if(hStopStreamingMutex == NULL) return(-1);

 WaitResult = WaitForSingleObject(hStopStreamingMutex, 1000);
  if (WaitResult == WAIT_FAILED || WaitResult == WAIT_TIMEOUT) {
    sprintf(sss,"WaitForSingleObject(hStopStreaming,1000) returned %d",
            WaitResult);
    MessageBox(NULL, sss, "StopStreamingMutex",
               MB_OK | MB_ICONEXCLAMATION | MB_SETFOREGROUND);
      status = -1;
    } else {
      stop_streaming = stop_streaming_saved_value;
      ReleaseMutex(hStopStreamingMutex);
      status = 0;
    }
return(status);
}
/**************************************************************************
* Routine to access the StopStreaming Mutex and modify the current status:
**************************************************************************/
int Write_StopStreamingMutex(BOOL stop_streaming) {
DWORD WaitResult;
int status = -1;
 if(hStopStreamingMutex == NULL) return(-1);

 WaitResult = WaitForSingleObject(hStopStreamingMutex, 1000);
  if (WaitResult == WAIT_FAILED || WaitResult == WAIT_TIMEOUT) {
    sprintf(sss,"WaitForSingleObject(hStopStreaming,1000) returned %d",
            WaitResult);
    MessageBox(NULL, sss, "StopStreamingMutex",
               MB_OK | MB_ICONEXCLAMATION | MB_SETFOREGROUND);
      status = -1;
    } else {
      stop_streaming_saved_value = stop_streaming;
      ReleaseMutex(hStopStreamingMutex);
      status = 0;
    }
return(status);
}