bug-mailutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: pop3d errno assignments and pthreads.


From: Alain Magloire
Subject: Re: pop3d errno assignments and pthreads.
Date: Sun, 22 Apr 2001 14:45:07 -0400 (EDT)

Bonjour

> 
> Many functions of the package assign a value to errno variable. This
> is no problem when the package is compiled with --disable-pthread
> option. But when compiled with pthreads this causes grief, since
> in threaded environment errno location is shared between threads.
> For example, in GNU/Linux:

You got this backward, in a multi-thread environment errno is global
to the thread, but local between threads .i.e  errno location is uniq
per thread.

> #if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_REENTRANT)
> extern int*     __errno_location  __P((void));
> #define errno   (*__errno_location ())
> 
> in Solaris/i86:
> 
> #if (defined(_REENTRANT) || defined(_TS_ERRNO) || \
>         _POSIX_C_SOURCE - 0 >= 199506L) && !(defined(lint) || defined(__lint))
> extern int *___errno();
> #define errno (*(___errno()))

Yes, Phtread provides a per-thread errno.

http://pauillac.inria.fr/~xleroy/linuxthreads/faq.html

> 
> , etc. Thus, any assignment to errno made by child process clobbers
> its value in the parent also. Consequently, the following fragment

I'm not sure I understand your point.  In a process model, a child
can not clobber the value of the parent.  The child has a different
memory space.

> in pop3d.c does not work:
> 
>       connfd = accept (listenfd, (struct sockaddr *)&client, &size);
>       if (connfd == -1)
>         {
>           if (errno == EINTR)
>           continue;
>           syslog (LOG_ERR, "accept: %s", strerror (errno));
>           exit (-1);
>         }
> 
> When accept() gets interrupted by, say SIGCHLD, the value of errno
> is not EINTR, so the master daemon just complains and dies after
> the first child is finished. Possible solution would be

That can not be, if accept was interrupted by a signal errno == EINTR
unless ... it was clobber somewhere like in the signal handler(I'm
not sure about this, I will have to double check).  The other problem
that I can see that you patch address is that signal() is not
restartable, and I should re-arm the signal(SIGCHLD ..) or
use sigaction().


> Index: pop3d/signal.c
> ===================================================================
> RCS file: /cvs/mailutils/pop3d/signal.c,v
> retrieving revision 1.2
> diff -c -r1.2 signal.c
> *** signal.c  2001/01/11 04:46:34     1.2
> --- signal.c  2001/04/22 11:39:33
> ***************
> *** 8,14 ****
>     pid_t pid;
>     int status;
>   
> -   (void)signo;
>     while ( (pid = waitpid(-1, &status, WNOHANG)) > 0)
>         --children;
>   }
> --- 8,15 ----
>     pid_t pid;
>     int status;
>   
>     while ( (pid = waitpid(-1, &status, WNOHANG)) > 0)
>         --children;
> +   signal(signo, pop3_sigchld);
> +   errno = EINTR; 
>   }

In any case your patch is correct :
- make sure we restore errno if it was clobber by waitpid(again I'm not
  sure this is necessary but it will not hurt and the right thing)
- reinstate the signal handler(on some platform, signal() is not
  restartable)

I would prefer to use sigaction() instead of signal() wich will make sure
that the signal is re-arm(POSIX semantics).

Many thanks for catching this.

You also brought to light another point, that is when configuring
with pthread, I should define -D_REENTRANT or similar since some
libraries may have a different behaviour if this is not set.

> 
> But I fear the problem will manifest itself in other places that rely
> on the value of errno. It may be better to use some internal variable
> instead of the global errno, how do you think?

There is no problem, with errno, I think you actually found 2 bugs and
a good fix but for the wrong reasons.

The library takes the same approach as POSIX.1c(Pthreads) meaning instead
of return -1 and setting errno, all functions return a value(int) that
represent an error code when not == 0.  This actually save us from
clobbering the global errno (per thread).


> Cheers,

Many, Thanks

-- 
au revoir, alain
----
Aussi haut que l'on soit assis, on est toujours assis que sur son cul !!!




reply via email to

[Prev in Thread] Current Thread [Next in Thread]