From c6f352312b9808009966c9c640941003ae9fd90d Mon Sep 17 00:00:00 2001 From: Bright Chen Date: Fri, 3 Jan 2025 21:22:58 +0800 Subject: [PATCH] Fix universal reference --- src/brpc/versioned_ref_with_id.h | 24 ++++++++++++------------ src/butil/object_pool.h | 2 +- src/butil/object_pool_inl.h | 25 ++++--------------------- src/butil/resource_pool.h | 2 +- src/butil/resource_pool_inl.h | 25 ++++--------------------- 5 files changed, 22 insertions(+), 56 deletions(-) diff --git a/src/brpc/versioned_ref_with_id.h b/src/brpc/versioned_ref_with_id.h index c78f019b9d..23ea0e0ad1 100644 --- a/src/brpc/versioned_ref_with_id.h +++ b/src/brpc/versioned_ref_with_id.h @@ -102,7 +102,7 @@ typename std::enable_if::value, Ret>::type ReturnEmpty() {} template \ typename std::enable_if(0))::value, return_type>::type \ - Call(class_type* obj, Args... args) { \ + Call(class_type* obj, Args&&... args) { \ BAIDU_CASSERT((butil::is_result_same< \ return_type, decltype(&T::func_name), T, Args...>::value), \ "Params or return type mismatch"); \ @@ -112,7 +112,7 @@ typename std::enable_if::value, Ret>::type ReturnEmpty() {} template \ typename std::enable_if(0))::value, return_type>::type \ - Call(class_type* obj, Args... args) { \ + Call(class_type* obj, Args&&... args) { \ return ReturnEmpty(); \ } \ } @@ -128,13 +128,13 @@ typename std::enable_if::value, Ret>::type ReturnEmpty() {} // // CRTP // Derived classes implement 6 functions : -// 1. (required) int OnCreated(Args... args) : +// 1. (required) int OnCreated(Args&&... args) : // Will be called in Create() to initialize T init when T is created successfully. // If initialization fails, return non-zero. VersionedRefWithId will be `SetFailed' // and Create() returns non-zero. // 2. (required) void BeforeRecycled() : // Will be called in Dereference() before T is recycled. -// 3. (optional) void OnFailed(Args... args) : +// 3. (optional) void OnFailed(Args&&... args) : // Will be called in SetFailed() when VersionedRefWithId is set failed successfully. // 4. (optional) void BeforeAdditionalRefReleased() : // Will be called in ReleaseAdditionalReference() before additional ref is released. @@ -212,7 +212,7 @@ class VersionedRefWithId { // `args' will be passed to OnCreated() directly. // Returns 0 on success, -1 otherwise. template - static int Create(VRefId* id, Args... args); + static int Create(VRefId* id, Args&&... args); // Place the VersionedRefWithId associated with identifier `id' into // unique_ptr `ptr', which will be released automatically when out @@ -246,10 +246,10 @@ class VersionedRefWithId { // This function is lock-free. // Returns -1 when the Socket was already SetFailed(), 0 otherwise. template - static int SetFailedById(VRefId id, Args... args); + static int SetFailedById(VRefId id, Args&&... args); template - int SetFailed(Args... args); + int SetFailed(Args&&... args); bool Failed() const { return VersionOfVRef(_versioned_ref.load(butil::memory_order_relaxed)) @@ -290,7 +290,7 @@ friend void DereferenceVersionedRefWithId<>(T* r); } template - int SetFailedImpl(Args... args); + int SetFailedImpl(Args&&... args); // Release the reference. If no one is addressing this VersionedRefWithId, // it will be recycled automatically and T::BeforeRecycled() will be called. @@ -351,7 +351,7 @@ void DereferenceVersionedRefWithId(T* r) { template template -int VersionedRefWithId::Create(VRefId* id, Args... args) { +int VersionedRefWithId::Create(VRefId* id, Args&&... args) { resource_id_t slot; T* const t = butil::get_resource(&slot, Forbidden()); if (t == NULL) { @@ -458,7 +458,7 @@ void VersionedRefWithId::ReAddress(VersionedRefWithIdUniquePtr* ptr) { template template -int VersionedRefWithId::SetFailedById(VRefId id, Args... args) { +int VersionedRefWithId::SetFailedById(VRefId id, Args&&... args) { VersionedRefWithIdUniquePtr ptr; if (Address(id, &ptr) != 0) { return -1; @@ -468,13 +468,13 @@ int VersionedRefWithId::SetFailedById(VRefId id, Args... args) { template template -int VersionedRefWithId::SetFailed(Args... args) { +int VersionedRefWithId::SetFailed(Args&&... args) { return SetFailedImpl(std::forward(args)...); } template template -int VersionedRefWithId::SetFailedImpl(Args... args) { +int VersionedRefWithId::SetFailedImpl(Args&&... args) { const uint32_t id_ver = VersionOfVRefId(_this_id); uint64_t vref = _versioned_ref.load(butil::memory_order_relaxed); for (;;) { diff --git a/src/butil/object_pool.h b/src/butil/object_pool.h index 5bb312b9e2..aa265dfae8 100644 --- a/src/butil/object_pool.h +++ b/src/butil/object_pool.h @@ -77,7 +77,7 @@ template inline bool local_pool_free_empty() { // Get an object typed |T|. The object should be cleared before usage. // NOTE: If there are no arguments, T must be default-constructible. template -inline T* get_object(Args... args) { +inline T* get_object(Args&&... args) { return ObjectPool::singleton()->get_object(std::forward(args)...); } diff --git a/src/butil/object_pool_inl.h b/src/butil/object_pool_inl.h index ab8d88d199..f4853262fe 100644 --- a/src/butil/object_pool_inl.h +++ b/src/butil/object_pool_inl.h @@ -192,7 +192,7 @@ class BAIDU_CACHELINE_ALIGNMENT ObjectPool { } template - inline T* get(Args... args) { + inline T* get(Args&&... args) { BAIDU_OBJECT_POOL_GET((std::forward(args)...)); } @@ -235,28 +235,11 @@ class BAIDU_CACHELINE_ALIGNMENT ObjectPool { return true; } - inline T* get_object() { + template + inline T* get_object(Args&&... args) { LocalPool* lp = get_or_new_local_pool(); if (BAIDU_LIKELY(lp != NULL)) { - return lp->get(); - } - return NULL; - } - - template - inline T* get_object(const A1& arg1) { - LocalPool* lp = get_or_new_local_pool(); - if (BAIDU_LIKELY(lp != NULL)) { - return lp->get(arg1); - } - return NULL; - } - - template - inline T* get_object(const A1& arg1, const A2& arg2) { - LocalPool* lp = get_or_new_local_pool(); - if (BAIDU_LIKELY(lp != NULL)) { - return lp->get(arg1, arg2); + return lp->get(std::forward(args)...); } return NULL; } diff --git a/src/butil/resource_pool.h b/src/butil/resource_pool.h index 84da80525b..f5667938f4 100644 --- a/src/butil/resource_pool.h +++ b/src/butil/resource_pool.h @@ -94,7 +94,7 @@ namespace butil { // The object should be cleared before usage. // NOTE: If there are no arguments, T must be default-constructible. template -inline T* get_resource(ResourceId* id, Args... args) { +inline T* get_resource(ResourceId* id, Args&&... args) { return ResourcePool::singleton()->get_resource(id, std::forward(args)...); } diff --git a/src/butil/resource_pool_inl.h b/src/butil/resource_pool_inl.h index 115bceda5d..4803b2f743 100644 --- a/src/butil/resource_pool_inl.h +++ b/src/butil/resource_pool_inl.h @@ -216,7 +216,7 @@ class BAIDU_CACHELINE_ALIGNMENT ResourcePool { } template - inline T* get(ResourceId* id, Args... args) { + inline T* get(ResourceId* id, Args&&... args) { BAIDU_RESOURCE_POOL_GET((std::forward(args)...)); } @@ -277,28 +277,11 @@ class BAIDU_CACHELINE_ALIGNMENT ResourcePool { return NULL; } - inline T* get_resource(ResourceId* id) { + template + inline T* get_resource(ResourceId* id, Args&&... args) { LocalPool* lp = get_or_new_local_pool(); if (__builtin_expect(lp != NULL, 1)) { - return lp->get(id); - } - return NULL; - } - - template - inline T* get_resource(ResourceId* id, const A1& arg1) { - LocalPool* lp = get_or_new_local_pool(); - if (__builtin_expect(lp != NULL, 1)) { - return lp->get(id, arg1); - } - return NULL; - } - - template - inline T* get_resource(ResourceId* id, const A1& arg1, const A2& arg2) { - LocalPool* lp = get_or_new_local_pool(); - if (__builtin_expect(lp != NULL, 1)) { - return lp->get(id, arg1, arg2); + return lp->get(id, std::forward(args)...); } return NULL; }