filesink: handle fsync interrupted by signal (EINTR)
authorPeter Seiderer <ps.report@gmx.net>
Thu, 12 Dec 2019 10:07:07 +0000 (11:07 +0100)
committerPeter Seiderer <ps.report@gmx.net>
Thu, 12 Dec 2019 19:49:36 +0000 (20:49 +0100)
According to [1] EINTR is a possible errno for fsync() and it happens in
reality on linux (video writing via splitmuxsink with robust muxing enabled
on a cifs mounted network share), so handle it as all other EINTR
(do/while(errno == EINTR)).

Fixes:

  GError.message: Error while writing to file "vidoe_001.mp4". GError.domain: 2372 GError.code: 10 from: FileSink debug: gstfilesink.c(849): gst_file_sink_render (): /GstPipeline:Pipeline/GstSplitMuxSink:SplitMuxSink/GstBin:QueueBin/GstFileSink:FileSink: Interrupted system call

Signed-off-by: Peter Seiderer <ps.report@gmx.net>
plugins/elements/gstfilesink.c

index 0240048..c8b427b 100644 (file)
@@ -813,6 +813,7 @@ gst_file_sink_render_list (GstBaseSink * bsink, GstBufferList * buffer_list)
   GstFileSink *sink;
   guint i, num_buffers;
   gboolean sync_after = FALSE;
+  gint fsync_ret;
 
   sink = GST_FILE_SINK_CAST (bsink);
 
@@ -847,7 +848,10 @@ gst_file_sink_render_list (GstBaseSink * bsink, GstBufferList * buffer_list)
   }
 
   if (flow == GST_FLOW_OK && sync_after) {
-    if (fsync (fileno (sink->file))) {
+    do {
+      fsync_ret = fsync (fileno (sink->file));
+    } while (fsync_ret < 0 && errno == EINTR);
+    if (fsync_ret) {
       GST_ELEMENT_ERROR (sink, RESOURCE, WRITE,
           (_("Error while writing to file \"%s\"."), sink->filename),
           ("%s", g_strerror (errno)));
@@ -871,6 +875,7 @@ gst_file_sink_render (GstBaseSink * sink, GstBuffer * buffer)
   GstFlowReturn flow;
   guint8 n_mem;
   gboolean sync_after;
+  gint fsync_ret;
 
   filesink = GST_FILE_SINK_CAST (sink);
 
@@ -902,7 +907,10 @@ gst_file_sink_render (GstBaseSink * sink, GstBuffer * buffer)
   }
 
   if (flow == GST_FLOW_OK && sync_after) {
-    if (fsync (fileno (filesink->file))) {
+    do {
+      fsync_ret = fsync (fileno (filesink->file));
+    } while (fsync_ret < 0 && errno == EINTR);
+    if (fsync_ret) {
       GST_ELEMENT_ERROR (filesink, RESOURCE, WRITE,
           (_("Error while writing to file \"%s\"."), filesink->filename),
           ("%s", g_strerror (errno)));