This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Semaphore Lock Failed Error


Our program is failing in creating and acquiring lock on the
semaphore. Created a test program 'semtest.c'. It is creating the
semaphore using the program semaphore.c. Compiled and executed using
the latest CYGWIN- 2.4.1. It is failing at line

if  ((semval = semctl(*id, 1, GETVAL, semctl_arg)) < 0 )

with error no 22.

Code for semtest.c and semaphore.c are attached here.
/* semmain.c - test */
#define PROG_NAME "SEMTEST"
#define TITLE "SEMTEST Semaphore Test Stub - Version 0.1 (10-Dec-1992)"
#define USAGE "Usage: semtest c|o"

#ifndef lint
static char *sccs_id="$Id: semtest.c,v 7.0 2000/08/24 15:59:12 growe Exp $";
#endif

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>

#ifndef LOCAL_INC
#include <kinsys.h>
#include <semaphore.h>
#include <errormsg.h>

#else
#include <kinsys.h>
#include <semaphore.h>
#include <errormsg.h>
#endif

static int sem = SEM_NULL;
static key_t key = 0x123d4a;

int main(int argc, char *argv[])
{
	printf("\n%s\n", TITLE);
	printf("\n%s\n", USAGE);
	if (argc != 2)
	{
		printf("\n%s\n", USAGE);
		exit(EXIT_FAILURE);
	}


	switch (argv[1][0])
	{
	case 'c':
		if (SemCreate(&sem, key, SEM_BINARY) EQ FAIL)
			goto ErrExit;
		printf("Semaphore Created key: 0x%x    sem: %d\n", key, sem);
		break;

	case 'o':
		if (SemOpen(&sem, key) EQ FAIL)
			goto ErrExit;
		printf("Semaphore Opened key: 0x%x    sem: %d\n", key, sem);
		break;

	default:
		printf("\n%s\n", USAGE);
		exit(EXIT_FAILURE);

	}


	printf("About to Wait/lock on semaphore\n");
	if (SemWait(sem) EQ FAIL)
		goto ErrExit;

	printf("semaphore locked\n");

	printf("Press [RETURN] to continue and unlock semaphore\n");
	(void) getchar();

	printf("About to Signal/unlock on semaphore\n");
	if (SemSignal(sem) EQ FAIL)
		goto ErrExit;
	printf("semaphore unlocked\n");


	printf("About to Close on semaphore\n");
	if (SemClose(sem) EQ FAIL)
		goto ErrExit;
	sem = SEM_NULL;

	printf("semaphore closed\n");

	(void)MsgClose(mhDefault);
	printf("Program Terminated Successfully\n");
	exit(EXIT_SUCCESS);
	return(SUCCESS);

ErrExit:
	(void) EsTraceBack();
	(void)MsgClose(mhDefault);
	printf("Program Terminated with error\n");
	exit(EXIT_FAILURE);
	return(FAIL);
}

 /*
 *	Description:        Provides a simpler and safer interface to the UNIX
 *                      System V Release 4 semaphores. Seven functions are
 *                      provided.
 *
 *                      1.  id = SemCreate(key, value);
 *                      2.  id = SemOpen(key);
 *                      3.  SemWait(id);
 *                      4.  SemSignal(id);
 *                      5.  SemOp(id, amount);
 *                      6.  SemClose(id);
 *                      7.  SemRm(id);

 *
 *	Portability Issues:	This implementation requires System V semaphore
 *                      facility.
 *
 *	Edit History:
 *
 *
 */

#ifndef lint
static char *sccs_id="$Id: semaphore.c,v 7.2 2001/03/26 10:54:28 asealy Exp $";
#endif

#include <stdio.h>
#include <stdlib.h>
#include <machine.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <errno.h>
extern int errno;

#define SEM_
#include <kinsys.h>
#include <debug.h>
#include <errormsg.h>
#include <semaphore.h>
#include <semaphore.mh>
#include <ux.h>					/* General UNIX messages */
#include <ux.mh>					/* General UNIX messages */

#define BIGCOUNT 10000 /* Initial value of process counter */

#if !SEMUN_DEFINED
union semun {
  int val;
  struct semid_ds *buf;
  ushort *array;
} semctl_arg;
#else
union semun semctl_arg;
#endif

typedef struct sembuf SEMBUF;

/* Prototypes for local functions */

/*
 * Define the semaphore operation arrays for the semop() calls.
 */

static SEMBUF	op_lock[2] = {
	2, 0, 0,		/* wait for [2] (lock) to equal 0 */
	2, 1, SEM_UNDO	/* then incrrement [2] to 1 - this locks it */
					/* UNDO to release the lock it process exits
					   before explicitly unblocking */
	};

static SEMBUF op_endcreate[2] = {
	1, -1, SEM_UNDO,
	2, -1, SEM_UNDO
};

static SEMBUF op_open[1] = {
	1, -1, SEM_UNDO
};

static SEMBUF op_close[3] = {
	2, 0, 0,
	2, 1, SEM_UNDO,
	1, 1, SEM_UNDO
};

static SEMBUF op_unlock[1] = {
	2, -1, SEM_UNDO
};

static SEMBUF op_op[1] = {
	0, 99, SEM_UNDO
};


/************************************************************************
 * Name:            SemCreate
 *
 * Function:
 *
 * Input:           key - the IPC key that identifies the semaphore.
 *                  initval - initial value of the semaphore.
 *
 * Output           *id - the identifier of this semaphore.
 *
 * Return:          SUCCESS or FAIL
 *
 * Side Effects:    none
 *
 * Procedure:       1.
 *                  2.
 *                  3.
 ************************************************************************/

STATUS
SemCreate(int *id, key_t key, int initval)
{

    printf(" \n in semcretae");

    printf("\n SEMUN_DEFINED = %i  " , SEMUN_DEFINED);

	register int semval;

    printf(" \n After Register = %i  ", semval);

	if (key EQ IPC_PRIVATE)
	{
		printf(" \n SEM, Not intended for private semaphores");
		goto ErrExit;
	}

	else if (key EQ (key_t) -1)
	{
		printf("\nSEM, probably an ftok() error by caller");
		goto ErrExit;
	}

again:
	if ( (*id = semget(key, 3, 0666 | IPC_CREAT)) < 0)
	{
		printf("\nSEM, SemCreate, semget access/limits errno %d", errno);
		goto ErrExit;
	}


	if (semop(*id, &op_lock[0], 2) < 0)
	{
		if (errno EQ EINVAL)
			goto again;
		printf("\nSEM, Can't lock...: errno = %d", errno);
		goto ErrExit;
	}

	/*
	 * Get the value of the process counter. If it equals zero
	 * then no one has initialised the semaphore yet.
	 */

	semctl_arg.val = 0;

	if ( (semval = semctl(*id, 1, GETVAL, semctl_arg)) < 0)
	{
		printf("\n SEM, can't GETVAL..: errno = %d", errno);


		goto ErrExit;
	}

	if (semval EQ 0)
	{
		/* We could initialise by doing a SETALL, but that
	 	* would clear the adjust value.
	 	*/
		semctl_arg.val = initval;
		if (semctl(*id, 0, SETVAL, semctl_arg) < 0)
		{
			printf("\nSEM, can SETVAL[0]..: errno = %d", errno);
			goto ErrExit;
		}

		semctl_arg.val = BIGCOUNT;
		if (semctl(*id, 1, SETVAL, semctl_arg) < 0)
		{
			printf("\nSEM, can SETVAL[1]..: errno = %d", errno);
			goto ErrExit;
		}

	}

	/*
	 * Decrement the process counter and then release the lock.
	 */

	if (semop(*id, &op_endcreate[0], 2) < 0)
	{
		printf("\nSEM", "can't endcreate..: errno = %d", errno);
		goto ErrExit;
	}

	printf("\nSEM", "SemCreate SUCCESS id:%d  tok:%x", *id, key);
	return(SUCCESS);

ErrExit:
	*id = SEM_NULL;
	printf("\n SEM, SemCreate FAIL   id:%d  tok:%x", *id, key);
	return(FAIL);
}


/************************************************************************
 * Name:            SemOpen
 *
 * Function:
 *
 * Input:           id - the identifier of this semaphore.
 *
 * Output:          none.
 *
 * Return:          SUCCESS or FAIL
 *
 * Side Effects:    none
 *
 * Procedure:       1.
 *                  2.
 *                  3.
 ************************************************************************/

STATUS
SemOpen(int *id, key_t key)
{

	printf("\n SEM", "SemOpen Token/key tok:%x", key);

	if (key EQ IPC_PRIVATE)
	{
		printf("\n SEM, Not intended for private semaphores");
		goto ErrExit;
	}

	else if (key EQ (key_t) -1)
	{
		printf("\n SEM", "probably an ftok() error by caller");
		goto ErrExit;
	}

	if ( (*id = semget(key, 3, 0)) < 0)
	{
		printf("\n SEM, SemOpen, semget prot or tables full:..: errno = %d", errno);
		goto ErrExit;
	}

	/*
	 * Decrement the process counter  -  we don't need a lock.
	 */

	if (semop(*id, &op_open[0], 1) < 0)
	{
		printf("\n SEM, can't open..: errno = %d", errno);
		goto ErrExit;
	}

	printf("\n SEM, SemOpen SUCCESS id:%d   tok:%x", *id, key);
	return(SUCCESS);

ErrExit:
	*id = SEM_NULL;
	printf("\n SEM, SemOpen FAIL   id:%d    tok:%x", *id, key);
	return(FAIL);
}



/************************************************************************
 * Name:            SemRm
 *
 * Function:
 *
 * Input:           id - the identifier of this semaphore.
 *
 * Output:          none.
 *
 * Return:          SUCCESS or FAIL
 *
 * Side Effects:    none
 *
 * Procedure:       1.
 *                  2.
 *                  3.
 ************************************************************************/

STATUS
SemRm(int id)
{
	printf("\n SEM", "SemRm( id:%d)",id);
	semctl_arg.val = 0;
	if (semctl(id, 0, IPC_RMID, semctl_arg) < 0)
	{
		printf("\n SEM", "can't IPC_RMID..: errno = %d", errno);
		goto ErrExit;
	}

    printf("\n SemRm Error");
	return(SUCCESS);

ErrExit:
	printf("\n SemRm Error");
	return(FAIL);
}


/************************************************************************
 * Name:            SemClose
 *
 * Function:
 *
 * Input:           id - the identifier of this semaphore.
 *
 * Output:          none.
 *
 * Return:          SUCCESS or FAIL
 *
 * Side Effects:    none
 *
 * Procedure:       1.
 *                  2.
 *                  3.
 ************************************************************************/

STATUS
SemClose(int id)
{
	register int semval;

	/* the followung semop() first gets a lock on the semaphore,
	 * then increments [1] - the process conuter.
	 */

	printf(" \n SEM, SemClose( id:%d)",id);

	if (semop(id,  &op_close[0], 3) < 0)
	{
		printf("\n SEM, SemClose can't sem_op..: errno = %d", errno);
		goto ErrExit;
	}

	/*
	 * Now that we have a lock, read the value of the process
	 * counter to see if this is the last reference to the
	 * semaphore.
	 * There is a race condition here - see the comment in
	 * SemCreate().
	 */


	semctl_arg.val = 0;
	if ( (semval = semctl(id, 1, GETVAL, semctl_arg)) < 0)
	{
		printf("\n SEM, SemClose can't GETVAL..: errno = %d", errno);
		goto ErrExit;
	}

	if (semval > BIGCOUNT)
	{
		printf("\nSEM, sem[1] > BIGCOUNT");
		goto ErrExit;
	}
	else if (semval EQ BIGCOUNT)
	{
		if ( SemRm(id) EQ FAIL)
			goto ErrExit;
	}
	else if (semop(id, &op_unlock[0], 1) < 0)
	{
		printf("\nSEM, can't unlock..: errno = %d", errno);
		goto ErrExit;
	}

	printf("\n SemClose Error");
	return(SUCCESS);

ErrExit:
	printf("\n SemClose Error FAIL id:%d",id);
	return(FAIL);
}


/************************************************************************
 * Name:            SemWait
 *
 * Function:
 *
 * Input:           id - the identifier of this semaphore.
 *
 * Output:          none.
 *
 * Return:          SUCCESS or FAIL
 *
 * Side Effects:    none
 *
 * Procedure:       1.
 *                  2.
 *                  3.
 ************************************************************************/

STATUS
SemWait(int id)
{
	if (SemOp(id, -1) EQ FAIL)
		goto ErrExit;
		printf("\n SemWait Error");
	return(SUCCESS);

ErrExit:
	printf("\n SemWait Error");
	return(FAIL);
}


/************************************************************************
 * Name:            SemSignal
 *
 * Function:
 *
 * Input:           id - the identifier of this semaphore.
 *
 * Output:          none.
 *
 * Return:          SUCCESS or FAIL
 *
 * Side Effects:    none
 *
 * Procedure:       1.
 *                  2.
 *                  3.
 ************************************************************************/

STATUS
SemSignal(int id)
{
	if ( SemOp(id, 1) EQ FAIL)
		goto ErrExit;

		printf("\n SemSignal Error");
	return(SUCCESS);

ErrExit:
	printf("\n SemSignal Error");
	return(FAIL);
}


/************************************************************************
 * Name:            SemOp
 *
 * Function:
 *
 * Input:           id - the identifier of this semaphore.
 *
 * Output:          none.
 *
 * Return:          SUCCESS or FAIL
 *
 * Side Effects:    none
 *
 * Procedure:       1.
 *                  2.
 *                  3.
 ************************************************************************/

STATUS
SemOp(int id, int value)
{

	if ( (op_op[0].sem_op = value) EQ 0)
	{
		printf("\n SEM, can't have value EQ 0");
		goto ErrExit;
	}

	if (semop(id,  &op_op[0], 1) < 0)
	{
		printf("\n SEM, semop error..: errno = %d", errno);
		goto ErrExit;
	}

    printf("\n SemOp Success");
	return(SUCCESS);

ErrExit:
	printf("\n SemOp Error");
	return(FAIL);
}

/* End of file: semaphore.c */
--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]