teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

2

tokio::sync::Mutex::try_lock を使った実装を追記

2020/03/16 16:19

投稿

techno-tanoC
techno-tanoC

スコア24

title CHANGED
File without changes
body CHANGED
@@ -7,9 +7,9 @@
7
7
  [tokio::sync::Mutex - Rust](https://docs.rs/tokio/0.2.13/tokio/sync/struct.Mutex.html)
8
8
  [std::sync::Mutex - Rust](https://doc.rust-lang.org/std/sync/struct.Mutex.html)
9
9
 
10
- ### 発生している問題・エラーメッセージ
10
+ ### 発生している問題
11
11
 
12
- `tokio::sync::Mutex` はロックを取得するのに `mutex.lock().await` する必要がありますが、 `await` は `AsyncWrite::poll_write` の中では使えないので困っています。上手く実装を与えることはできないのでしょうか?
12
+ `tokio::sync::Mutex` はロックを取得するのに `mutex.lock().await` する必要がありますが、 `await` は `AsyncWrite::poll_write` の中では使えないので困っています。上手く実装を与えることはできないのでしょうか?(追記した `try_lock` を使った実装は適切なのでしょうか? )
13
13
 
14
14
  後述の通り、代わりに `std::sync::Mutex` を用いた実装はできたので `tokio::sync::Mutex` が使えない場合はこちらを使おうと思うのですが、その場合のパフォーマンスへの影響はどのようなものでしょうか?
15
15
 
@@ -108,6 +108,35 @@
108
108
  }
109
109
  ```
110
110
 
111
+ ### 追記 2020-03-17 01:20
112
+
113
+ `tokio::sync::Mutex::try_lock()` を使うことで実装できました(これが適切な方針なのかは自信が無いのでアドバイスお願いします)
114
+
115
+ ```rust
116
+ impl<T: AsyncWrite + Unpin> AsyncWrite for Progress<T> {
117
+ fn poll_write(
118
+ self: Pin<&mut Self>,
119
+ cx: &mut Context,
120
+ buf: &[u8]
121
+ ) -> Poll<Result<usize, Error>> {
122
+ match self.0.try_lock() {
123
+ Ok(mut s) => {
124
+ let poll = Pin::new(&mut s.inner).poll_write(cx, buf);
125
+ if let Poll::Ready(Ok(n)) = poll {
126
+ s.size += n;
127
+ }
128
+ poll
129
+ },
130
+ Err(_e) => {
131
+ Poll::Pending
132
+ }
133
+ }
134
+ }
135
+
136
+ // poll_flush, poll_shutdown 略
137
+ }
138
+ ```
139
+
111
140
  ### 補足情報(FW/ツールのバージョンなど)
112
141
  rustc 1.41.1
113
142
  tokio 0.2.13

1

タスクのリンクを変更

2020/03/16 16:19

投稿

techno-tanoC
techno-tanoC

スコア24

title CHANGED
File without changes
body CHANGED
@@ -1,7 +1,7 @@
1
1
  ### 前提・実現したいこと
2
2
  マルチスレッドで共有できる書き込まれたバイト数を保持しながら書き込みを行う型を実装したいです。そこで `struct Progress<T>(std::sync::Arc<tokio::sync::Mutex<(T, usize)>>)` のような型に `AsyncWrite` を実装すると上手く抽象化できると考えました。
3
3
 
4
- ある[タスク](https://docs.rs/tokio/0.2.13/tokio/task/index.html)で書き込みを行い、他のタスクから進捗を見る感じです。
4
+ ある[タスク](https://docs.rs/tokio/0.2.13/tokio/task/index.html#what-are-tasks)で書き込みを行い、他のタスクから進捗を見る感じです。
5
5
 
6
6
  [tokio::io::AsyncWrite - Rust](https://docs.rs/tokio/0.2.13/tokio/io/trait.AsyncWrite.html)
7
7
  [tokio::sync::Mutex - Rust](https://docs.rs/tokio/0.2.13/tokio/sync/struct.Mutex.html)