Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UnsolicitedResponse isn't Send #254

Open
jonhoo opened this issue Feb 5, 2023 · 11 comments · May be fixed by #260
Open

UnsolicitedResponse isn't Send #254

jonhoo opened this issue Feb 5, 2023 · 11 comments · May be fixed by #260

Comments

@jonhoo
Copy link
Owner

jonhoo commented Feb 5, 2023

As reported in #250, the UnsolicitedResponse type isn't Send, but it should be. We should fix that.

@dequbed
Copy link

dequbed commented Feb 6, 2023

Are you sure? rustdoc (and static_assertions) do show an Auto Trait implementation for Send and Sync on imap::types::UnsolicitedResponse.

Connection<T>, Client<T> and Session<T> do all also implement Send as long as T does, however they are !Sync. However that's not because of UnsolicitedResponse but because std::mpsc::Sender and std::mpsc::Receiver are always !Sync

@jonhoo
Copy link
Owner Author

jonhoo commented Feb 11, 2023

Huh, that's very weird indeed. In that case I don't know what was causing #250. There, @soywod claimed that mpsc::Sender<UnsolicitedResponse> and mpsc::Receiver<UnsolicitedResponse> weren't thread-safe, but they should be if the underlying type is Send (which it apparently is). @soywod can you speak more to how exactly the compiler was complaining at you?

@soywod
Copy link
Contributor

soywod commented Feb 17, 2023

Here the error I get:

error[E0277]: `std::sync::mpsc::Sender<UnsolicitedResponse>` cannot be shared between threads safely
   --> src/backend/imap/backend.rs:404:10
    |
404 | impl<'a> Backend for ImapBackend<'a> {
    |          ^^^^^^^ `std::sync::mpsc::Sender<UnsolicitedResponse>` cannot be shared between threads safely
    |
    = help: within `backend::imap::backend::ImapBackend<'a>`, the trait `Sync` is not implemented for `std::sync::mpsc::Sender<UnsolicitedResponse>`
    = note: required because it appears within the type `Session<ImapSessionStream>`

When I said "not thread-safe" I meant not Sync nor Send, and indeed std::mpsc::Sender is not Sync by definition.

@MTRNord
Copy link

MTRNord commented Feb 21, 2023

Note that std::sync::mpsc::Receiver isn't Sync, either. So in a std::sync::RwLock type like used by relm4 (higher level gtk lib) this causes further issues.

@MTRNord
Copy link

MTRNord commented Feb 21, 2023

Fixing the sender on the other hand would be possible with https://doc.rust-lang.org/std/sync/mpsc/fn.sync_channel.html however the same error would appear for the Receiver then

@dequbed
Copy link

dequbed commented Feb 23, 2023

Fixing the sender on the other hand would be possible with https://doc.rust-lang.org/std/sync/mpsc/fn.sync_channel.html however the same error would appear for the Receiver then

Hmm, as I understand the code the unsolicited_responses is really mostly used in a 'self-pipe' pattern, with Session always holding both the sending and receiving end and in essence using it as a FIFO queue. Especially given that right now the uses of unsolicited_responses_tx always take it as a &mut anyway, I do think it would make sense to use a VecDeque or plain Vec instead. That would also enable the multi-threaded access patterns that I think @soywod wants to work with.

Your thoughts @jonhoo? I'd be happy to write a PR for that change if you agree that it makes sense.

@soywod
Copy link
Contributor

soywod commented Feb 23, 2023 via email

@jonhoo
Copy link
Owner Author

jonhoo commented Mar 5, 2023

Ah, so the concern is actually that the client isn't Send/Sync (because it holds these senders/receivers), not that the elements of the channel aren't. That does make more sense! Yes, I think replacing it with a VecDeque makes a lot of sense, and would be happy to look at a PR!

@soywod soywod linked a pull request May 11, 2023 that will close this issue
@soywod
Copy link
Contributor

soywod commented May 11, 2023

I initiated a PR, please let me know if it resembles what you had in mind.

@soywod
Copy link
Contributor

soywod commented May 12, 2023

With the PR, I do not have anymore the cannot be shared between threads safely, but I still cannot run multiple tasks in parallel using a same Session. My intuition is that every session fn borrows self as mut &self mut which cannot be shared safely between threads without a Mutex. The PR has no impact on the initial problem.

@jonhoo
Copy link
Owner Author

jonhoo commented Aug 6, 2023

Ah, yes, so, that's sort of fundamental to the IMAP protocol. It doesn't allow for multiple concurrent requests. So you'd need to either use a Mutex or spin up a separate Session for each client unfortunately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants