@@ -13,7 +13,7 @@ use crate::arch::kernel::mmio as hardware;
13
13
#[ cfg( feature = "pci" ) ]
14
14
use crate :: drivers:: pci as hardware;
15
15
use crate :: executor:: vsock:: { VsockState , VSOCK_MAP } ;
16
- use crate :: fd:: { block_on, Endpoint , IoCtl , ListenEndpoint , ObjectInterface } ;
16
+ use crate :: fd:: { block_on, Endpoint , IoCtl , ListenEndpoint , ObjectInterface , PollEvent } ;
17
17
use crate :: io:: { self , Error } ;
18
18
19
19
#[ derive( Debug ) ]
@@ -59,6 +59,77 @@ impl Socket {
59
59
60
60
#[ async_trait]
61
61
impl ObjectInterface for Socket {
62
+ async fn poll ( & self , event : PollEvent ) -> io:: Result < PollEvent > {
63
+ let port = self . port . load ( Ordering :: Acquire ) ;
64
+
65
+ future:: poll_fn ( |cx| {
66
+ let mut guard = VSOCK_MAP . lock ( ) ;
67
+ let raw = guard. get_mut_socket ( port) . ok_or ( Error :: EINVAL ) ?;
68
+
69
+ match raw. state {
70
+ VsockState :: Shutdown | VsockState :: ReceiveRequest => {
71
+ let available = PollEvent :: POLLOUT
72
+ | PollEvent :: POLLWRNORM
73
+ | PollEvent :: POLLWRBAND
74
+ | PollEvent :: POLLIN
75
+ | PollEvent :: POLLRDNORM
76
+ | PollEvent :: POLLRDBAND ;
77
+
78
+ let ret = event & available;
79
+
80
+ if ret. is_empty ( ) {
81
+ Poll :: Ready ( Ok ( PollEvent :: POLLHUP ) )
82
+ } else {
83
+ Poll :: Ready ( Ok ( ret) )
84
+ }
85
+ }
86
+ VsockState :: Listen | VsockState :: Connecting => {
87
+ raw. rx_waker . register ( cx. waker ( ) ) ;
88
+ raw. tx_waker . register ( cx. waker ( ) ) ;
89
+ Poll :: Pending
90
+ }
91
+ VsockState :: Connected => {
92
+ let mut available = PollEvent :: empty ( ) ;
93
+
94
+ if !raw. buffer . is_empty ( ) {
95
+ // In case, we just establish a fresh connection in non-blocking mode, we try to read data.
96
+ available. insert (
97
+ PollEvent :: POLLIN | PollEvent :: POLLRDNORM | PollEvent :: POLLRDBAND ,
98
+ ) ;
99
+ }
100
+
101
+ let diff = raw. tx_cnt . abs_diff ( raw. peer_fwd_cnt ) ;
102
+ if diff < raw. peer_buf_alloc {
103
+ available. insert (
104
+ PollEvent :: POLLOUT | PollEvent :: POLLWRNORM | PollEvent :: POLLWRBAND ,
105
+ ) ;
106
+ }
107
+
108
+ let ret = event & available;
109
+
110
+ if ret. is_empty ( ) {
111
+ if event. intersects (
112
+ PollEvent :: POLLIN | PollEvent :: POLLRDNORM | PollEvent :: POLLRDBAND ,
113
+ ) {
114
+ raw. rx_waker . register ( cx. waker ( ) ) ;
115
+ }
116
+
117
+ if event. intersects (
118
+ PollEvent :: POLLOUT | PollEvent :: POLLWRNORM | PollEvent :: POLLWRBAND ,
119
+ ) {
120
+ raw. tx_waker . register ( cx. waker ( ) ) ;
121
+ }
122
+
123
+ Poll :: Pending
124
+ } else {
125
+ Poll :: Ready ( Ok ( ret) )
126
+ }
127
+ }
128
+ }
129
+ } )
130
+ . await
131
+ }
132
+
62
133
fn bind ( & self , endpoint : ListenEndpoint ) -> io:: Result < ( ) > {
63
134
match endpoint {
64
135
ListenEndpoint :: Vsock ( ep) => {
@@ -144,6 +215,10 @@ impl ObjectInterface for Socket {
144
215
Ok ( Endpoint :: Vsock ( endpoint) )
145
216
}
146
217
218
+ fn shutdown ( & self , _how : i32 ) -> io:: Result < ( ) > {
219
+ Ok ( ( ) )
220
+ }
221
+
147
222
fn ioctl ( & self , cmd : IoCtl , value : bool ) -> io:: Result < ( ) > {
148
223
if cmd == IoCtl :: NonBlocking {
149
224
if value {
0 commit comments