Message ID | 20170619125246.65326-2-martin@martin.st |
---|---|
State | Committed |
Commit | eb061ad6fd0e3cea7cf7cfbff0749bc90dd7d888 |
Headers | show |
On Mon, Jun 19, 2017 at 03:52:46PM +0300, Martin Storsjö wrote: > The rtmp protocol uses nonblocking reads, to poll for incoming > messages from the server while publishing a stream. Prior to > 94599a6de3822b13c94096d764868128f388ba28 and > d13b124eaf452b267480074b2e6946538ed03a6e, the tls protocol > handled the nonblocking flag. Those commit logs claim that the tls protocol does not have to handle the nonblocking flag, apparently it has to now. An explanation would be illuminating. probably OK > --- a/libavformat/tls_gnutls.c > +++ b/libavformat/tls_gnutls.c > @@ -97,7 +98,10 @@ static ssize_t gnutls_url_pull(gnutls_transport_ptr_t transport, > return ret; > if (ret == AVERROR_EXIT) > return 0; > - errno = EIO; > + if (ret == AVERROR(EAGAIN)) > + errno = EAGAIN; > + else > + errno = EIO; > return -1; > } > > @@ -110,7 +114,10 @@ static ssize_t gnutls_url_push(gnutls_transport_ptr_t transport, > return ret; > if (ret == AVERROR_EXIT) > return 0; > - errno = EIO; > + if (ret == AVERROR(EAGAIN)) > + errno = EAGAIN; > + else > + errno = EIO; > return -1; > } Convert to switch/case at some point? Diego
On Tue, 20 Jun 2017, Diego Biurrun wrote: > On Mon, Jun 19, 2017 at 03:52:46PM +0300, Martin Storsjö wrote: >> The rtmp protocol uses nonblocking reads, to poll for incoming >> messages from the server while publishing a stream. Prior to >> 94599a6de3822b13c94096d764868128f388ba28 and >> d13b124eaf452b267480074b2e6946538ed03a6e, the tls protocol >> handled the nonblocking flag. > > Those commit logs claim that the tls protocol does not have to handle > the nonblocking flag, apparently it has to now. An explanation would > be illuminating. It's more or less a revert of d13b124eaf452b267480074b2e6946538ed03a6e. After chaining the IO calls to the underlying urlprotocol, we didn't need to handle nonblocking mode here when the tls protocol was used in blocking mode. I had overlooked the fact that callers actually wanted to use it in nonblocking mode as well (as the rtmps protocol does), and at that point when I removed it, the fact that it supported nonblocking mode felt more like a sideeffect, not a necessary feature in itself. But it is indeed necessary for rtmps. // Martin
diff --git a/libavformat/tls_gnutls.c b/libavformat/tls_gnutls.c index 1ae7656dcb..7bfe02deb0 100644 --- a/libavformat/tls_gnutls.c +++ b/libavformat/tls_gnutls.c @@ -61,6 +61,7 @@ static int print_tls_error(URLContext *h, int ret) { switch (ret) { case GNUTLS_E_AGAIN: + return AVERROR(EAGAIN); case GNUTLS_E_INTERRUPTED: break; case GNUTLS_E_WARNING_ALERT_RECEIVED: @@ -97,7 +98,10 @@ static ssize_t gnutls_url_pull(gnutls_transport_ptr_t transport, return ret; if (ret == AVERROR_EXIT) return 0; - errno = EIO; + if (ret == AVERROR(EAGAIN)) + errno = EAGAIN; + else + errno = EIO; return -1; } @@ -110,7 +114,10 @@ static ssize_t gnutls_url_push(gnutls_transport_ptr_t transport, return ret; if (ret == AVERROR_EXIT) return 0; - errno = EIO; + if (ret == AVERROR(EAGAIN)) + errno = EAGAIN; + else + errno = EIO; return -1; } @@ -202,7 +209,11 @@ fail: static int tls_read(URLContext *h, uint8_t *buf, int size) { TLSContext *c = h->priv_data; - int ret = gnutls_record_recv(c->session, buf, size); + int ret; + // Set or clear the AVIO_FLAG_NONBLOCK on c->tls_shared.tcp + c->tls_shared.tcp->flags &= ~AVIO_FLAG_NONBLOCK; + c->tls_shared.tcp->flags |= h->flags & AVIO_FLAG_NONBLOCK; + ret = gnutls_record_recv(c->session, buf, size); if (ret > 0) return ret; if (ret == 0) @@ -213,7 +224,11 @@ static int tls_read(URLContext *h, uint8_t *buf, int size) static int tls_write(URLContext *h, const uint8_t *buf, int size) { TLSContext *c = h->priv_data; - int ret = gnutls_record_send(c->session, buf, size); + int ret; + // Set or clear the AVIO_FLAG_NONBLOCK on c->tls_shared.tcp + c->tls_shared.tcp->flags &= ~AVIO_FLAG_NONBLOCK; + c->tls_shared.tcp->flags |= h->flags & AVIO_FLAG_NONBLOCK; + ret = gnutls_record_send(c->session, buf, size); if (ret > 0) return ret; if (ret == 0)