[vlc-commits] smb2: fix teardown when interrupted
Thomas Guillem
git at videolan.org
Mon Aug 12 09:00:32 CEST 2019
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Thu Aug 8 14:55:34 2019 +0200| [2dbee7d17bc40104781ca1737f6b709fa367ffe8] | committer: Thomas Guillem
smb2: fix teardown when interrupted
When the input is stopped by the user, there are lot of chances that this
access is waiting for the read command completion (smb2_read_async()).
If the read command is not fully processed (since interrupted by VLC), any
future commands will fail, like smb2_close_async() when the access is finally
closed.
To fix this issue, we switch back to the posix poll() when interrupted to let a
chance to finish the current command in order to be able to close the smb2
session nicely.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=2dbee7d17bc40104781ca1737f6b709fa367ffe8
---
modules/access/smb2.c | 29 ++++++++++++++++++++++++-----
1 file changed, 24 insertions(+), 5 deletions(-)
diff --git a/modules/access/smb2.c b/modules/access/smb2.c
index 66adc28fa3..5cdbf209b4 100644
--- a/modules/access/smb2.c
+++ b/modules/access/smb2.c
@@ -135,17 +135,20 @@ smb2_set_generic_error(stream_t *access, const char *psz_func)
static int
vlc_smb2_mainloop(stream_t *access, bool teardown)
{
+#define TEARDOWN_TIMEOUT 250 /* in ms */
struct access_sys *sys = access->p_sys;
int timeout = -1;
int (*poll_func)(struct pollfd *, unsigned, int) = vlc_poll_i11e;
- if (teardown && vlc_killed())
+ if (teardown)
{
- /* The thread is interrupted, so vlc_poll_i11e will return immediatly.
- * Use poll() with a timeout instead for tear down. */
- timeout = 500;
+ /* Don't use vlc_poll_i11e that will return immediately with the EINTR
+ * errno if VLC's input is interrupted. Use the posix poll with a
+ * timeout to let a chance for a clean teardown. */
+ timeout = TEARDOWN_TIMEOUT;
poll_func = (void *)poll;
+ sys->error_status = 0;
}
sys->res_done = false;
@@ -159,11 +162,27 @@ vlc_smb2_mainloop(stream_t *access, bool teardown)
if (p_fds[0].fd == -1 || (ret = poll_func(p_fds, 1, timeout)) < 0)
{
if (errno == EINTR)
+ {
msg_Warn(access, "vlc_poll_i11e interrupted");
+ if (poll_func != (void *) poll)
+ {
+ /* Try again with a timeout to let the command complete.
+ * Indeed, if this command is interrupted, every future
+ * commands will fail and we won't be able to teardown. */
+ timeout = TEARDOWN_TIMEOUT;
+ poll_func = (void *) poll;
+ }
+ else
+ sys->error_status = -errno;
+ }
else
+ {
msg_Err(access, "vlc_poll_i11e failed");
- sys->error_status = -errno;
+ sys->error_status = -errno;
+ }
}
+ else if (ret == 0)
+ sys->error_status = -ETIMEDOUT;
else if (ret > 0 && p_fds[0].revents
&& smb2_service(sys->smb2, p_fds[0].revents) < 0)
VLC_SMB2_SET_GENERIC_ERROR(access, "smb2_service");
More information about the vlc-commits
mailing list