Subject: Re: select call implementation and threads
To: Andrey Petrov <petrov@netbsd.org>
From: malleswararao venkatanaga <bobbyavn@yahoo.com>
List: tech-userlevel
Date: 05/24/2003 04:26:11
Here is the code i tested with.
/* Recv.c This is the code that receives messages */
#include <stdio.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/select.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include <pthread.h>

void * stub_test (void *p );
pthread_t  threads[3];
int main()
{
  int rc;
  stub_test2();
  rc = pthread_create(&threads[0], NULL , stub_test
,(void *) &threads[0]);
  if(rc)
  {
    printf("Error in creating thread\n");
    exit(0);
  }

  rc = pthread_join( &threads[0], NULL);
  if(rc)
  {
    printf("Error in creating thread\n");
    exit(0);
  }
}


void * stub_test (void *p )
{
 struct sockaddr_in     saddr;
 int sock_fd, i, nread, ndfs, ret_val;
 fd_set   read_set;
 char buff[1000];
 struct timeval timeval;
 
 saddr.sin_family =    AF_INET;
 saddr.sin_port   =    45000;
 saddr.sin_addr.s_addr = htonl ( INADDR_ANY);
 if( (sock_fd = socket( AF_INET , SOCK_DGRAM , 0 ) ) <
0 )
     return -1;

 if ( bind ( sock_fd , (struct sockaddr * ) &saddr,
sizeof(saddr ) ) < 0)
     return -1;

  ndfs = sock_fd + 1;
  while(1)
  {
     FD_ZERO ( &read_set);
     FD_SET (sock_fd , &read_set);
     ret_val = select(ndfs, &read_set, NULL, NULL,
NULL);
     if(ret_val >0)
     {
          if(FD_ISSET(sock_fd, &read_set))
          {

           nread = recvfrom ( sock_fd , buff , 10, 0
,NULL, NULL);
           printf("Read bytes thr 2 %d\n", nread);
           for(i = 0; i <5; i++)
           {
              printf("Buff contents = %c\n", buff[i]);
           }
           }
      }
      else
     {
        printf("\n failed in select");
     }
   } 
  return 0;
}
void stub_test2()
{
   struct sockaddr_in   saddr2;
   fd_set  read_set;
   int sock_fd, ret_val, ndfs;

 struct timeval timeval;

 timeval.tv_sec  = 10;
 timeval.tv_usec = 0;

 saddr2.sin_family =    AF_INET;
 saddr2.sin_port   =    45001;
 saddr2.sin_addr.s_addr = htonl ( INADDR_ANY);

  if( (sock_fd = socket( AF_INET , SOCK_DGRAM , 0 ) )
< 0 )
     return -1;

  if ( bind ( sock_fd , (struct sockaddr * ) &saddr2,
sizeof(saddr2 ) ) < 0)
               return -1;

 ndfs = sock_fd + 1;
 while(1)
 {
   FD_ZERO ( &read_set);
   FD_SET (sock_fd , &read_set);
    ret_val = select(ndfs, &read_set, NULL, NULL,NULL
);
    if(ret_val >0)
    {
       if(FD_ISSET(sock_fd, &read_set))
       {
            int nread;
            char buf[1000];
            printf("\n Recvd some message  main thread
\n");
            nread = read(sock_fd, buf, sizeof(buf));
            if(nread>0)
                  {
              printf("\n read %i bytes", nread);
            }
       }
    }
    else
     {
        printf("\n failed in select 1");
     }
 }   
 
}


/* The code that sends messages on both the ports */

#include <stdio.h>
#include <sys/errno.h>
#include <sys/types.h>
#include<sys/socket.h>
#include<sys/select.h>
#include<netinet/in.h>



main()
{
        int                             sockfd,
nwritten , i=1;
        const char                      on = 1;
        struct sockaddr_in               saddr;
        unsigned char                    *pbuf;

        pbuf = (unsigned char*)malloc(5);
        strcpy(pbuf, "hello");

        saddr.sin_family                = AF_INET;
        saddr.sin_addr.s_addr   = INADDR_ANY;

        if ( ( sockfd = socket ( AF_INET, SOCK_DGRAM,
0 ) ) < 0 )
        {
                return -1;
        }
        for ( ;  ; )
        {
         if(i==0)
         {
        saddr.sin_port                  = 45000;
         i = 1;
         }
         else
         {
         {
         saddr.sin_port                  = 45001;
           i=0;
         }
        nwritten        = sendto ( sockfd, pbuf, 5,
0,(struct sockaddr *)&saddr,

                                               
(size_t)(sizeof (struct sockaddr_in)) );

       if ( nwritten < 0 )
        {
                return -1;
        }
           printf("\n sent message ");
           sleep(10);
        }

   return;
}



--- Andrey Petrov <petrov@netbsd.org> wrote:
> On Fri, May 23, 2003 at 09:50:02AM -0700,
> malleswararao venkatanaga wrote:
> > Hi,
> >  I'm facing a problem and it is somewhat like
> this,
> >   1)I spawn a thread using pthread_create()
> >   2) In the thread I open a socket, bind it to a
> port
> > say 10001 and block it in the select call for
> > receiving a UDP message.
> >   Similarly 
> >   In my main thread i open a socket and bind it to
> a 
> > port say 10000 and block the main thread in a
> select
> > call.
> >   Both the main thread and the other thread are
> > essentially waiting for different messages on
> > different ports and different socket fds with
> their
> > respective select calls.
> >   I observe that if i send a messages to both of
> them
> > only one of them receives while the other one is
> still
> > blocked in the select call though it has messages
> to
> > read. 
> > 
> 
> Good thing about userland's threads is that it's
> easy to debug:
> build pth library and your applicarion with '-g' and
> you'll
> get the full picture of what's going on.
> 
> The behavouir you described is strange: select is
> normally
> redefined to pth_select and that supposed to take
> care of swiching
> betwean threads. Well, you can post your application
> here...
> 
> 	Andrey
> 


__________________________________
Do you Yahoo!?
The New Yahoo! Search - Faster. Easier. Bingo.
http://search.yahoo.com