got the alpha 2.0.36 kernel from redhat 5.2/updates for alpha

still got the problem. Attached is a demo ( client/server) program that
demonstrates the loss of the SIGIO interrupt after a few EAGAIN failures. I do
not know why the loss, but for most of the failures there is a I "have no more
buffer space" failure in net/core/sock.c. BUT since SIGIO's were gen'd a few
times under the same "lack" of space scenario, i have no hard facts to point a
firm belief that the buffer failure is the absolute cause.
gat
tomm i will fire up the 386, and see how that fairs.

Alan Cox wrote:

> updates. I'm not interested in 2.0.33 network problems unless they are also
> duplicatable on .35/36.
>
> Alan

/* *  server.c
 *  cc -g -o server server.c
 * To demonstrate unexpected SIGIO loss
 * [EMAIL PROTECTED]
 */

#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <sys/un.h>
#include <sys/uio.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>

int fd, work_fd;

main()
{
 char *p1, *p2;
 struct iovec iovec[2];
 int i;
 int j = 0;
 open_socket();

 p2 = malloc( 10*1024 );
 iovec[0].iov_len = 10*1024;
 iovec[0].iov_base = p2;

 while( i > 0 ) {
     i = readv(work_fd, &iovec, 1);
     printf("%d\n",j++);
 }
 unlink("X0");
}


open_socket()
{

 struct sockaddr_un sockname, sockname2;
 int i;
 int len;

 fd = socket(1,1,0);
 if ( fd < 0 ) {
  printf("Socket error %d\n", errno);
  exit();
 }

 unlink("X0");
 sockname.sun_family = AF_UNIX;
 len = sprintf(sockname.sun_path,"X0");
 len += sizeof(sockname.sun_family);
 i = bind( fd, &sockname, len);
 if ( i<0 ) {
  printf("Cannot connect to &s, errno=%d\n",
   sockname.sun_path, errno);
  exit();
 }
 i = listen( fd, 2 );
 i = 50;
 work_fd = accept( fd, &sockname2, &i);

#if 0
 i = fcntl( fd, F_GETFL,0);
 fcntl( fd, F_SETFL, O_NONBLOCK | i);
 fcntl( fd, F_SETOWN, getpid());
#endif
}
/******************** end of server.c *****************************/

/*
 *  client.c
 *  cc -g -o client client.c
 * To demonstrate SIGIO loss.
 */

#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <sys/un.h>
#include <sys/uio.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>

int fd;
void io_done(int);
void timedout(int);
int myv( int fd, struct iovec *a, size_t b);
long gettime();
#define A_LONG_TIME (30*1000) /* 30 seconds */
enum timeouts { GOT_IO=34,GOT_TIME };
struct {
 long begin_time;
 long end_time;
 enum timeouts flag;
} t;

main()
{
 char *p1, *p2;
 int loops=0;
 struct iovec iovec[2];

 signal( SIGALRM, timedout);
 signal( SIGIO,   io_done);

 open_socket();

 p1 = malloc(24);
 p2 = malloc( 262123 );

 while(1){
  iovec[0].iov_len = 24;
  iovec[0].iov_base = p1;
  iovec[1].iov_len = 200*1024-24;
  iovec[1].iov_base = p2;

      myv( fd, (struct iovec *)&iovec, 2);
      printf("Loops = %d\n",loops++);
      nod_off(500, "Delay");  /* 500ms */
 }
}

myv( int fd,struct iovec * vec , size_t c)
{
 int wrote, left;
 struct iovec *iov;

 iov = vec;
 while (c > 0 ) {
     t.begin_time = 0;
     t.end_time = 0;
     wrote = writev( fd, iov, c );
     if ( wrote < 0 ) {

         if ( errno == EAGAIN ) {
          nod_off( A_LONG_TIME ,"EAGAIN");
   continue;
         }
  printf("Unexpected writev error %d\n", errno);
     }

     for ( ; c; iov++,c--) {
        left = wrote - iov->iov_len;
        if ( left >= 0 ) {
            wrote -= iov->iov_len;
     continue;
  }
  iov->iov_len -= wrote;
  iov->iov_base += wrote;
  break;
     }
 }
}

nod_off( int time , char *m)
{
 struct itimerval value;
 int i;
 int status;

 value.it_interval.tv_sec  = 0;
 value.it_interval.tv_usec = 0;
 value.it_value.tv_sec  = time/1000;
 value.it_value.tv_usec = (time%1000)*1000;
 setitimer( ITIMER_REAL, &value, 0 );
 if ( t.begin_time || t.end_time ) {
     printf(" Signal Happened after writev. (b=%lx,e=%lx)\n",
  t.begin_time, t.end_time);
 }
 t.begin_time = gettime();
 t.end_time = 0;
 i = pause(); /* ZZZZZZZZZZZZZzzzzzzzzzzzzzzzzz........ */
 if (i >= 0 ) /* ??? */
  ;
 if ( m[0] != 'D') {
     printf("Woke up(%d): time.b=%lx,time.e=%lx,Reason=%s\n",
    errno, t.begin_time, t.end_time,
   (t.flag == GOT_IO)?"SIGIO":"TimedOut");
 }

}

open_socket()
{

 struct sockaddr_un sockname;
 int i;
 int len;

 fd = socket(PF_UNIX,SOCK_STREAM,0);
 if ( fd < 0 ) {
  printf("Socket error %d\n", errno);
  exit(1);
 }

 sockname.sun_family = AF_UNIX;
 len = sprintf(sockname.sun_path,"X0");
 len += sizeof(sockname.sun_family);
 i = connect( fd, &sockname, len);
 if ( i<0 ) {
  printf("Cannot connect to %s, errno=%d\n",
   sockname.sun_path, errno);
  exit(2);
 }
 i = fcntl( fd, F_GETFL,0);
 if ( i < 0 ) exit(3);
 i = fcntl( fd, F_SETFL, O_NONBLOCK | O_ASYNC | i);
 if ( i < 0 ) exit(4);
 i = fcntl( fd, F_SETOWN, getpid());
 if ( i < 0 ) exit(4);
 i = fcntl( fd, F_GETFL,0);

}

void
timedout(int sig )
{
 t.end_time = gettime();
 t.flag = GOT_TIME;
 signal(sig, timedout);
}

void
io_done(int sig )
{
 t.end_time = gettime();
 t.flag = GOT_IO;
 signal( sig, io_done);
}

long
gettime()
{
 struct timeval tv;
 gettimeofday( &tv, 0);

 return (tv.tv_sec*1000L + tv.tv_usec/1000L);
}
/****************** end of client.c *********************************/


Reply via email to