public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* SIGIO using UDP sockets just hangs (permantely blocks) socket I/O.
@ 2017-09-30 12:53 tvonderhaar
  2017-10-10  9:58 ` Corinna Vinschen
  0 siblings, 1 reply; 2+ messages in thread
From: tvonderhaar @ 2017-09-30 12:53 UTC (permalink / raw)
  To: cygwin

[-- Attachment #1: Type: text/plain, Size: 1453 bytes --]

     Dear cygwin_list,

     I have tried to get signals working with UDP bound sockets. I have
tried every combination and order of the included code, but once I
ioctl() the socket with "FIOASYNC" I get one signal from the socket and
the previously "FNDELAY" set socket blocks forever on a call to
recvfrom(). I can detect the block with a select, but it never becomes
ready. This code works flawlessly on Linux and in the past worked on
SUN,HP- UX(I remove the HP specific code) and Alpha OSes. If I don't
perform the ioctl() with "FIOASYNC" or perform a second call to ioctl()
with the "set_state=0" the socket does not block as expected, but I of
course I don't get my SIGIO signal. Note: I make the call to the
function as follows:

    set_io_async(udp_socket_fd,call_back,SIGIO,FALSE);
   /*FASLE defined as '0' and SIGIO as defined by CYGWIN.*/

  I only found one google search of an individual attempting non-blocking
asynchronous() I/O and they indicated it worked using this code sequence
under CYGWIN. "FASYNC" has no affect on CYGWIN using fcntl() as after
setting that flag with "F_SETFL" and reading the flags back with
"F_GETFL" the flag is not set.

     Some help would be appreciated. I know some feel signals are
obsolete but I don't and I have used them over for 20+ years. Thanks.

       Tom

---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

[-- Attachment #2: sigio.c --]
[-- Type: application/octet-stream, Size: 4118 bytes --]

/*********************************Start-set_io_async***************************/
/*This Function sets up a signal call back function '(*call_back)()' to be
  called asynchronously when I/O is available on the file descriptor 'fd'.
  The siganl system is set to restart if possible any system calls that are 
  interrupted and to send the signal information data with the call back
  function 'call_back_func()'. (See sigaction() in Linux manuals.) This
  signal is blocked until we return or use the signal masking functions
  to change the signals blocking state. The signal call back function is
  retained until specifically changed(unlike when using 'signal()'.)
  Real Time signals are queued to a MAX depth set by the system. There are
  approximtely 32 RT signals available SIGRTMIN to SIGRTMAX.

 Input:
            wait:   0 => Set I/O mode non-blocking on file descriptor 'fd'.
                    1 => Set I/O mode blocking on file descriptor 'fd'.
       rt_sig_no:   Real time signal number to use. If 'rt_sig_no' is
                    less than SIGRTMIM or greater than SIGRTMAX the then
                    signal queue depth reverts to '1' and the signal
                    info structure may or may not apply. Specifically
                    CYGWIN does not seem to offer a 'fcntl()'
                    'F_SETSIG' signal option, but does support signal
                    information at least via 'sigqueue()'.
   Return:
         0 =>   Success.
        -1 =>   Failure, global variable "errno" has error code.
*/
int set_io_async(int fd,void (*call_back)(int signum, siginfo_t *siginfo,
                 void *ucontext),int rt_sig_no,u_char wait)
{
int              flags;
struct sigaction new_signal_handler;
struct sigaction org_signal_handler;

   DBPRINTF(2,"set_io_async(fd=%d,call_back=%ul,rt_sig_no=%d,wait=%d)\n",
            fd,call_back,rt_sig_no,wait);

   /*Setup new signal handler struct.*/
   new_signal_handler.sa_sigaction=call_back;
   sigemptyset(&new_signal_handler.sa_mask);
   new_signal_handler.sa_flags= SA_SIGINFO|SA_RESTART;

   /*Setup our signal handler.*/
   if(sigaction(rt_sig_no,&new_signal_handler,&org_signal_handler)<0){
      DBPRINTF(2,"sigaction() failed.\n");
      return(-1);
   }

#  ifndef __CYGWIN__
   /*Setup to use as a real time signal(signals are queue'd.)*/
   if(fcntl(fd,F_SETSIG,rt_sig_no)<0){
      DBPRINTF(2,"fcntl(F_SETSIG) failed.\n");
      sigaction(rt_sig_no,&org_signal_handler,NULL);/*Restore old handler.*/
      return(-1);
   }
#  endif

   /*Setup owner for async I/O.*/
   if(fcntl(fd,F_SETOWN,getpid())<0){
      DBPRINTF(2,"fcntl(F_SETOWN) failed.\n");
      sigaction(rt_sig_no,&org_signal_handler,NULL);/*Restore old handler.*/
      return(-1);
   }

#  ifdef __CYGWIN__        
   if((flags=fcntl(fd,F_GETFL,0))<0){
      DBPRINTF(2,"fcntl(F_GETFL) failed.\n");
      sigaction(rt_sig_no,&org_signal_handler,NULL);/*Restore old handler.*/
      return(-1);
   }
   flags|=(wait)?(FASYNC):(FNDELAY|FASYNC);
   /*Allow asynchronous I/O signals and if wait mode set non-blocking I/O.*/
   if(fcntl(fd,F_SETFL,flags)<0){
      DBPRINTF(2,"fcntl(F_SETFL) failed.\n");
      sigaction(rt_sig_no,&org_signal_handler,NULL);/*Restore old handler.*/
      return(-1);
   }

   int set_state=1;
   if(ioctl(fd,FIOASYNC,&set_state)<0){
      DBPRINTF(2,"ioctl(FIOASYNC) failed.\n");
      sigaction(rt_sig_no,&org_signal_handler,NULL);/*Restore old handler.*/
      return(-1);
   }
#  else
   /*Get current socket flags.*/
   if((flags=fcntl(fd,F_GETFL,0))<0){
      DBPRINTF(2,"fcntl(F_GETFL) failed.\n");
      sigaction(rt_sig_no,&org_signal_handler,NULL);/*Restore old handler.*/
      return(-1);
   }
   flags|=(wait)?(FASYNC):(FNDELAY|FASYNC);
   /*Allow receipt of asynchronous I/O signals and set non-blocking I/O.*/
   if(fcntl(fd,F_SETFL,flags)<0){
      DBPRINTF(2,"fcntl(F_SETFL) failed.\n");
      sigaction(rt_sig_no,&org_signal_handler,NULL);/*Restore old handler.*/
      return(-1);
   }
#endif

   /*Good return.*/
   return(0);
}
/**********************************End-set_io_async****************************/

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


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

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

* Re: SIGIO using UDP sockets just hangs (permantely blocks) socket I/O.
  2017-09-30 12:53 SIGIO using UDP sockets just hangs (permantely blocks) socket I/O tvonderhaar
@ 2017-10-10  9:58 ` Corinna Vinschen
  0 siblings, 0 replies; 2+ messages in thread
From: Corinna Vinschen @ 2017-10-10  9:58 UTC (permalink / raw)
  To: cygwin

[-- Attachment #1: Type: text/plain, Size: 1535 bytes --]

On Sep 30 11:50, tvonderhaar wrote:
>     Dear cygwin_list,
> 
>     I have tried to get signals working with UDP bound sockets. I have
> tried every combination and order of the included code, but once I
> ioctl() the socket with "FIOASYNC" I get one signal from the socket and
> the previously "FNDELAY" set socket blocks forever on a call to
> recvfrom(). I can detect the block with a select, but it never becomes
> ready. This code works flawlessly on Linux and in the past worked on
> SUN,HP- UX(I remove the HP specific code) and Alpha OSes. If I don't
> perform the ioctl() with "FIOASYNC" or perform a second call to ioctl()
> with the "set_state=0" the socket does not block as expected, but I of
> course I don't get my SIGIO signal. Note: I make the call to the
> function as follows:
> 
>    set_io_async(udp_socket_fd,call_back,SIGIO,FALSE);
>   /*FASLE defined as '0' and SIGIO as defined by CYGWIN.*/
> 
>  I only found one google search of an individual attempting non-blocking
> asynchronous() I/O and they indicated it worked using this code sequence
> under CYGWIN. "FASYNC" has no affect on CYGWIN using fcntl() as after

FASYNC/O_ASYNC is not supported at all by Cygwin and never was.
Signal-driven IO was never very high on the wishlist, so it wasn't fully
implemented.  What about using select from another thread instead?


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

end of thread, other threads:[~2017-10-10  9:58 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-09-30 12:53 SIGIO using UDP sockets just hangs (permantely blocks) socket I/O tvonderhaar
2017-10-10  9:58 ` Corinna Vinschen

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