@@ -91,7 +91,7 @@ struct ib_socket_shared_state_t
91
91
std::queue<std::pair<std::error_code, std::size_t >>
92
92
recv_result; // TODO optimize with circle buffer
93
93
callback_t recv_cb_;
94
- callback_t send_cb_;
94
+ std::deque< callback_t > send_cb_;
95
95
ib_buffer_t recv_buf_;
96
96
std::shared_ptr<ib_buffer_pool_t > ib_buffer_pool_;
97
97
std::unique_ptr<asio::posix::stream_descriptor> fd_;
@@ -182,7 +182,7 @@ struct ib_socket_shared_state_t
182
182
struct resume_struct {
183
183
std::error_code ec;
184
184
std::size_t len;
185
- callback_t * cb ;
185
+ uint64_t wr_id ;
186
186
};
187
187
188
188
void post_send_impl (std::span<ibv_sge> sge, callback_t && handler) {
@@ -195,12 +195,11 @@ struct ib_socket_shared_state_t
195
195
sge = std::move (sge_copy)]() mutable {
196
196
ibv_send_wr sr{};
197
197
ibv_send_wr* bad_wr = nullptr ;
198
- self->send_cb_ = std::move (handler);
199
198
if (sge.size () && sge[0 ].lkey == 0 ) {
200
199
sr.send_flags = IBV_SEND_INLINE;
201
200
}
202
201
sr.next = NULL ;
203
- sr.wr_id = ( uintptr_t )&self-> send_cb_ ;
202
+ sr.wr_id = 1 ;
204
203
sr.sg_list = sge.data ();
205
204
sr.num_sge = sge.size ();
206
205
sr.opcode = IBV_WR_SEND;
@@ -211,13 +210,16 @@ struct ib_socket_shared_state_t
211
210
}
212
211
// post the receive request to the RQ
213
212
else if (auto ec = ibv_post_send (self->qp_ .get (), &sr, &bad_wr); ec) {
214
- err = std::make_error_code (std::errc{std::abs (ec) });
213
+ err = std::make_error_code (std::errc{ec });
215
214
ELOG_ERROR << " ibv post send failed: " << err.message ();
216
215
}
217
216
if (err) {
218
217
ib_socket_shared_state_t::resume (std::pair{err, std::size_t {0 }},
219
218
handler);
220
219
}
220
+ else {
221
+ self->send_cb_ .push_back (std::move (handler));
222
+ }
221
223
},
222
224
executor_->get_asio_executor ())
223
225
.start ([](auto && res) {
@@ -243,7 +245,7 @@ struct ib_socket_shared_state_t
243
245
struct ibv_wc wc{};
244
246
int ne = 0 ;
245
247
std::vector<resume_struct> vec;
246
- callback_t tmp_callback ;
248
+ callback_t tmp_recv_callback ;
247
249
while ((ne = ibv_poll_cq (cq_.get (), 1 , &wc)) != 0 ) {
248
250
if (ne < 0 ) {
249
251
ELOG_ERROR << " poll CQ failed:" << ne;
@@ -275,8 +277,8 @@ struct ib_socket_shared_state_t
275
277
close ();
276
278
}
277
279
}
278
- tmp_callback = std::move (recv_cb_);
279
- vec.push_back ({ec, wc.byte_len , &tmp_callback });
280
+ tmp_recv_callback = std::move (recv_cb_);
281
+ vec.push_back ({ec, wc.byte_len , 0 });
280
282
}
281
283
else {
282
284
recv_result.push (std::pair{ec, (std::size_t )wc.byte_len });
@@ -289,15 +291,21 @@ struct ib_socket_shared_state_t
289
291
}
290
292
}
291
293
else {
292
- vec.push_back ({ec, wc.byte_len , ( callback_t *) wc.wr_id });
294
+ vec.push_back ({ec, wc.byte_len , wc.wr_id });
293
295
}
294
296
if (cq_ == nullptr ) {
295
297
break ;
296
298
}
297
299
}
298
300
}
299
301
for (auto & result : vec) {
300
- resume (std::pair{result.ec , result.len }, *result.cb );
302
+ if (result.wr_id == 0 ) {
303
+ resume (std::pair{result.ec , result.len }, tmp_recv_callback);
304
+ }
305
+ else {
306
+ resume (std::pair{result.ec , result.len }, send_cb_.front ());
307
+ send_cb_.pop_front ();
308
+ }
301
309
}
302
310
return ec;
303
311
}
@@ -333,7 +341,7 @@ struct ibverbs_config {
333
341
uint32_t cq_size = 128 ;
334
342
uint32_t recv_buffer_cnt = 4 ;
335
343
ibv_qp_type qp_type = IBV_QPT_RC;
336
- ibv_qp_cap cap = {.max_send_wr = 2 ,
344
+ ibv_qp_cap cap = {.max_send_wr = 32 ,
337
345
.max_recv_wr = 32 ,
338
346
.max_send_sge = 3 ,
339
347
.max_recv_sge = 1 ,
@@ -389,7 +397,8 @@ class ib_socket_t {
389
397
~ib_socket_t () { close (); }
390
398
391
399
bool is_open () const noexcept {
392
- return state_->fd_ != nullptr && state_->fd_ ->is_open ();
400
+ return state_->fd_ != nullptr && state_->fd_ ->is_open () &&
401
+ !state_->has_close_ ;
393
402
}
394
403
std::shared_ptr<ib_buffer_pool_t > buffer_pool () const noexcept {
395
404
return state_->ib_buffer_pool_ ;
@@ -799,7 +808,7 @@ class ib_socket_t {
799
808
void init_fd () {
800
809
int r = ibv_req_notify_cq (state_->cq_ .get (), 0 );
801
810
if (r) {
802
- auto err_code = std::make_error_code (std::errc{errno });
811
+ auto err_code = std::make_error_code (std::errc{r });
803
812
ELOG_ERROR << " ibv_req_notify_cq failed: " << err_code.message ();
804
813
throw std::system_error (err_code);
805
814
}
@@ -823,12 +832,15 @@ class ib_socket_t {
823
832
}
824
833
825
834
if (ec) {
826
- auto send_cb = std::move (self->send_cb_ );
827
835
self->close ();
828
836
ib_socket_shared_state_t::resume (std::pair{ec, std::size_t {0 }},
829
837
self->recv_cb_ );
830
- ib_socket_shared_state_t::resume (std::pair{ec, std::size_t {0 }},
831
- send_cb);
838
+ while (!self->send_cb_ .empty ()) {
839
+ ib_socket_shared_state_t::resume (std::pair{ec, std::size_t {0 }},
840
+ self->send_cb_ .front ());
841
+ self->send_cb_ .pop_front ();
842
+ }
843
+
832
844
break ;
833
845
}
834
846
}
0 commit comments