回答編集履歴
6
誤字を修正しました
test
CHANGED
@@ -86,7 +86,7 @@
|
|
86
86
|
|
87
87
|
|
88
88
|
|
89
|
-
`Mutex`のロックに失敗して`poll_write()`から`Poll::Pending`を返したとします。その後、ロックできる状態になったら、非同期ランタイムから再度`poll_write()`を
|
89
|
+
`Mutex`のロックに失敗して`poll_write()`から`Poll::Pending`を返したとします。その後、ロックできる状態になったら、非同期ランタイムから再度`poll_write()`を呼んでもらわないといけません。そのためには前回の`poll_write()`で引数にとった`Context`内にある`Waker`の`wake()`メソッドを呼ぶことでランタイムに通知する必要があります。
|
90
90
|
|
91
91
|
|
92
92
|
|
5
誤字を修正しました
test
CHANGED
@@ -38,7 +38,7 @@
|
|
38
38
|
|
39
39
|
// FutureExtトレイトのboxed()でPin<Box<dyn Future<Output = ..>>に
|
40
40
|
|
41
|
-
// 変換し、as_mut()でPin<&mut Future<Output = ..>>に変換すればよい。
|
41
|
+
// 変換し、as_mut()でPin<&mut dyn Future<Output = ..>>に変換すればよい。
|
42
42
|
|
43
43
|
match self.0.lock().boxed().as_mut().poll(cx) {
|
44
44
|
|
4
デッドロックに関する説明を訂正しました
test
CHANGED
@@ -70,7 +70,11 @@
|
|
70
70
|
|
71
71
|
|
72
72
|
|
73
|
-
tokioの`Runtime`のようなマルチスレッドな非同期ランタイムでは、非同期タスクに対応していない`Mutex`は使えないようです。[こちら](https://rust-lang.github.io/async-book/03_async_await/01_chapter.html?highlight=mutex#awaiting-on-a-multithreaded-executor) の説明によると、デッドロックを引き起こす恐れがあるそうです。
|
73
|
+
~~tokioの`Runtime`のようなマルチスレッドな非同期ランタイムでは、非同期タスクに対応していない`Mutex`は使えないようです。[こちら](https://rust-lang.github.io/async-book/03_async_await/01_chapter.html?highlight=mutex#awaiting-on-a-multithreaded-executor) の説明によると、デッドロックを引き起こす恐れがあるそうです。~~
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
(訂正)参照先の説明をもう一度読んだところ、デッドロックを引き起こす可能性があるのは、複数の`.await`にまたがってロックを使用するときだけだとわかりました。今回の使いかたは、それには該当しないはずです。ただデッドロックは起こらなくても、stdの`Mutex`の`lock()`はブロッキングな操作ですので、非同期タスク内から呼ぶと非同期ランタイムのexecutorスレッドの実行を一時的にブロックします。ですから性能面の影響は多少あるかもしれません。それほど長い時間はブロックしなさそうなので、無視できる範囲かもしれませんが。
|
74
78
|
|
75
79
|
|
76
80
|
|
3
追記部分の説明を改良しました
test
CHANGED
@@ -78,7 +78,11 @@
|
|
78
78
|
|
79
79
|
|
80
80
|
|
81
|
-
「追記 2020-03-17 01:20」についてですが、`tokio::sync::Mutex::try_lock()`だとダメそうな気がします。
|
81
|
+
「追記 2020-03-17 01:20」についてですが、`tokio::sync::Mutex::try_lock()`だとダメそうな気がします。
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
`Mutex`のロックに失敗して`poll_write()`から`Poll::Pending`を返したとします。その後、ロックできる状態になったら、非同期ランタイムから再度`poll_write()`を読んでもらわないといけません。そのためには前回の`poll_write()`で引数にとった`Context`内にある`Waker`の`wake()`メソッドを呼ぶことでランタイムに通知する必要があります。
|
82
86
|
|
83
87
|
|
84
88
|
|
2
「動かないようでしたら調べますので...」という一文を追加しました。
test
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
|
8
8
|
|
9
|
-
`poll_write()`の実装を以下のようにしたところコンパイルは通りました。ただし、私は`Future`トレイトや`AsyncWrite`トレイトを実装するのは不慣れですので、これで正しく動くという自信はありません。
|
9
|
+
`poll_write()`の実装を以下のようにしたところコンパイルは通りました。ただし、私は`Future`トレイトや`AsyncWrite`トレイトを実装するのは不慣れですので、これで正しく動くという自信はありません。動かないようでしたら調べますので教えてください。
|
10
10
|
|
11
11
|
|
12
12
|
|
1
質問の「追記 2020-03-17 01:20」にたいする回答を追加しました
test
CHANGED
@@ -71,3 +71,23 @@
|
|
71
71
|
|
72
72
|
|
73
73
|
tokioの`Runtime`のようなマルチスレッドな非同期ランタイムでは、非同期タスクに対応していない`Mutex`は使えないようです。[こちら](https://rust-lang.github.io/async-book/03_async_await/01_chapter.html?highlight=mutex#awaiting-on-a-multithreaded-executor) の説明によると、デッドロックを引き起こす恐れがあるそうです。
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
**追記**
|
78
|
+
|
79
|
+
|
80
|
+
|
81
|
+
「追記 2020-03-17 01:20」についてですが、`tokio::sync::Mutex::try_lock()`だとダメそうな気がします。`poll_write()`から`Poll::Pending`を返したあと、ロックできる状態になったら、非同期ランタイムから再度`poll_write()`を読んでもらわないといけません。そのためには前回の`poll_write()`で引数にとった`Context`内にある、`Waker`の`wake()`メソッドを呼ぶことでランタイムに通知する必要があります。
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
質問の追記部分にあるコードですと、`wake()`メソッドを呼ぶことがないので、ランタイムが`poll_write()`を呼んでくれなくなってしまい、非同期タスクが前に進みません。
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
回答に書いたコードでは`lock()`が返した`Future`の`poll()`で`Context`を引数として渡しています。こうすることで、ロックできる状態になったときに、tokioの`Mutex`の実装側から`wake()`を呼んでもらえます。
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
`Waker`の働きについては公式のAsync Bookの [この章](https://rust-lang.github.io/async-book/02_execution/03_wakeups.html) が参考になると思います。
|