On 6/1/2012 1:51 PM, Ryan C. Underwood wrote:
On Fri, Jun 01, 2012 at 08:59:06PM +0200, Corinna Vinschen wrote:

If you can press a long story into a short testcase in plain C with the
bare minimum of code to reproduce the behaviour, it would be much
appreciated.

The basic issue is that sem_wait() is being kicked out with EINTR
extremely frequently (9 out of 10 times or more),

Does the attached program vaguely resemble what your program is trying to do? It does get EINTR, but only because I'm using alarm(2) to add a timeout to the sem_wait() call.

You should just get an infinite series of "Child timed out normally waiting for the semaphore." messages from it after initialization, one per second.
#include <semaphore.h>
#include <sys/types.h>

#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

static int timed_out = 0;

void timeout(int sig)
{
        timed_out = 1;
}

int main()
{
        static const char* sem_name = "/myhappysemaphore";
        sem_t* ps = sem_open(sem_name, O_RDWR);
        if (ps) sem_close(ps);  // clean up old semaphore; we probably crashed
        ps = sem_open(sem_name, O_CREAT, 0600, 0);
        if (ps == SEM_FAILED) {
                perror("sem_open");
                return 1;
        }
        puts("Created semamphore.");

        pid_t pid = fork();
        switch (pid) {
                case -1:        // error
                        perror("fork");
                        return 2;

                case 0:         // child
                        signal(SIGALRM, timeout);
                        while (1) {
                                alarm(1);
                                int ret = sem_wait(ps);
                                if (ret == -1) {
                                        if (timed_out) {
                                                if (errno == EINTR) {
                                                        puts("Child timed out 
normally waiting "
                                                                        "for 
the semaphore.");
                                                        timed_out = 0;
                                                }
                                                else {
                                                        puts("Child timed out 
ABNORMALLY waiting "
                                                                        "for 
the semaphore!");
                                                        exit(99);
                                                }
                                        }
                                        else {
                                                perror("sem_wait");
                                                exit(69);
                                        }
                                }
                                else {
                                        puts("Child got the semaphore!  "
                                                        "How the spit did that 
happen?");
                                        exit(42);
                                }
                        }
                        break;

                default: {      // parent
                        puts("Created child.  Posting the deathwatch.");
                        int status;
                        while (1) {
                                pid_t ret = waitpid(pid, &status, 0);
                                if (ret > 0) {
                                        if (WIFEXITED(status)) {
                                                printf("Child %d died 
peacefully, code %d.\n",
                                                                ret, 
WEXITSTATUS(status));
                                                break;
                                        }
                                        else {
                                                printf("Child %d died 
screaming, status 0x%08X.\n",
                                                                ret, status);
                                                return 3;
                                        }
                                }
                                else {
                                        perror("waitpid");
                                        return 4;
                                }
                        }
                }
        }

        return 0;
}

--
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

Reply via email to