[patch] for rsync

jw schultz jw at pegasys.ws
Wed Sep 4 01:30:00 EST 2002


On Tue, Sep 03, 2002 at 05:00:02PM -0700, drstaples at beckman.com wrote:
> 
> JW,
> 
> I pushed everything to a LINUX box and did the diff again this time with the
> -bur option.
> It does look significantly different.  I think I've got below what you are
> looking for, so I am
> resending it to rsync at lists.samba.org.
> 
> I'm including two additional people as they have asked for the patch information
> as well.
> The diff was performed on main.c (2.5.5 version from rsync.samba.org).  I hope
> everyone
> knows that I'm my purpose in providing this information, is so that everyone can
> critique
> my code (to make it better) and we can eliminate this problem for everyone.
> 
> Dave

Thank you Dave.  I've been abusing/educating him a bit
offline so be nice everybody.  He has not only diagnosed the
bug independantly but has come up with a direction to go
toward a permanent solution.

Aside from my dislike of a fixed size array
my comments are below.


> -------------------------------------------------------------
> 
> --- main.c.orig     Tue Sep  3 16:38:23 2002
> +++ main.c     Tue Sep  3 16:41:08 2002
> @@ -27,6 +27,11 @@
> 
>  extern int verbose;
> 
> +struct pid_status {
> +    pid_t pid;
> +    int   status;
> + } pid_stat_table[10];

The use of a literal here is bad news.
Should be a #define CHILD_TABLE_SIZE or whatever.
Then macro can be used in the loops.

Question.  Is 10 a good size?  Should it be more?
I've not dug into the child spawning of rsync.

> +
>  static void show_malloc_stats(void);
> 
>  /****************************************************************************
> @@ -34,9 +39,27 @@
>  ****************************************************************************/
>  void wait_process(pid_t pid, int *status)
>  {
> -    while (waitpid(pid, status, WNOHANG) == 0) {
> +    pid_t waited_pid;
> +    int   cnt;
> +
> +    while ( 1 ) {
> +         waited_pid = waitpid(pid, status, WNOHANG);
> +         if ( waited_pid == 0 ) {
>           msleep(20);
>           io_flush();
> +         } else break;
> +    }
> +    if (( waited_pid == -1 ) && ( errno == ECHILD )) {
> +         /* status of requested child no longer available.  Check */
> +         /* to see if it was processed by the sigchld_handler.    */
> +         cnt = 0;
> +         while ( cnt < 10 ) {
> +              if ( pid == pid_stat_table[cnt].pid ) {
> +                   *status = pid_stat_table[cnt].status;

If we do 'pid_stat_table[cnt].pid = 0' here we'll be able to
reuse the slots. (if necessary)

> +                   break;
> +              }
> +              cnt++;
> +         }
>      }
> 
>          /* TODO: If the child exited on a signal, then log an
> @@ -792,7 +815,22 @@
> 
>  static RETSIGTYPE sigchld_handler(int UNUSED(val)) {
>  #ifdef WNOHANG
> -    while (waitpid(-1, NULL, WNOHANG) > 0) ;
> +    int cnt = 0;
> +    pid_t pid = 0;
> +    int status = 0;
> +    while ( 1 ) {
> +         pid = waitpid(-1, &status, WNOHANG);
> +         cnt = 0;
> +         while ( cnt < 10 ) {
> +              if (pid_stat_table[cnt].pid == 0 ) {
> +                   pid_stat_table[cnt].pid = pid;
> +                   pid_stat_table[cnt].status = status;
> +                   break;
> +              }
> +              cnt++;
> +         }
> +         if ( pid < 1 ) break;

If we run off the end of the array (cnt == 10) we should kick out a
warning or we should resize it.

> +    };
>  #endif
>  }

-- 
________________________________________________________________
	J.W. Schultz            Pegasystems Technologies
	email address:		jw at pegasys.ws

		Remember Cernan and Schmitt



More information about the rsync mailing list