/* ***********************IMPORTANT *********************************************
 *  Copyright (C) 2004-2007 Thierry Lagarde <tlagarde@users.sourceforge.net>
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License.
 *
 *
 *                      ********************
 *
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *
 *                      ********************
 *
 *
 * You are highly encouraged to send your changes to <tlagarde@users.sourceforge.net>
 * for possible incorporation into the main distribution.
 * By sending these changes to <tlagarde@users.sourceforge.net>,
 * it is assumed that you are offering <tlagarde@users.sourceforge.net>
 * the unlimited, non-exclusive right to reuse, modify, and relicense the code.
 *
 *
 *                      ********************
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **************************************************************************************/
#include "Semaphore.h"
#include "Com/Initialisation_Com.h"
#include "Debug.h"


#ifndef         __WINDOWS_ENABLE
#include <errno.h>

void Attendre_Semaphore (sem_t * sem)
{
	ERROR_if (sem == NULL);
	if (sem_wait (sem) == -1) {
		switch (errno) {
		    case EINTR:
			    debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "EINTR : (A signal interrupted)  - %s", strerror (errno));
		    case EINVAL:
			    debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "EINVAL : (Does not refer to a valid semaphore)  - %s", strerror (errno));
		    case EAGAIN:
			    debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "EAGAIN  - %s", strerror (errno));
		    default:
			    debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s", strerror (errno));
			    break;
		}
	}
}

void Liberation_Semaphore (sem_t * sem)
{
	ERROR_if (sem == NULL);
	if (sem_post (sem) == -1) {
		switch (errno) {
		    case EINVAL:
			    debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "EINVAL : (Does not refer to a valid semaphore)  - %s", strerror (errno));
		    default:
			    debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "%s", strerror (errno));
			    break;
		}
	}
}

int Valeur_Semaphore (sem_t * sem)
{
	int       valeur;
	
	ERROR_if (sem == NULL);
	sem_getvalue (sem, &valeur);
	return valeur;
}

void Initialisation_Semaphore_Gestion_Thread (void)
{
	sem_init (&Semaphore_Nouveau_Equipement, 0, 0);
	sem_init (&Semaphore_Thread_Scan, 0, Info_Demarrage.Nb_Thread_Max);
}

void Initialisation_Semaphore (void)
{
	sem_init (&Semaphore_Info, 0, 1);
	sem_init (&Semaphore_Control_Usage_Socket, 0, 1);
	sem_init (&Semaphore_Notification_Equipement, 0, 1);
	sem_init (&Semaphore_Debug, 0, 1);
	sem_init (&Semaphore_Notification_Port, 0, 1);
	sem_init (&Semaphore_Equipement, 0, 1);
	sem_init (&Semaphore_Snmp, 0, 1);
	sem_init (&Semaphore_Communication, 0, 1);
	sem_init (&Semaphore_DNS, 0, 1);
	sem_init (&Semaphore_WakeUp, 0, 1);
	sem_init (&Semaphore_Mem, 0, 1); 
	sem_init (&Semaphore_Ping_Equipement, 0, 1); 
	sem_init (&Semaphore_Etat_Thread, 0, 1); 
	sem_init (&Semaphore_Thread, 0, 1); 
	sem_init (&Semaphore_Scan_Arp_Sous_Reseau, 0, 2); 
	sem_init (&Semaphore_Fonction_Externe, 0, 1);
	sem_init (&Semaphore_BackTrace, 0, 1);
	sem_init (&Semaphore_Log_File, 0, 1);
}

#else


void Attendre_Semaphore (HANDLE sem)
{ 
	if (WaitForSingleObject (sem, INFINITE)== WAIT_FAILED)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "WaitForSingleObject  error: %ld\n", GetLastError ());
	if ((sem==Semaphore_Nouveau_Equipement) || (sem==Semaphore_Thread_Scan)){
		
		if (WaitForSingleObject (Semaphore_Compteur, INFINITE)== WAIT_FAILED)
			debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "WaitForSingleObject  error: %ld\n", GetLastError ());
		if (sem==Semaphore_Nouveau_Equipement)
			Compteur_Nouveau_Equipement++;
		if (sem==Semaphore_Thread_Scan)
			Compteur_Thread_Scan--;
		if (!ReleaseSemaphore (Semaphore_Compteur, 1, NULL))
			debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "ReleaseSemaphore  error: %ld\n", GetLastError ());
	}
} 

void Liberation_Semaphore (HANDLE sem)
{
	if (!ReleaseSemaphore (sem, 1, NULL))
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "ReleaseSemaphore  error: %ld\n", GetLastError ());
	if ((sem==Semaphore_Nouveau_Equipement) || (sem==Semaphore_Thread_Scan)){

		if (WaitForSingleObject (Semaphore_Compteur, INFINITE)== WAIT_FAILED)
			debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "WaitForSingleObject  error: %ld\n", GetLastError ());
		if (sem==Semaphore_Nouveau_Equipement)
			Compteur_Nouveau_Equipement--;
		if (sem==Semaphore_Thread_Scan)
			Compteur_Thread_Scan++;
		if (!ReleaseSemaphore (Semaphore_Compteur, 1, NULL))
			debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "ReleaseSemaphore  error: %ld\n", GetLastError ());
	}
}

int Valeur_Semaphore (HANDLE *sem)
{
	int       valeur;
 
	if (*sem==Semaphore_Nouveau_Equipement)
		return Compteur_Nouveau_Equipement;
	if (*sem==Semaphore_Thread_Scan)
		return Compteur_Thread_Scan;
	return 1;
}

void Initialisation_Semaphore_Gestion_Thread (void)
{
	Compteur_Nouveau_Equipement = 0;  
	Compteur_Thread_Scan = Info_Demarrage.Nb_Thread_Max;

	if ((Semaphore_Nouveau_Equipement = CreateSemaphore (NULL, 0, 65535, NULL)) == NULL)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "CreateSemaphore(Semaphore_Nouveau_Equipement) error: %ld\n", GetLastError ());
	if ((Semaphore_Thread_Scan = CreateSemaphore (NULL, Info_Demarrage.Nb_Thread_Max, Info_Demarrage.Nb_Thread_Max, NULL)) == NULL)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "CreateSemaphore(Semaphore_Thread_Scan) error: %ld\n", GetLastError ());


	if ((Semaphore_Compteur = CreateSemaphore (NULL, 1, 1, NULL)) == NULL)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "CreateSemaphore(Semaphore_Compteur) error: %ld\n", GetLastError ());
}

void Initialisation_Semaphore (void)
{
	
	if ((Semaphore_Info = CreateSemaphore (NULL, 1, 1, NULL)) == NULL)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "CreateSemaphore(Semaphore_Info) error: %ld\n", GetLastError ());
	if ((Semaphore_Control_Usage_Socket = CreateSemaphore (NULL, 1, 1, NULL)) == NULL)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "CreateSemaphore(Semaphore_Control_Usage_Socket) error: %ld\n", GetLastError ());
	if ((Semaphore_Notification_Equipement = CreateSemaphore (NULL, 1, 1, NULL)) == NULL)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "CreateSemaphore(Semaphore_Notification_Equipement) error: %ld\n", GetLastError ());
	if ((Semaphore_Debug = CreateSemaphore (NULL, 1, 1, NULL)) == NULL)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "CreateSemaphore(Semaphore_Debug) error: %ld\n", GetLastError ());
	if ((Semaphore_Notification_Port = CreateSemaphore (NULL, 1, 1, NULL)) == NULL)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "CreateSemaphore(Semaphore_Notification_Port) error: %ld\n", GetLastError ());
	if ((Semaphore_Equipement = CreateSemaphore (NULL, 1, 1, NULL)) == NULL)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "CreateSemaphore(Semaphore_Equipement) error: %ld\n", GetLastError ());
	if ((Semaphore_Snmp = CreateSemaphore (NULL, 1, 1, NULL)) == NULL)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "CreateSemaphore(Semaphore_Snmp) error: %ld\n", GetLastError ());
	if ((Semaphore_Communication = CreateSemaphore (NULL, 1, 1, NULL)) == NULL)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "CreateSemaphore(Semaphore_Communication) error: %ld\n", GetLastError ());
	if ((Semaphore_DNS = CreateSemaphore (NULL, 1, 1, NULL)) == NULL)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "CreateSemaphore(Semaphore_DNS) error: %ld\n", GetLastError ());
	if ((Semaphore_WakeUp = CreateSemaphore (NULL, 1, 1, NULL)) == NULL)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "CreateSemaphore(Semaphore_WakeUp) error: %ld\n", GetLastError ());
	if ((Semaphore_Mem = CreateSemaphore (NULL, 1, 1, NULL)) == NULL)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "CreateSemaphore(Semaphore_Mem) error: %ld\n", GetLastError ());
	if ((Semaphore_Ping_Equipement = CreateSemaphore (NULL, 1, 1, NULL)) == NULL)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "CreateSemaphore(Semaphore_Ping_Equipement) error: %ld\n", GetLastError ());
	if ((Semaphore_Etat_Thread = CreateSemaphore (NULL, 1, 1, NULL)) == NULL)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "CreateSemaphore(Semaphore_Etat_Thread) error: %ld\n", GetLastError ());
	if ((Semaphore_Thread = CreateSemaphore (NULL, 1, 1, NULL)) == NULL)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "CreateSemaphore(Semaphore_Thread) error: %ld\n", GetLastError ());
	if ((Semaphore_Scan_Arp_Sous_Reseau = CreateSemaphore (NULL, 1, 2, NULL)) == NULL)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "CreateSemaphore(Semaphore_Scan_Arp_Sous_Reseau) error: %ld\n", GetLastError ());
	if ((Semaphore_Fonction_Externe = CreateSemaphore (NULL, 1, 1, NULL)) == NULL)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "CreateSemaphore(Semaphore_Fonction_Externe) error: %ld\n", GetLastError ());
	if ((Semaphore_BackTrace = CreateSemaphore (NULL, 1, 1, NULL)) == NULL)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "CreateSemaphore(Semaphore_BackTrace) error: %ld\n", GetLastError ());
	if ((Semaphore_Log_File = CreateSemaphore (NULL, 1, 1, NULL)) == NULL)
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "CreateSemaphore(Semaphore_Log_File) error: %ld\n", GetLastError ());
}
#endif
