public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
From: tvonderhaar <tlvonderhaar@gmail.com>
To: "cygwin@cygwin.com" <cygwin@cygwin.com>
Subject: SIGIO using UDP sockets just hangs (permantely blocks) socket I/O.
Date: Sat, 30 Sep 2017 12:53:00 -0000	[thread overview]
Message-ID: <embecdb725-8b17-4963-84ed-12e570da7532@str-c> (raw)

[-- 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

             reply	other threads:[~2017-09-30 11:51 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-30 12:53 tvonderhaar [this message]
2017-10-10  9:58 ` Corinna Vinschen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=embecdb725-8b17-4963-84ed-12e570da7532@str-c \
    --to=tlvonderhaar@gmail.com \
    --cc=cygwin@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).