* 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).