From: Marcel Holtmann Date: Sun, 7 Nov 2010 11:33:23 +0000 (+0100) Subject: Deal with EAGAIN and GnuTLS channels X-Git-Tag: 0.64~90 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3163467423257f6567fe977810ad42388a95fcdb;p=platform%2Fupstream%2Fconnman.git Deal with EAGAIN and GnuTLS channels --- diff --git a/gweb/giognutls.c b/gweb/giognutls.c index e6c1bde..06eff4a 100644 --- a/gweb/giognutls.c +++ b/gweb/giognutls.c @@ -44,6 +44,7 @@ struct _GIOGnuTLSChannel { gnutls_certificate_credentials_t cred; gnutls_session session; gboolean established; + gboolean again; }; struct _GIOGnuTLSWatch { @@ -68,15 +69,18 @@ static GIOStatus check_handshake(GIOChannel *channel, GError **err) DBG("channel %p", channel); -again: if (gnutls_channel->established == TRUE) return G_IO_STATUS_NORMAL; +again: result = gnutls_handshake(gnutls_channel->session); if (result == GNUTLS_E_INTERRUPTED || result == GNUTLS_E_AGAIN) { GIOFlags flags = g_io_channel_get_flags(channel); + if (gnutls_channel->again == TRUE) + return G_IO_STATUS_AGAIN; + if (flags & G_IO_FLAG_NONBLOCK) return G_IO_STATUS_AGAIN; @@ -124,6 +128,9 @@ again: if (result == GNUTLS_E_INTERRUPTED || result == GNUTLS_E_AGAIN) { GIOFlags flags = g_io_channel_get_flags(channel); + if (gnutls_channel->again == TRUE) + return G_IO_STATUS_AGAIN; + if (flags & G_IO_FLAG_NONBLOCK) return G_IO_STATUS_AGAIN; @@ -172,6 +179,9 @@ again: if (result == GNUTLS_E_INTERRUPTED || result == GNUTLS_E_AGAIN) { GIOFlags flags = g_io_channel_get_flags(channel); + if (gnutls_channel->again == TRUE) + return G_IO_STATUS_AGAIN; + if (flags & G_IO_FLAG_NONBLOCK) return G_IO_STATUS_AGAIN; @@ -352,6 +362,11 @@ static ssize_t g_io_gnutls_push_func(gnutls_transport_ptr_t transport_data, result = write(fd, buf, count); + if (result < 0 && errno == EAGAIN) + gnutls_channel->again = TRUE; + else + gnutls_channel->again = FALSE; + DBG("result %zd", result); return result; @@ -370,6 +385,11 @@ static ssize_t g_io_gnutls_pull_func(gnutls_transport_ptr_t transport_data, result = read(fd, buf, count); + if (result < 0 && errno == EAGAIN) + gnutls_channel->again = TRUE; + else + gnutls_channel->again = FALSE; + DBG("result %zd", result); return result;