Skip to content

Commit d02c7fd

Browse files
authored
Fix universal reference (#2862)
1 parent 4158a17 commit d02c7fd

5 files changed

Lines changed: 22 additions & 56 deletions

File tree

src/brpc/versioned_ref_with_id.h

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ typename std::enable_if<butil::is_void<Ret>::value, Ret>::type ReturnEmpty() {}
102102
template<typename... Args> \
103103
typename std::enable_if<decltype( \
104104
Test<class_type, Args...>(0))::value, return_type>::type \
105-
Call(class_type* obj, Args... args) { \
105+
Call(class_type* obj, Args&&... args) { \
106106
BAIDU_CASSERT((butil::is_result_same< \
107107
return_type, decltype(&T::func_name), T, Args...>::value), \
108108
"Params or return type mismatch"); \
@@ -112,7 +112,7 @@ typename std::enable_if<butil::is_void<Ret>::value, Ret>::type ReturnEmpty() {}
112112
template<typename... Args> \
113113
typename std::enable_if<!decltype( \
114114
Test<class_type, Args...>(0))::value, return_type>::type \
115-
Call(class_type* obj, Args... args) { \
115+
Call(class_type* obj, Args&&... args) { \
116116
return ReturnEmpty<return_type>(); \
117117
} \
118118
}
@@ -128,13 +128,13 @@ typename std::enable_if<butil::is_void<Ret>::value, Ret>::type ReturnEmpty() {}
128128
//
129129
// CRTP
130130
// Derived classes implement 6 functions :
131-
// 1. (required) int OnCreated(Args... args) :
131+
// 1. (required) int OnCreated(Args&&... args) :
132132
// Will be called in Create() to initialize T init when T is created successfully.
133133
// If initialization fails, return non-zero. VersionedRefWithId will be `SetFailed'
134134
// and Create() returns non-zero.
135135
// 2. (required) void BeforeRecycled() :
136136
// Will be called in Dereference() before T is recycled.
137-
// 3. (optional) void OnFailed(Args... args) :
137+
// 3. (optional) void OnFailed(Args&&... args) :
138138
// Will be called in SetFailed() when VersionedRefWithId is set failed successfully.
139139
// 4. (optional) void BeforeAdditionalRefReleased() :
140140
// Will be called in ReleaseAdditionalReference() before additional ref is released.
@@ -212,7 +212,7 @@ class VersionedRefWithId {
212212
// `args' will be passed to OnCreated() directly.
213213
// Returns 0 on success, -1 otherwise.
214214
template<typename ... Args>
215-
static int Create(VRefId* id, Args... args);
215+
static int Create(VRefId* id, Args&&... args);
216216

217217
// Place the VersionedRefWithId associated with identifier `id' into
218218
// unique_ptr `ptr', which will be released automatically when out
@@ -246,10 +246,10 @@ class VersionedRefWithId {
246246
// This function is lock-free.
247247
// Returns -1 when the Socket was already SetFailed(), 0 otherwise.
248248
template<typename... Args>
249-
static int SetFailedById(VRefId id, Args... args);
249+
static int SetFailedById(VRefId id, Args&&... args);
250250

251251
template<typename... Args>
252-
int SetFailed(Args... args);
252+
int SetFailed(Args&&... args);
253253

254254
bool Failed() const {
255255
return VersionOfVRef(_versioned_ref.load(butil::memory_order_relaxed))
@@ -290,7 +290,7 @@ friend void DereferenceVersionedRefWithId<>(T* r);
290290
}
291291

292292
template<typename... Args>
293-
int SetFailedImpl(Args... args);
293+
int SetFailedImpl(Args&&... args);
294294

295295
// Release the reference. If no one is addressing this VersionedRefWithId,
296296
// it will be recycled automatically and T::BeforeRecycled() will be called.
@@ -351,7 +351,7 @@ void DereferenceVersionedRefWithId(T* r) {
351351

352352
template <typename T>
353353
template<typename ... Args>
354-
int VersionedRefWithId<T>::Create(VRefId* id, Args... args) {
354+
int VersionedRefWithId<T>::Create(VRefId* id, Args&&... args) {
355355
resource_id_t slot;
356356
T* const t = butil::get_resource(&slot, Forbidden());
357357
if (t == NULL) {
@@ -458,7 +458,7 @@ void VersionedRefWithId<T>::ReAddress(VersionedRefWithIdUniquePtr<T>* ptr) {
458458

459459
template<typename T>
460460
template<typename... Args>
461-
int VersionedRefWithId<T>::SetFailedById(VRefId id, Args... args) {
461+
int VersionedRefWithId<T>::SetFailedById(VRefId id, Args&&... args) {
462462
VersionedRefWithIdUniquePtr<T> ptr;
463463
if (Address(id, &ptr) != 0) {
464464
return -1;
@@ -468,13 +468,13 @@ int VersionedRefWithId<T>::SetFailedById(VRefId id, Args... args) {
468468

469469
template<typename T>
470470
template<typename... Args>
471-
int VersionedRefWithId<T>::SetFailed(Args... args) {
471+
int VersionedRefWithId<T>::SetFailed(Args&&... args) {
472472
return SetFailedImpl(std::forward<Args>(args)...);
473473
}
474474

475475
template<typename T>
476476
template<typename... Args>
477-
int VersionedRefWithId<T>::SetFailedImpl(Args... args) {
477+
int VersionedRefWithId<T>::SetFailedImpl(Args&&... args) {
478478
const uint32_t id_ver = VersionOfVRefId(_this_id);
479479
uint64_t vref = _versioned_ref.load(butil::memory_order_relaxed);
480480
for (;;) {

src/butil/object_pool.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ template <typename T> inline bool local_pool_free_empty() {
7777
// Get an object typed |T|. The object should be cleared before usage.
7878
// NOTE: If there are no arguments, T must be default-constructible.
7979
template <typename T, typename... Args>
80-
inline T* get_object(Args... args) {
80+
inline T* get_object(Args&&... args) {
8181
return ObjectPool<T>::singleton()->get_object(std::forward<Args>(args)...);
8282
}
8383

src/butil/object_pool_inl.h

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ class BAIDU_CACHELINE_ALIGNMENT ObjectPool {
192192
}
193193

194194
template<typename... Args>
195-
inline T* get(Args... args) {
195+
inline T* get(Args&&... args) {
196196
BAIDU_OBJECT_POOL_GET((std::forward<Args>(args)...));
197197
}
198198

@@ -235,28 +235,11 @@ class BAIDU_CACHELINE_ALIGNMENT ObjectPool {
235235
return true;
236236
}
237237

238-
inline T* get_object() {
238+
template <typename... Args>
239+
inline T* get_object(Args&&... args) {
239240
LocalPool* lp = get_or_new_local_pool();
240241
if (BAIDU_LIKELY(lp != NULL)) {
241-
return lp->get();
242-
}
243-
return NULL;
244-
}
245-
246-
template <typename A1>
247-
inline T* get_object(const A1& arg1) {
248-
LocalPool* lp = get_or_new_local_pool();
249-
if (BAIDU_LIKELY(lp != NULL)) {
250-
return lp->get(arg1);
251-
}
252-
return NULL;
253-
}
254-
255-
template <typename A1, typename A2>
256-
inline T* get_object(const A1& arg1, const A2& arg2) {
257-
LocalPool* lp = get_or_new_local_pool();
258-
if (BAIDU_LIKELY(lp != NULL)) {
259-
return lp->get(arg1, arg2);
242+
return lp->get(std::forward<Args>(args)...);
260243
}
261244
return NULL;
262245
}

src/butil/resource_pool.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ namespace butil {
9494
// The object should be cleared before usage.
9595
// NOTE: If there are no arguments, T must be default-constructible.
9696
template <typename T, typename... Args>
97-
inline T* get_resource(ResourceId<T>* id, Args... args) {
97+
inline T* get_resource(ResourceId<T>* id, Args&&... args) {
9898
return ResourcePool<T>::singleton()->get_resource(id, std::forward<Args>(args)...);
9999
}
100100

src/butil/resource_pool_inl.h

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ class BAIDU_CACHELINE_ALIGNMENT ResourcePool {
216216
}
217217

218218
template<typename... Args>
219-
inline T* get(ResourceId<T>* id, Args... args) {
219+
inline T* get(ResourceId<T>* id, Args&&... args) {
220220
BAIDU_RESOURCE_POOL_GET((std::forward<Args>(args)...));
221221
}
222222

@@ -277,28 +277,11 @@ class BAIDU_CACHELINE_ALIGNMENT ResourcePool {
277277
return NULL;
278278
}
279279

280-
inline T* get_resource(ResourceId<T>* id) {
280+
template<typename... Args>
281+
inline T* get_resource(ResourceId<T>* id, Args&&... args) {
281282
LocalPool* lp = get_or_new_local_pool();
282283
if (__builtin_expect(lp != NULL, 1)) {
283-
return lp->get(id);
284-
}
285-
return NULL;
286-
}
287-
288-
template <typename A1>
289-
inline T* get_resource(ResourceId<T>* id, const A1& arg1) {
290-
LocalPool* lp = get_or_new_local_pool();
291-
if (__builtin_expect(lp != NULL, 1)) {
292-
return lp->get(id, arg1);
293-
}
294-
return NULL;
295-
}
296-
297-
template <typename A1, typename A2>
298-
inline T* get_resource(ResourceId<T>* id, const A1& arg1, const A2& arg2) {
299-
LocalPool* lp = get_or_new_local_pool();
300-
if (__builtin_expect(lp != NULL, 1)) {
301-
return lp->get(id, arg1, arg2);
284+
return lp->get(id, std::forward<Args>(args)...);
302285
}
303286
return NULL;
304287
}

0 commit comments

Comments
 (0)