diff --git a/gst-plugin-threadshare/Cargo.toml b/gst-plugin-threadshare/Cargo.toml index 425c7c34..961ac0f6 100644 --- a/gst-plugin-threadshare/Cargo.toml +++ b/gst-plugin-threadshare/Cargo.toml @@ -5,6 +5,7 @@ authors = ["Sebastian Dröge "] license = "LGPL-2.1+" [dependencies] +libc = "0.2" glib-sys = { git = "https://github.com/gtk-rs/sys" } gobject-sys = { git = "https://github.com/gtk-rs/sys" } gio-sys = { git = "https://github.com/gtk-rs/sys" } @@ -26,6 +27,9 @@ either = "1.0" rand = "0.5" net2 = "0.2" +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["winsock2", "processthreadsapi"] } + [lib] name = "gstthreadshare" crate-type = ["cdylib", "rlib"] diff --git a/gst-plugin-threadshare/src/lib.rs b/gst-plugin-threadshare/src/lib.rs index c6d5f6ed..65f8fd30 100644 --- a/gst-plugin-threadshare/src/lib.rs +++ b/gst-plugin-threadshare/src/lib.rs @@ -17,6 +17,8 @@ #![crate_type = "cdylib"] +extern crate libc; + extern crate gio_sys as gio_ffi; extern crate glib_sys as glib_ffi; extern crate gobject_sys as gobject_ffi; @@ -47,6 +49,9 @@ extern crate lazy_static; extern crate net2; +#[cfg(windows)] +extern crate winapi; + mod iocontext; mod socket; diff --git a/gst-plugin-threadshare/src/udpsrc.rs b/gst-plugin-threadshare/src/udpsrc.rs index eda24f56..8558cd7c 100644 --- a/gst-plugin-threadshare/src/udpsrc.rs +++ b/gst-plugin-threadshare/src/udpsrc.rs @@ -95,12 +95,16 @@ impl GioSocketWrapper { #[cfg(unix)] fn get(&self) -> T { - unsafe { FromRawFd::from_raw_fd(gio_ffi::g_socket_get_fd(self.socket)) } + use libc; + + unsafe { FromRawFd::from_raw_fd(libc::dup(gio_ffi::g_socket_get_fd(self.socket))) } } #[cfg(windows)] fn get(&self) -> T { - unsafe { FromRawSocket::from_raw_socket(ffi::g_socket_get_fd(self.socket) as _) } + unsafe { + FromRawSocket::from_raw_socket(dup_socket(ffi::g_socket_get_fd(self.socket) as _) as _) + } } } @@ -120,6 +124,32 @@ impl Drop for GioSocketWrapper { } } +#[cfg(windows)] +unsafe fn dup_socket(socket: usize) -> usize { + use std::mem; + use winapi::shared::minwindef::DWORD; + use winapi::shared::ws2def; + use winapi::um::processthreadsapi; + use winapi::um::winsock2; + use winapi::um::winsock2; + + let mut proto_info = mem::zeroed(); + let ret = winsock2::WSADuplicateSocketA( + socket, + processthreadsapi::GetCurrentProcess(), + &mut proto_info, + ); + assert_eq!(ret, 0); + winsock2::WSASocketA( + ws2def::AF_INET, + ws2def::SOCK_DGRAM, + ws2def::IPPROTO_UDP, + &mut proto_info, + 0, + 0, + ); +} + #[derive(Debug, Clone)] struct Settings { address: Option, @@ -223,8 +253,8 @@ pub struct UdpReader { } impl UdpReader { - pub fn new(socket: net::UdpSocket) -> Self { - Self { socket: socket } + fn new(socket: net::UdpSocket) -> Self { + Self { socket } } } @@ -668,7 +698,9 @@ impl UdpSrc { // Store the socket as used-socket in the settings #[cfg(unix)] { - let fd = socket.as_raw_fd(); + use libc; + + let fd = unsafe { libc::dup(socket.as_raw_fd()) }; // This is technically unsafe because it allows // us to share the fd between the socket and the @@ -694,7 +726,7 @@ impl UdpSrc { } #[cfg(windows)] { - let fd = socket.as_raw_socket(); + let fd = unsafe { dup_socket(socket.as_raw_socket() as _) as _ }; // This is technically unsafe because it allows // us to share the fd between the socket and the