// ===================================================
// Листинг 25. Работа с семафорами
//
// Файл semsign\semsign.cpp
//
// (C) A. Frolov, 1993
// ===================================================

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>

#define BYTE unsigned char
#define WORD unsigned int

extern "C" int GetNetWareShellVersion(char *,char *, char *);
extern "C" int OpenSemaphore(char *, int, long *, WORD *);
extern "C" int CloseSemaphore(long);
extern "C" int ExamineSemaphore(long, int *, WORD *);
extern "C" int SignalSemaphore(long);
extern "C" int WaitOnSemaphore(long, WORD);

void main(void) {

	char MajorVersion=0;
	char MinorVersion=0;
	char Revision=0;

	int ccode;
	long SemaphoreHandle;
	WORD OpenCount;
	int SemaphoreValue;

	printf("\n*SEMSIGN* (C) Frolov A., 1993\n");

// Проверяем наличие сетевой оболочки

	asm push si
	GetNetWareShellVersion(&MajorVersion,
			&MinorVersion, &Revision);
	asm pop si

	if(MajorVersion == 0) {
		printf("\nОболочка NetWare не загружена\n");
		return;
	}

// Открываем семафор с именем SEMLOCK

	ccode = OpenSemaphore("SEMLOCK", 1, &SemaphoreHandle,
		  &OpenCount);

	if(!ccode) {
		printf("Семафор SEMLOCK открыт\n");
		printf("Handle = %ld, OpenCount = %d\n",
			 SemaphoreHandle, OpenCount);
	}
	else  {
		printf("Ошибка при открытии семафора "
			 "SEMLOCK %02.2X\n", ccode);
		return;
	}

// Определяем текущее состояние семафора

	ccode = ExamineSemaphore(SemaphoreHandle,
		  &SemaphoreValue, &OpenCount);

	if(!ccode) {
		printf("SemaphoreValue = %d\n", SemaphoreValue);
	}
	else 	printf("Ошибка при получении состояния семафора "
			 "SEMLOCK %02.2X\n", ccode);

// Запрашиваем доступ к критическому ресурсу,
// ожидаем получение доступа в течение 20 секунд

	printf("Запрашиваем доступ к критическому ресурсу...\n");

	ccode = WaitOnSemaphore(SemaphoreHandle, 18*20);

	if(!ccode) {
		printf("Доступ к критическому ресурсу получен\n");
	}
	else {
		printf("Ресурс заблокирован, ошибка %02.2X\n", ccode);
		return;
	}

// Теперь, если мы получили доступ к ресурсу,
// можно выполнять с ним необходимые действия.
// В нашей программе мы ничего не делаем,
// просто ожидаем, пока оператор не нажмет
// любую клавишу

	printf("Нажмите любую клавишу для освобожения ресурса\n");
	getch();

// Освобождаем ресурс

	ccode = SignalSemaphore(SemaphoreHandle);

	if(!ccode) {
		printf("Ресурс освобожден\n");
	}
	else
		printf("Ошибка при освобождении ресурса %02.2X\n", ccode);

// Закрываем семафор

	ccode = CloseSemaphore(SemaphoreHandle);

	if(!ccode)
		printf("Семафор SEMLOCK закрыт\n");
	else
		printf("Ошибка при закрытии семафора "
			 "SEMLOCK %02.2X\n", ccode);
}

