Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,6 @@ objc_library(
"src/butil/memory/aligned_memory.h",
"src/butil/memory/scoped_policy.h",
"src/butil/memory/scoped_ptr.h",
"src/butil/move.h",
"src/butil/port.h",
"src/butil/posix/eintr_wrapper.h",
"src/butil/scoped_generic.h",
Expand Down
39 changes: 39 additions & 0 deletions docs/en/cpp14_move.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Migrating butil ownership transfers to C++14

The C++03 move emulation in `butil/move.h` has been replaced by native
rvalue references and `std::move` from `<utility>`. The header and
`MOVE_ONLY_TYPE_FOR_CPP_03` macro have been removed.

For an existing butil resource owner, transfer ownership with `std::move`:

```cpp
#include <utility>
#include "butil/memory/scoped_ptr.h"

scoped_ptr<int> source(new int(42));
scoped_ptr<int> destination(std::move(source));
```

Return a local owner directly to allow copy elision or an implicit move.
`Pass()` and `scoped_ptr::PassAs<T>()` have been removed. Replace ownership
transfers with `std::move(owner)`, or return the local owner directly, including
when converting a `scoped_ptr<Derived>` to `scoped_ptr<Base>`.

A discarded `owner.Pass()` used to release the resource through a temporary
owner. Replace such calls with the appropriate explicit cleanup operation
(`reset()`, `clear()`, or `Close()`). Discarding `std::move(owner)` does not
release anything.

These types remain noncopyable. `ScopedGeneric` and `ScopedFILE` retain
their existing support for move construction only. `scoped_ptr`,
`ScopedVector`, and `File` also support move assignment. Custom deleters
and stateful traits retain their existing copying behavior.

Downstream types using the removed macro must declare deleted copy
operations and implement native move operations that transfer ownership
and invalidate the source. Merely defaulting a move constructor for a raw
resource handle does not prevent both objects from releasing that handle.

The exported `File` move constructor and move assignment signatures now
take `File&&`. Rebuild downstream binaries when updating the brpc shared
library; the old C++03-emulation symbols are no longer provided.
2 changes: 2 additions & 0 deletions docs/en/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,8 @@ Same with [here](#compile-brpc-with-cmake)

c++14 is turned on by default to remove dependencies on boost (atomic).

For butil ownership transfers, see [Migrating to C++14 move semantics](cpp14_move.md).

The over-aligned issues in GCC7 is suppressed temporarily now.

Using other versions of gcc may generate warnings, contact us to fix.
Expand Down
6 changes: 3 additions & 3 deletions src/bthread/execution_queue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,14 +344,14 @@ ExecutionQueueBase::scoped_ptr_t ExecutionQueueBase::address(uint64_t id) {
const uint32_t ver1 = _version_of_vref(vref1);
if (ver1 == _version_of_id(id)) {
ret.reset(m);
return ret.Pass();
return ret;
}

const uint64_t vref2 = m->_versioned_ref.fetch_sub(
1, butil::memory_order_release);
const int32_t nref = _ref_of_vref(vref2);
if (nref > 1) {
return ret.Pass();
return ret;
} else if (__builtin_expect(nref == 1, 1)) {
const uint32_t ver2 = _version_of_vref(vref2);
if ((ver2 & 1)) {
Expand Down Expand Up @@ -379,7 +379,7 @@ ExecutionQueueBase::scoped_ptr_t ExecutionQueueBase::address(uint64_t id) {
CHECK(false) << "Over dereferenced id=" << id;
}
}
return ret.Pass();
return ret;
}

int ExecutionQueueBase::create(uint64_t* id, const ExecutionQueueOptions* options,
Expand Down
2 changes: 1 addition & 1 deletion src/bthread/execution_queue_inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ friend class TaskIterator<T>;
Base::scoped_ptr_t ptr = Base::address(id.value);
Base* b = ptr.release();
scoped_ptr_t ret((self_type*)b);
return ret.Pass();
return ret;
}

int execute(typename butil::add_const_reference<T>::type task) {
Expand Down
4 changes: 2 additions & 2 deletions src/butil/containers/scoped_ptr_hash_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class ScopedPtrHashMap {

scoped_ptr<Value> ret(it->second);
it->second = nullptr;
return ret.Pass();
return ret;
}

scoped_ptr<Value> take(const Key& k) {
Expand All @@ -97,7 +97,7 @@ class ScopedPtrHashMap {

scoped_ptr<Value> ret(it->second);
data_.erase(it);
return ret.Pass();
return ret;
}

scoped_ptr<Value> take_and_erase(const Key& k) {
Expand Down
2 changes: 1 addition & 1 deletion src/butil/environment.cc
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ scoped_ptr<char*[]> AlterEnvironment(const char* const* const env,
result[i] = &storage_data[result_indices[i]];
result[result_indices.size()] = 0; // Null terminator.

return result.Pass();
return result;
}

#endif // OS_POSIX
Expand Down
22 changes: 11 additions & 11 deletions src/butil/files/file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,25 +47,25 @@ File::File(Error error_details)
async_(false) {
}

File::File(RValue other)
: file_(other.object->TakePlatformFile()),
error_details_(other.object->error_details()),
created_(other.object->created()),
async_(other.object->async_) {
File::File(File&& other) noexcept
: file_(other.TakePlatformFile()),
error_details_(other.error_details()),
created_(other.created()),
async_(other.async_) {
}

File::~File() {
// Go through the AssertIOAllowed logic.
Close();
}

File& File::operator=(RValue other) {
if (this != other.object) {
File& File::operator=(File&& other) noexcept {
if (this != &other) {
Close();
SetPlatformFile(other.object->TakePlatformFile());
error_details_ = other.object->error_details();
created_ = other.object->created();
async_ = other.object->async_;
SetPlatformFile(other.TakePlatformFile());
error_details_ = other.error_details();
created_ = other.created();
async_ = other.async_;
}
return *this;
}
Expand Down
12 changes: 5 additions & 7 deletions src/butil/files/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#include "butil/base_export.h"
#include "butil/basictypes.h"
#include "butil/files/scoped_file.h"
#include "butil/move.h"
#include "butil/time/time.h"

#if defined(OS_WIN)
Expand Down Expand Up @@ -53,8 +52,6 @@ typedef struct stat64 stat_wrapper_t;
// to the OS is not considered const, even if there is no apparent change to
// member variables.
class BUTIL_EXPORT File {
MOVE_ONLY_TYPE_FOR_CPP_03(File, RValue)

public:
// FLAG_(OPEN|CREATE).* are mutually exclusive. You should specify exactly one
// of the five (possibly combining with other flags) when opening or creating
Expand Down Expand Up @@ -167,13 +164,14 @@ class BUTIL_EXPORT File {
// Creates an object with a specific error_details code.
explicit File(Error error_details);

// Move constructor for C++03 move emulation of this type.
File(RValue other);
File(const File&) = delete;
File& operator=(const File&) = delete;

File(File&& other) noexcept;

~File();

// Move operator= for C++03 move emulation of this type.
File& operator=(RValue other);
File& operator=(File&& other) noexcept;

// Creates or opens the given file.
void Initialize(const FilePath& name, uint32_t flags);
Expand Down
4 changes: 3 additions & 1 deletion src/butil/files/memory_mapped_file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#include "butil/files/memory_mapped_file.h"

#include <utility>

#include "butil/files/file_path.h"
#include "butil/logging.h"

Expand Down Expand Up @@ -36,7 +38,7 @@ bool MemoryMappedFile::Initialize(File file) {
if (IsValid())
return false;

file_ = file.Pass();
file_ = std::move(file);

if (!MapFileToMemory()) {
CloseHandles();
Expand Down
11 changes: 6 additions & 5 deletions src/butil/files/scoped_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ typedef ScopedGeneric<int, internal::ScopedFDCloseTraits> ScopedFD;

//// Automatically closes |FILE*|s.
class ScopedFILE {
MOVE_ONLY_TYPE_FOR_CPP_03(ScopedFILE, RValue);
public:
ScopedFILE() : _fp(nullptr) {}

Expand All @@ -61,10 +60,12 @@ class ScopedFILE {
// destructor, otherwise the behavior is undefined
explicit ScopedFILE(FILE *fp) :_fp(fp) {}

ScopedFILE(RValue rvalue) {
_fp = rvalue.object->_fp;
rvalue.object->_fp = nullptr;
}
ScopedFILE(const ScopedFILE&) = delete;
ScopedFILE& operator=(const ScopedFILE&) = delete;

ScopedFILE(ScopedFILE&& other) noexcept : _fp(other.release()) {}

ScopedFILE& operator=(ScopedFILE&&) = delete;

~ScopedFILE() {
if (_fp != nullptr) {
Expand Down
Loading
Loading