Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , 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 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> Content-Type: multipart/mixed; boundary="------------050504050105030800080702" 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #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--