Commit 9750195c authored by Sebastian Dröge's avatar Sebastian Dröge 🍵

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.
parent 4ac6863e
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment