aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Parrill <[email protected]>2019-06-08 17:51:35 -0400
committerMatthew Collins <[email protected]>2019-06-09 23:50:11 +0100
commitd3fd9ff69ae1c419bf7be3c82d4b706f7cc47ead (patch)
tree1b29385c08b71cebab09f1e452c8dcc9d38e1f65
parentFix UGC UserListQuery::drop leaking (diff)
downloadsteamworks-rs-d3fd9ff69ae1c419bf7be3c82d4b706f7cc47ead.tar.xz
steamworks-rs-d3fd9ff69ae1c419bf7be3c82d4b706f7cc47ead.zip
Fix QueryResults possibly outliving the steam client by limiting it to the callback
Strictly speaking, the query result can live for as long as the steam client, but since the Arc<Inner<Manager>> that keeps the client alive isn't `Send`, we can't move it into the callback that captures the results.
-rw-r--r--src/ugc.rs17
1 files changed, 10 insertions, 7 deletions
diff --git a/src/ugc.rs b/src/ugc.rs
index b38dd2c..7982c75 100644
--- a/src/ugc.rs
+++ b/src/ugc.rs
@@ -1,10 +1,11 @@
use super::*;
+use std::error;
use std::ffi::{CStr, CString};
-use std::mem;
use std::fmt;
-use std::error;
+use std::marker;
+use std::mem;
pub struct UGC<Manager> {
pub(crate) ugc: *mut sys::ISteamUGC,
@@ -357,7 +358,7 @@ impl <Manager> UserListQuery<Manager> {
/// Runs the query
pub fn fetch<F>(mut self, mut cb: F)
- where F: FnMut(Result<QueryResults,SteamError>) + 'static + Send
+ where F: for<'a> FnMut(Result<QueryResults<'a>,SteamError>) + 'static + Send
{
let ugc = self.ugc;
let inner = Arc::clone(&self.inner);
@@ -383,6 +384,7 @@ impl <Manager> UserListQuery<Manager> {
num_results_returned: v.m_unNumResultsReturned,
num_results_total: v.m_unTotalMatchingResults,
was_cached: v.m_bCachedData,
+ _phantom: Default::default(),
};
cb(Ok(result));
});
@@ -415,21 +417,22 @@ impl <Manager> UserListQuery<Manager> {
}
/// Query results
-pub struct QueryResults {
+pub struct QueryResults<'a> {
ugc: *mut sys::ISteamUGC,
handle: sys::UGCQueryHandle_t,
num_results_returned: u32,
num_results_total: u32,
was_cached: bool,
+ _phantom: marker::PhantomData<&'a sys::ISteamUGC>,
}
-impl Drop for QueryResults {
+impl<'a> Drop for QueryResults<'a> {
fn drop(&mut self) {
unsafe {
sys::SteamAPI_ISteamUGC_ReleaseQueryUGCRequest(self.ugc, self.handle);
}
}
}
-impl QueryResults {
+impl<'a> QueryResults<'a> {
/// Were these results retreived from a cache?
pub fn was_cached(&self) -> bool {
self.was_cached
@@ -496,7 +499,7 @@ impl QueryResults {
}
/// Returns an iterator that runs over all the fetched results
- pub fn iter<'a>(&'a self) -> impl Iterator<Item=QueryResult> + 'a {
+ pub fn iter<'b>(&'b self) -> impl Iterator<Item=QueryResult> + 'b {
(0..self.returned_results())
.map(move |i| self.get(i).unwrap())
}