Current-Users archive

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

Re: SIGIO, xemacs random crashes on SMP system



On Tuesday, at 23:14, Anthony Mallet wrote:
| Now, my question is: isn't it possible for an LWP that has set the direction
| flag, e.g. during a memmove() call, to be interrupted by a signal and have its
| direction flag unset behind its back, thus messing up the end of the memmove()
| call?

In addition to this, the small program attached below aborts quickly on my
machine. Removing either the SIGIO handler or the memmove() calls make it work
fine.

Can someone check if he can reproduce this behaviour (and if the program is
otherwise correct ...)?
Thanks,
-- 
Anthony
#include <err.h>
#include <errno.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <fcntl.h>

static const int values = 1000;

/* empty SIGIO handler */
void
sigioh(int sig)
{
  ;
}

/* writer thread */
void
writer_thread(int fd)
{
  int i;

  for(i=0; i<values;i++) {
    write(fd, &i, sizeof(i));
  }
  close(fd);
}

/* main program */
int
main()
{
  const int size = 40960;
  int *test;

  int fd[2];
  int i, c, s;

  /* setup a buffer with data */
  test = malloc(size * sizeof(int));
  if (!test) errx(2, "malloc()");

  for(i=size-1; i>=0; i--)
    test[i] = i;

  for(i=size-1; i>=0; i--)
    if (test[i] != i) errx(2, "cannot setup data...");

  /* create a pipe, configure SIGIO to be sent to us */
  signal(SIGIO, sigioh);
  pipe(fd);
  fcntl(fd[0], F_SETFL, O_ASYNC|O_NONBLOCK);
  fcntl(fd[0], F_SETOWN, getpid());

  /* spawn the writer */
  switch(fork()) {
    case -1:
      errx(2, "cannot fork writer...");
      break;

    case 0:
      writer_thread(fd[1]);
      exit(0);
  }

  /* reader loop */
  while(1) {
    memmove(test+1, test, (size-1) * sizeof(int));
    memmove(test, test+1, (size-1) * sizeof(int));
    test[size-1] = size-1;

    if (read(fd[0], &c, sizeof(c)) <= 0) continue;
    if (c >= values - 1) break;

    for(i=size-1; i>=0; i--)
      assert(test[i] == i);
  }

  assert(c+1 == values);
  warnx("done.");
  return 0;
}


Home | Main Index | Thread Index | Old Index