Subject: Re: select call implementation and threads
To: malleswararao venkatanaga <bobbyavn@yahoo.com>
From: Andrey Petrov <petrov@netbsd.org>
List: tech-userlevel
Date: 05/24/2003 17:23:49
On Sat, May 24, 2003 at 04:26:11AM -0700, malleswararao venkatanaga wrote:
> 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]);

Well, well, well. Try to reverse 2 previous lines.


>   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