public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* Hang problem related to signals and process priority
@ 2002-03-04  3:13 Ivan Szanto
  2002-03-05  3:38 ` Ivan Szanto
  0 siblings, 1 reply; 2+ messages in thread
From: Ivan Szanto @ 2002-03-04  3:13 UTC (permalink / raw)
  To: cygwin

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1294 bytes --]


Hello cywin guru,                                                                                                                 


Maybe you can help me with the following problem.
We are running Cygwin version 1.3.10 on Windows NT.
We use sigaction to redirect the SIGIO signal to our
own signal handler in a client/server app. 

When running several processes of the same client program 
in the background, a couple of them seem to hang.

It is interesting that this problem does not surface when
we have all those processes running in the foreground or
when we start them using "cmd start /high ..."

Please find attached the relevant code for reproducing
the problem. It is a client program that tries to connect
to a telnetd. It expects the machine name where telnetd is
running as well as the repeat count for the send loop.
I reproduced the problem as follows

  1. opened an xterm with a bash
  2. in the xterm I typed the following
   
     for i in 1 2 3
     do
       ./a.exe localhost 300 &
     done

The result was that one process did well, but the other two hanged.

Is this behavior related to a known CYGWIN problem?
Do you think we can change our code in some way to avoid this problem?
We will greatly appreciate your expert advice on this matter.


Greetings,


  Ivan

[-- Attachment #2: Type: TEXT/PLAIN, Size: 3487 bytes --]

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <string.h>
#include <signal.h>


int global_int;

void
handle_signal(int a)
{
  global_int = 1; 
}

int 
set_mode(int socknum, int mode)
{
  int real_mode;
  int flags, yes = 1;  // yes actually is needed for CYGWIN

  real_mode = mode & (FASYNC + FNDELAY);
  flags = fcntl (socknum, F_GETFL);
  if (flags == -1)
    { perror("GETFL failed"); exit(0); }

#ifdef __CYGWIN__
  flags &= ~(FASYNC + O_NONBLOCK);
#else
  flags &= ~(FASYNC + FNDELAY);
#endif
  flags |= real_mode;

#ifndef __CYGWIN__
  // not supported by cygnus B20.1
  if (mode & FASYNC)
    {
      if (fcntl (socknum, F_SETOWN, getpid ()) == -1)
        { perror("SETOWN failed"); exit(0); }
    }
#endif // ! __CYGWIN__ //

  if (fcntl (socknum, F_SETFL, flags) == -1)
    { perror("SETFL failed"); exit(0); }

#ifdef __CYGWIN__
  if (mode & FASYNC)
    {
      if (ioctl (socknum, FIOASYNC, &yes) == -1)
        { perror("FIOASYNC failed"); exit(0); }
    }
#endif // __CYGWIN__ //
}

int
main(int argc, char *argv[])
{
  int                  socknum;
  char                 host_buffer[100];
  struct hostent     * host_entry;
  struct sockaddr_in * address;

  struct sigaction    action;
  sigset_t            block_mask;

  int                 i,n,wait;

  void               * memory;

  if ( argc < 3 )
    { printf("need a hostname and a repeat count\n"); exit(0); }
  
  strncpy(host_buffer, argv[1], 100);
  n = atoi(argv[2]);
  if ( n < 1 )
    { printf("count %d is not ok\n", n); exit(0); }

  /* allocate socket and connect to server */
  socknum = socket(AF_INET, SOCK_STREAM, 0);
  if ( ! socknum ) 
    { perror("socknum is 0"); exit(0); }

  host_entry = gethostbyname (host_buffer);
  if (! host_entry)
    { perror("could not get host entry"); exit(0); }

  address = (struct sockaddr_in *)
    calloc (1, sizeof (struct sockaddr_in));
  if (! address )
    { perror("could not alloc address"); exit(0); }
  address -> sin_family = AF_INET;

  memcpy ((char *) &(address -> sin_addr), 
	  (char *) host_entry -> h_addr,
	  host_entry -> h_length);

  address -> sin_port = htons(23);

  if (connect (socknum, (struct sockaddr *)address, sizeof (struct sockaddr_in))
      == -1)
    { perror("connect failed"); exit(0); }

  /* sigaction */
  global_int = 0;
  sigemptyset (&block_mask);
  sigaddset (&block_mask, SIGINT);
  sigaddset (&block_mask, SIGQUIT);
  sigaddset (&block_mask, SIGTSTP);
  sigaddset (&block_mask, SIGIO);

  // note that SA_RESTART is not supported on cygnus prior to 1.1.8
  action.sa_handler = handle_signal;
  action.sa_mask    = block_mask;
  action.sa_flags   = SA_RESTART;

  if (sigaction (SIGIO, &action, (struct sigaction *) 0) == -1)
    { perror("sigaction failed"); exit(0); }

  /* set async mode */
  set_mode (socknum, FNDELAY + FASYNC);
  for ( i = 0; i < n ; i++ )
    {
      if ( send (socknum, host_buffer, 1, 0) == -1 )
        { perror("send failed"); exit(0); }

      for ( wait = 0; wait < 1000; wait++ )
	{
	  memory = malloc(1000);
	  if ( !memory )
            { perror("malloc failed"); continue; }
	  free(memory);
	}
    }

  printf("Everything went ok, global_int is %d!\n", global_int);
  return 0;
}

[-- Attachment #3: Type: text/plain, Size: 214 bytes --]

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Hang problem related to signals and process priority
  2002-03-04  3:13 Hang problem related to signals and process priority Ivan Szanto
@ 2002-03-05  3:38 ` Ivan Szanto
  0 siblings, 0 replies; 2+ messages in thread
From: Ivan Szanto @ 2002-03-05  3:38 UTC (permalink / raw)
  To: cygwin

Hi,


Is there a way to quickly check if data is available
for read in a tcp socket without blocking the program?

If there is one, we could use that instead of the overly 
complex signal handling method that sometimes also results
in process hangs, which I reported in my previous mail.

Yes, select and poll could be used to do such a check, but
it looks to me that they are not quick. Or am I wrong in this?
Could someone please help me out here?


thanks a lot,

Ivan
-- 


--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2002-03-05 11:38 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-03-04  3:13 Hang problem related to signals and process priority Ivan Szanto
2002-03-05  3:38 ` Ivan Szanto

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).