]>
git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/src/net/packet.cc
2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing,
12 * software distributed under the License is distributed on an
13 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 * KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations
19 * Copyright (C) 2014 Cloudius Systems, Ltd.
22 #include <seastar/core/reactor.hh>
23 #include <seastar/net/packet.hh>
32 constexpr size_t packet::internal_data_size
;
33 constexpr size_t packet::default_nr_frags
;
35 void packet::linearize(size_t at_frag
, size_t desired_size
) {
36 _impl
->unuse_internal_data();
38 size_t accum_size
= 0;
39 while (accum_size
< desired_size
) {
40 accum_size
+= _impl
->_frags
[at_frag
+ nr_frags
].size
;
43 std::unique_ptr
<char[]> new_frag
{new char[accum_size
]};
44 auto p
= new_frag
.get();
45 for (size_t i
= 0; i
< nr_frags
; ++i
) {
46 auto& f
= _impl
->_frags
[at_frag
+ i
];
47 p
= std::copy(f
.base
, f
.base
+ f
.size
, p
);
49 // collapse nr_frags into one fragment
50 std::copy(_impl
->_frags
+ at_frag
+ nr_frags
, _impl
->_frags
+ _impl
->_nr_frags
,
51 _impl
->_frags
+ at_frag
+ 1);
52 _impl
->_nr_frags
-= nr_frags
- 1;
53 _impl
->_frags
[at_frag
] = fragment
{new_frag
.get(), accum_size
};
54 if (at_frag
== 0 && desired_size
== len()) {
55 // We can drop the old buffer safely
56 auto x
= std::move(_impl
->_deleter
);
57 _impl
->_deleter
= make_deleter([buf
= std::move(new_frag
)] {});
59 _impl
->_deleter
= make_deleter(std::move(_impl
->_deleter
), [buf
= std::move(new_frag
)] {});
64 packet
packet::free_on_cpu(unsigned cpu
, std::function
<void()> cb
)
66 // make new deleter that runs old deleter on an origin cpu
67 _impl
->_deleter
= make_deleter(deleter(), [d
= std::move(_impl
->_deleter
), cpu
, cb
= std::move(cb
)] () mutable {
68 smp::submit_to(cpu
, [d
= std::move(d
), cb
= std::move(cb
)] () mutable {
69 // deleter needs to be moved from lambda capture to be destroyed here
70 // otherwise deleter destructor will be called on a cpu that called smp::submit_to()
71 // when work_item is destroyed.
72 deleter
xxx(std::move(d
));
77 return packet(impl::copy(_impl
.get()));
80 std::ostream
& operator<<(std::ostream
& os
, const packet
& p
) {
83 for (auto&& frag
: p
.fragments()) {
88 if (std::all_of(frag
.base
, frag
.base
+ frag
.size
, [] (int c
) { return c
>= 9 && c
<= 0x7f; })) {
90 for (auto p
= frag
.base
; p
!= frag
.base
+ frag
.size
; ++p
) {
94 } else if (c
== '\r') {
96 } else if (c
== '\n') {
98 } else if (c
== '\t') {
102 os
<< "\\x" << (b
/ 16) << (b
% 16);
109 for (auto p
= frag
.base
; p
!= frag
.base
+ frag
.size
; ++p
) {
115 os
<< format("{:02x}", unsigned(b
));