ipcpipeline: fix crash and error on windows with SOCKET or _pipe()
authorjinsl00000 <jinsl00000@msn.cn>
Fri, 25 Feb 2022 07:00:05 +0000 (15:00 +0800)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Tue, 1 Mar 2022 06:31:51 +0000 (06:31 +0000)
The fd was in different meanings on windows:
POSIX read and write use the fd as a file descriptor.
The gst_poll use the fd as a WSASocket.

This patch use WSASocket as default on windows. This is a temporary measure, because IPC has many different implement. There may be a better way in the future.

See #1044

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1791>

subprojects/gst-plugins-bad/sys/ipcpipeline/gstipcpipelinecomm.c
subprojects/gst-plugins-bad/sys/ipcpipeline/meson.build

index 7d9d720..afe61b8 100644 (file)
 #  include <unistd.h>
 #endif
 #ifdef _MSC_VER
-/* ssize_t is not available, so match return value of read()/write() on MSVC */
-#define ssize_t int
-/* read, write */
-#include <io.h>
+/* ssize_t is not available, so match return value of recv()/send() on MSVC */
+#  define ssize_t int
+#  include <winsock2.h>
 #endif
 #include <errno.h>
 #include <string.h>
@@ -230,6 +229,20 @@ write_to_fd_raw (GstIpcPipelineComm * comm, const void *data, size_t size)
   GST_TRACE_OBJECT (comm->element, "Writing %u bytes to fdout",
       (unsigned) size);
   while (size) {
+#ifdef _MSC_VER
+    ssize_t written =
+        send (comm->fdout, (const unsigned char *) data + offset, size, 0);
+    if (written < 0) {
+      int last_error = WSAGetLastError ();
+      if (last_error == WSAEWOULDBLOCK)
+        continue;
+      gchar *error_text = g_win32_error_message (last_error);
+      GST_ERROR_OBJECT (comm->element, "Failed to write to fd: %s", error_text);
+      g_free (error_text);
+      ret = FALSE;
+      goto done;
+    }
+#else
     ssize_t written =
         write (comm->fdout, (const unsigned char *) data + offset, size);
     if (written < 0) {
@@ -240,6 +253,7 @@ write_to_fd_raw (GstIpcPipelineComm * comm, const void *data, size_t size)
       ret = FALSE;
       goto done;
     }
+#endif
     size -= written;
     offset += written;
   }
@@ -1754,7 +1768,19 @@ again:
       mem = gst_allocator_alloc (NULL, comm->read_chunk_size, NULL);
 
     gst_memory_map (mem, &map, GST_MAP_WRITE);
+#ifdef _MSC_VER
+    sz = recv (comm->pollFDin.fd, map.data, map.size, 0);
+    if (sz < 0) {
+      int last_error = WSAGetLastError ();
+      if (last_error == WSAEWOULDBLOCK) {
+        errno = EAGAIN;
+      } else {
+        errno = last_error;
+      }
+    }
+#else
     sz = read (comm->pollFDin.fd, map.data, map.size);
+#endif
     gst_memory_unmap (mem, &map);
 
     if (sz <= 0) {
index 8d449a0..79174c6 100644 (file)
@@ -15,7 +15,7 @@ gstipcpipeline = library('gstipcpipeline',
   ipcpipeline_sources,
   c_args : gst_plugins_bad_args,
   include_directories : [configinc],
-  dependencies : [gstbase_dep],
+  dependencies : [gstbase_dep] + winsock2,
   install : true,
   install_dir : plugins_install_dir,
 )