: public boost::static_visitor<uint64_t> {
ImageDispatchSpec* spec;
uint64_t flag;
+ uint64_t *tokens;
- TokenRequestedVisitor(ImageDispatchSpec* spec, uint64_t _flag)
- : spec(spec), flag(_flag) {
+ TokenRequestedVisitor(ImageDispatchSpec* spec, uint64_t _flag,
+ uint64_t *tokens)
+ : spec(spec), flag(_flag), tokens(tokens) {
}
uint64_t operator()(const Read&) const {
if (flag & RBD_QOS_WRITE_MASK) {
- return 0;
+ *tokens = 0;
+ return false;
}
- if (flag & RBD_QOS_BPS_MASK) {
- return spec->extents_length();
- }
- return 1;
+ *tokens = (flag & RBD_QOS_BPS_MASK) ? spec->extents_length() : 1;
+ return true;
}
uint64_t operator()(const Flush&) const {
- return 0;
+ *tokens = 0;
+ return true;
}
template <typename T>
uint64_t operator()(const T&) const {
if (flag & RBD_QOS_READ_MASK) {
- return 0;
+ *tokens = 0;
+ return false;
}
- if (flag & RBD_QOS_BPS_MASK) {
- return spec->extents_length();
- }
- return 1;
+ *tokens = (flag & RBD_QOS_BPS_MASK) ? spec->extents_length() : 1;
+ return true;
}
};
}
template <typename I>
-uint64_t ImageDispatchSpec<I>::tokens_requested(uint64_t flag) {
- return boost::apply_visitor(TokenRequestedVisitor{this, flag}, m_request);
+bool ImageDispatchSpec<I>::tokens_requested(uint64_t flag, uint64_t *tokens) {
+ return boost::apply_visitor(TokenRequestedVisitor{this, flag, tokens},
+ m_request);
}
template <typename I>
}
throttle = t.second;
- tokens = item->tokens_requested(flag);
-
- if (throttle->get<ImageRequestWQ<I>, ImageDispatchSpec<I>,
+ if (item->tokens_requested(flag, &tokens) &&
+ throttle->get<ImageRequestWQ<I>, ImageDispatchSpec<I>,
&ImageRequestWQ<I>::handle_throttle_ready>(
tokens, this, item, flag)) {
blocked = true;
MOCK_CONST_METHOD1(was_throttled, bool(uint64_t));
MOCK_CONST_METHOD0(were_all_throttled, bool());
MOCK_CONST_METHOD1(set_throttled, void(uint64_t));
- MOCK_CONST_METHOD1(tokens_requested, uint64_t(uint64_t));
+ MOCK_CONST_METHOD2(tokens_requested, bool(uint64_t, uint64_t *));
ImageDispatchSpec() {
s_instance = this;
EXPECT_CALL(mock_image_request, was_throttled(_)).Times(6).WillRepeatedly(Return(value));
}
- void expect_tokens_requested(MockImageDispatchSpec &mock_image_request, uint64_t value) {
- EXPECT_CALL(mock_image_request, tokens_requested(_)).WillOnce(Return(value));
+ void expect_tokens_requested(MockImageDispatchSpec &mock_image_request,
+ uint64_t tokens, bool r) {
+ EXPECT_CALL(mock_image_request, tokens_requested(_, _))
+ .WillOnce(WithArg<1>(Invoke([tokens, r](uint64_t *t) {
+ *t = tokens;
+ return r;
+ })));
}
void expect_all_throttled(MockImageDispatchSpec &mock_image_request, bool value) {
mock_image_request_wq.apply_qos_limit(RBD_QOS_BPS_THROTTLE, 1, 0);
expect_front(mock_image_request_wq, &mock_queued_image_request);
- expect_tokens_requested(mock_queued_image_request, 2);
+ expect_tokens_requested(mock_queued_image_request, 2, true);
expect_dequeue(mock_image_request_wq, &mock_queued_image_request);
expect_all_throttled(mock_queued_image_request, true);
expect_requeue(mock_image_request_wq);
mock_image_request_wq.apply_qos_limit(RBD_QOS_BPS_THROTTLE, 1, 1);
expect_front(mock_image_request_wq, &mock_queued_image_request);
- expect_tokens_requested(mock_queued_image_request, 2);
+ expect_tokens_requested(mock_queued_image_request, 2, true);
expect_dequeue(mock_image_request_wq, &mock_queued_image_request);
expect_all_throttled(mock_queued_image_request, true);
expect_requeue(mock_image_request_wq);