nio: Make the callback futures Sync/Send.

master
Damir Jelić 2019-10-31 09:17:13 +01:00
parent 71d8500453
commit 066d76cc8e
3 changed files with 26 additions and 28 deletions

View File

@ -3,8 +3,8 @@
use std::{env, process::exit}; use std::{env, process::exit};
use std::pin::Pin; use std::pin::Pin;
use std::future::Future; use std::future::Future;
use std::sync::{Arc, Mutex};
use std::rc::Rc; use std::rc::Rc;
use std::cell::RefCell;
use matrix_nio::{ use matrix_nio::{
self, self,
@ -16,8 +16,8 @@ use matrix_nio::{
AsyncClient, AsyncClientConfig, SyncSettings, Room AsyncClient, AsyncClientConfig, SyncSettings, Room
}; };
async fn async_helper(room: Rc<RefCell<Room>>, event: Rc<RoomEvent>) { async fn async_helper(room: Arc<Mutex<Room>>, event: Arc<RoomEvent>) {
let room = room.borrow(); let room = room.lock().unwrap();
if let RoomEvent::RoomMessage(MessageEvent { if let RoomEvent::RoomMessage(MessageEvent {
content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }), content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
sender, sender,
@ -27,10 +27,9 @@ async fn async_helper(room: Rc<RefCell<Room>>, event: Rc<RoomEvent>) {
let user = room.members.get(&sender.to_string()).unwrap(); let user = room.members.get(&sender.to_string()).unwrap();
println!("{}: {}", user.display_name.as_ref().unwrap_or(&sender.to_string()), msg_body); println!("{}: {}", user.display_name.as_ref().unwrap_or(&sender.to_string()), msg_body);
} }
} }
fn async_callback(room: Rc<RefCell<Room>>, event: Rc<RoomEvent>) -> Pin<Box<dyn Future<Output = ()>>> { fn async_callback(room: Arc<Mutex<Room>>, event: Arc<RoomEvent>) -> Pin<Box<dyn Future<Output = ()> + Send + Sync >> {
Box::pin(async_helper(room, event)) Box::pin(async_helper(room, event))
} }

View File

@ -2,7 +2,7 @@ use std::convert::{TryFrom, TryInto};
use std::future::Future; use std::future::Future;
use std::pin::Pin; use std::pin::Pin;
use std::rc::Rc; use std::rc::Rc;
use std::cell::RefCell; use std::sync::{Arc, Mutex};
use http::Method as HttpMethod; use http::Method as HttpMethod;
use http::Response as HttpResponse; use http::Response as HttpResponse;
@ -22,7 +22,7 @@ use crate::error::{Error, InnerError};
use crate::session::Session; use crate::session::Session;
type RoomEventCallback = Box::<dyn FnMut(&Room, &RoomEvent)>; type RoomEventCallback = Box::<dyn FnMut(&Room, &RoomEvent)>;
type RoomEventCallbackF = Box::<dyn FnMut(Rc<RefCell<Room>>, Rc<RoomEvent>) -> Pin<Box<dyn Future<Output = ()>>>>; type RoomEventCallbackF = Box::<dyn FnMut(Arc<Mutex<Room>>, Arc<RoomEvent>) -> Pin<Box<dyn Future<Output = ()> + Send + Sync>> + Send + Sync>;
pub struct AsyncClient { pub struct AsyncClient {
/// The URL of the homeserver to connect to. /// The URL of the homeserver to connect to.
@ -31,8 +31,8 @@ pub struct AsyncClient {
http_client: reqwest::Client, http_client: reqwest::Client,
/// User session data. /// User session data.
base_client: BaseClient, base_client: BaseClient,
/// Event callbacks // /// Event callbacks
event_callbacks: Vec<RoomEventCallback>, // event_callbacks: Vec<RoomEventCallback>,
/// Event futures /// Event futures
event_futures: Vec<RoomEventCallbackF>, event_futures: Vec<RoomEventCallbackF>,
} }
@ -166,18 +166,18 @@ impl AsyncClient {
homeserver, homeserver,
http_client, http_client,
base_client: BaseClient::new(session), base_client: BaseClient::new(session),
event_callbacks: Vec::new(), // event_callbacks: Vec::new(),
event_futures: Vec::new(), event_futures: Vec::new(),
}) })
} }
pub fn add_event_callback( // pub fn add_event_callback(
&mut self, // &mut self,
event_type: EventType, // event_type: EventType,
callback: RoomEventCallback, // callback: RoomEventCallback,
) { // ) {
self.event_callbacks.push(callback); // self.event_callbacks.push(callback);
} // }
pub fn add_event_future( pub fn add_event_future(
&mut self, &mut self,
@ -245,12 +245,12 @@ impl AsyncClient {
let room = self.base_client.joined_rooms.get(&room_id).unwrap(); let room = self.base_client.joined_rooms.get(&room_id).unwrap();
for mut cb in &mut self.event_callbacks { // for mut cb in &mut self.event_callbacks {
cb(&room.borrow(), &event); // cb(&room.lock().unwrap(), &event);
} // }
for mut cb in &mut self.event_futures { for mut cb in &mut self.event_futures {
cb(room.clone(), Rc::new(event.clone())).await; cb(room.clone(), Arc::new(event.clone())).await;
} }
} }
} }

View File

@ -4,8 +4,7 @@ use crate::api::r0 as api;
use crate::events::collections::all::{RoomEvent, StateEvent}; use crate::events::collections::all::{RoomEvent, StateEvent};
use crate::events::room::member::{MemberEvent, MembershipState}; use crate::events::room::member::{MemberEvent, MembershipState};
use crate::session::Session; use crate::session::Session;
use std::rc::Rc; use std::sync::{Arc, Mutex};
use std::cell::RefCell;
pub type Token = String; pub type Token = String;
pub type RoomId = String; pub type RoomId = String;
@ -150,7 +149,7 @@ pub struct Client {
/// The current sync token that should be used for the next sync call. /// The current sync token that should be used for the next sync call.
pub sync_token: Option<Token>, pub sync_token: Option<Token>,
/// A map of the rooms our user is joined in. /// A map of the rooms our user is joined in.
pub joined_rooms: HashMap<RoomId, Rc<RefCell<Room>>>, pub joined_rooms: HashMap<RoomId, Arc<Mutex<Room>>>,
} }
impl Client { impl Client {
@ -186,11 +185,11 @@ impl Client {
self.session = Some(session); self.session = Some(session);
} }
fn get_or_create_room(&mut self, room_id: &RoomId) -> &mut Rc<RefCell<Room>> { fn get_or_create_room(&mut self, room_id: &RoomId) -> &mut Arc<Mutex<Room>> {
self.joined_rooms self.joined_rooms
.entry(room_id.to_string()) .entry(room_id.to_string())
.or_insert( .or_insert(
Rc::new(RefCell::new(Room::new( Arc::new(Mutex::new(Room::new(
room_id, room_id,
&self &self
.session .session
@ -210,7 +209,7 @@ impl Client {
/// Returns true if the membership list of the room changed, false /// Returns true if the membership list of the room changed, false
/// otherwise. /// otherwise.
pub fn receive_joined_timeline_event(&mut self, room_id: &RoomId, event: &RoomEvent) -> bool { pub fn receive_joined_timeline_event(&mut self, room_id: &RoomId, event: &RoomEvent) -> bool {
let mut room = self.get_or_create_room(room_id).borrow_mut(); let mut room = self.get_or_create_room(room_id).lock().unwrap();
room.receive_timeline_event(event) room.receive_timeline_event(event)
} }
@ -223,7 +222,7 @@ impl Client {
/// Returns true if the membership list of the room changed, false /// Returns true if the membership list of the room changed, false
/// otherwise. /// otherwise.
pub fn receive_joined_state_event(&mut self, room_id: &RoomId, event: &StateEvent) -> bool { pub fn receive_joined_state_event(&mut self, room_id: &RoomId, event: &StateEvent) -> bool {
let mut room = self.get_or_create_room(room_id).borrow_mut(); let mut room = self.get_or_create_room(room_id).lock().unwrap();
room.receive_state_event(event) room.receive_state_event(event)
} }
} }