mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-11-26 21:41:03 +00:00
ts-udpsrc: Dup the socket so that both tokio and GIO can take ownership of it
Otherwise both would be closing the same socket, which a) breaks the second user of the socket if any and b) could on the second close cause a completely unrelated socket to be closed. Windows part of the code is untested.
This commit is contained in:
parent
4ac6863eed
commit
9750195caa
3 changed files with 47 additions and 6 deletions
|
@ -5,6 +5,7 @@ authors = ["Sebastian Dröge <sebastian@centricular.com>"]
|
|||
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"]
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -95,12 +95,16 @@ impl GioSocketWrapper {
|
|||
|
||||
#[cfg(unix)]
|
||||
fn get<T: FromRawFd>(&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<T: FromRawSocket>(&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<String>,
|
||||
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue