delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2005/04/04/02:52:12

Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com
Message-ID: <4250E410.1060708@smousseland.com>
Date: Mon, 04 Apr 2005 08:52:00 +0200
From: Vincent Dedun <kraken+spam AT smousseland DOT com>
Reply-To: cygwin AT cygwin DOT com
User-Agent: Mozilla Thunderbird 1.0 (Windows/20041206)
MIME-Version: 1.0
To: cygwin AT cygwin DOT com
Subject: Re: ipc, sockets and windows sp2
References: <424D0232 DOT 5060305 AT smousseland DOT com> <20050401090414 DOT GD7415 AT cygbert DOT vinschen DOT de> <424D2B0B DOT 8000604 AT smousseland DOT com> <20050401121143 DOT GD1471 AT cygbert DOT vinschen DOT de> <424D5C64 DOT 5050706 AT smousseland DOT com> <20050401160749 DOT GH1471 AT cygbert DOT vinschen DOT de>
In-Reply-To: <20050401160749.GH1471@cygbert.vinschen.de>
X-IsSubscribed: yes

--------------050504050105030800080702
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Corinna Vinschen wrote :

>
>Thanks again for the testcase.  It helped to track down the problem which
>was a result of my previous check in.  It should be solved in CVS now.
>
>Since you're building from CVS anyway, I don't create another snapshot
>for now.  We're that close to 1.5.14 anyway...
>  
>
Thanks again for having solved this so quickly.

However, semaphores still doesn't work properly.
There is no more problem with semop not waiting, but with quick 
semaphores locking unlocking.

I attach a new testcase, which is the same as previous one, except each 
child task will lock the semaphore, wait 100ms, then release the 
semaphore and die. Each time a child dies, a new one is created to keep 
10 running childs.

On osx, you will see forever locking/unlocking of semaphore written on 
output.
On lastest cygwin, you will see some locking/unlocking (about 11 or 12 
lock/unlock pair for me), then every child keep waiting for locking, and 
the program comes in dead-lock.

I think that semop doesn't get awaken properly when semaphore value 
change quickly.

Same conditions (windows/cygwin version), as previous mail apply.

Kraken

--------------050504050105030800080702
Content-Type: text/plain;
 name="fork-ipc-sem2.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="fork-ipc-sem2.c"

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/errno.h>

#define USE_IPC
#define USE_SEM
//define BIND_AFTER_FORK 

#define BUFFERLEN 256

struct	database
{
	int		shmid;
	int 	semid;
	int 	test1;
	int 	test2;
}
*wdb;

int			get_shared_memory(char *path_key)
{
	key_t 	key;
	int		shmid;
	int		shmflg;
	char	file[BUFFERLEN];

  snprintf(file, BUFFERLEN-1, "%s.exe", path_key);
	if ((key = ftok(file, 'Z')) == -1)
	{
		perror("Getting key for shared memory");
		exit(1);
	}
	shmflg = IPC_CREAT|0600;
	if ((shmid = shmget(key, sizeof(struct database), shmflg)) == -1)
	{
		perror ("Getting shared memory");
		exit(1);
	}
	fprintf(stderr,"shmid: %i\n", shmid);
	return (shmid);
}

int					get_semaphores(char *path_key)
{
	key_t			key;
	int				semid;
	struct sembuf	op;
	int				semflg;
	char			file[BUFFERLEN];

  snprintf(file, BUFFERLEN-1, "%s.exe", path_key);
	if ((key = ftok(file, 'Z')) == -1)
	{
		perror("Getting key for semaphores");
		exit(1);
	}
	semflg = IPC_CREAT|0600;
	if ((semid = semget(key, 1, semflg)) == -1)
	{
		perror("Getting semaphores");
		exit(1);
	}
	if (semctl(semid, 0, SETVAL, 1) == -1)
	{
		perror("semctl SETVAL -> 1");
		exit(1);
	}
	if (semctl(semid, 0, GETVAL) == 0)
	{
		op.sem_num = 0;
		op.sem_op = 1;
		op.sem_flg = 0;
		if (semop(semid, &op, 1) == -1)
		{
			perror("semaphore_release");
			exit(1);
		}
	}
	fprintf(stderr,"semval: %i semid: %i\n", semctl (semid, 0, GETVAL), semid);
	return (semid);
}

void		*attach_shared_memory(int shmid)
{
	void	*rv; // return value

	if ((rv = shmat(shmid, 0, 0)) == (void *) -1)
	{
		perror("shmat");
		return ((void *) -1);
	}

	return (rv);
}

int		detach_shared_memory(void *shmaddr)
{
	int	rv; // return value

	if ((rv = shmdt(shmaddr)) == -1)
	{
		perror("shmdt");
		return (-1);
	}

	return (rv);
}

void					set_signal_handlers (void)
{
	struct sigaction	ignore;

	ignore.sa_handler = SIG_IGN;
	sigemptyset(&ignore.sa_mask);
	ignore.sa_flags = 0;
	sigaction(SIGHUP, &ignore, NULL); // So we keep running as a daemon
}

int						get_socket(short port)
{
	int					sfd; //socket file descriptor
	struct sockaddr_in	addr;
	int					opt;

	opt = 1;
	sfd = socket(PF_INET, SOCK_STREAM, 0);
	if (sfd == -1)
	{
		perror("socket");
		exit(1);
	}
	else
	{
		if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (int *) &opt, sizeof(opt)) == -1)
			perror ("setsockopt");
		addr.sin_family = AF_INET;
		addr.sin_port = htons(port);
		addr.sin_addr.s_addr = htonl(INADDR_ANY);
		if (bind(sfd, (struct sockaddr *) &addr, sizeof (addr)) == -1)
		{
			perror("bind");
			sfd = -1;
		} else {
			listen (sfd, 5);
		}
	}
	return (sfd);
}

int		accept_socket	(int sfd, struct sockaddr_in *addr)
{
  int	fd;
  int	len = sizeof(struct sockaddr_in);

	if ((fd = accept(sfd, (struct sockaddr *) addr, &len)) == -1)
  {
    perror("Accepting connection\n");
    exit(1);
  }
  return (fd);
}

void 			semaphore_lock(int semid)
{
  struct sembuf	op;

  op.sem_num = 0;
  op.sem_op = -1;
  op.sem_flg = SEM_UNDO;

  fprintf(stderr,"Locking... semval: %i semid: %i\n",semctl (semid,0,GETVAL),semid);
  if (semop(semid, &op, 1) == -1)
  {
	perror("semaphore_lock");
	printf("%i\n",errno);
	exit(0);
  }
  fprintf(stderr,"Locked !!! semval: %i semid: %i\n",semctl (semid,0,GETVAL),semid);
}

void			semaphore_release(int semid)
{
  struct sembuf	op;

  fprintf(stderr,"Unlocking... semval: %i semid: %i\n",semctl (semid,0,GETVAL),semid);
  op.sem_num = 0;
  op.sem_op = 1;
  op.sem_flg = SEM_UNDO;
  if (semop(semid, &op, 1) == -1)
  {
    perror ("semaphore_release");
	printf("%i\n",errno);
	exit(0);
  }
  fprintf(stderr,"Unlocked !!! semval: %i semid: %i\n",semctl (semid,0,GETVAL),semid);
}

int						main(int argc, char *argv[])
{
	int					sfd; // socket file descriptor
	int					csfd; // child sfd, the socket once accepted
	int					shmid; // shared memory id
	int					semid; // semaphore id
	struct sockaddr_in	addr; // Address of the remote host
	pid_t				child;
	pid_t				child_wait;
	int					n_children;
	int					rc; // Return code
	int					i; // For loops

	n_children = 0;
	set_signal_handlers();
	
#ifdef USE_IPC
	shmid = get_shared_memory(argv[0]);
	semid = get_semaphores(argv[0]);
	if ((wdb = attach_shared_memory(shmid)) == (void *) -1)
		exit (1);
	wdb->shmid = shmid;
	wdb->semid = semid;
#endif

#ifndef BIND_AFTER_FORK
	if ((sfd = get_socket(1234)) == -1)
		exit(0);
#endif

	printf ("Waiting for connections...\n");
	while (1)
	{
		if (n_children < 10)
		{
			if ((child = fork()) == 0)
			{
#ifdef BIND_AFTER_FORK
				if ((sfd = get_socket(1234)) == -1)
					exit(0);
#endif
#ifdef USE_SEM
				semaphore_lock(wdb->semid);
				usleep(100);
				semaphore_release(wdb->semid);
#endif
				exit(0);
			}
			else if (child != -1)
				n_children++;
			else
				perror("Forking\n");
		}
		else
		{
			if ((child_wait = wait (&rc)) != -1)
				n_children--;
		}
	}
	exit(0);
}



--------------050504050105030800080702
Content-Type: text/plain; charset=us-ascii

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/
--------------050504050105030800080702--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019