help-gsasl
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 3/3] change poll() code to deal with buffered streams


From: Enrico Scholz
Subject: [PATCH 3/3] change poll() code to deal with buffered streams
Date: Sat, 12 Nov 2011 23:33:45 +0100

As poll() was applied to file descriptors while rest of program used
data structures which buffer read data (FILE, gnutls session), the
poll() might block forever because already available data was not
recognized by it.

Patch integrates the previous getline() and gnutls buffering patches to
emulate POLLIN on file descriptors where data has been buffered.

Signed-off-by: Enrico Scholz <address@hidden>
---
 src/gsasl.c |   33 ++++++++++++++++++++++++++++++++-
 1 files changed, 32 insertions(+), 1 deletions(-)

diff --git a/src/gsasl.c b/src/gsasl.c
index 53dc116..b71bea8 100644
--- a/src/gsasl.c
+++ b/src/gsasl.c
@@ -859,11 +859,42 @@ main (int argc, char *argv[])
          while (1)
            {
              int rc;
+             struct pollfd *start_pfd = &pfd[0];
+             nfds_t num_pfd = sockfd ? 2 : 1;
+             int xtra_ev = 0;
 
              pfd[0].revents = 0;
              pfd[1].revents = 0;
 
-             rc = poll (pfd, sockfd ? 2 : 1, -1);
+             if (streaminput_have_chars(&stdinstream))
+               {
+                 start_pfd = &pfd[1];
+                 --num_pfd;
+                 ++xtra_ev;
+                 pfd[0].revents |= POLLIN;
+               }
+
+             if (sockfd && pending_sock_data)
+               {
+                 --num_pfd;
+                 ++xtra_ev;
+                 pfd[1].revents |= POLLIN;
+               }
+
+             if (num_pfd == 0)
+               rc = 0;
+             else
+               {
+                 /* having xtra_ev > 0 means, that there is data available in
+                    a buffering data structure. Use a timeout of 0 in this
+                    case to return immediately when other fds would
+                    block.  */
+                 rc = poll(start_pfd, num_pfd, xtra_ev > 0 ? 0 : -1);
+                 if (rc >= 0)
+                   /* emulate events which were set above */
+                   rc += xtra_ev;
+               }
+
              if (rc < 0 && errno == EINTR)
                continue;
 
-- 
1.7.7.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]