Skip to content

Commit

Permalink
Fix axmolengine#2060, make http request/respose reference counter thr…
Browse files Browse the repository at this point in the history
…ead-safe (axmolengine#2064)
  • Loading branch information
halx99 authored Jul 31, 2024
1 parent 687874c commit 377f340
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 16 deletions.
33 changes: 28 additions & 5 deletions core/base/Object.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,15 +163,38 @@ typedef void (Object::*SEL_CallFuncO)(Object*);
typedef void (Object::*SEL_MenuHandler)(Object*);
typedef void (Object::*SEL_SCHEDULE)(float);

#define AX_CALLFUNC_SELECTOR(_SELECTOR) static_cast<ax::SEL_CallFunc>(&_SELECTOR)
#define AX_CALLFUNCN_SELECTOR(_SELECTOR) static_cast<ax::SEL_CallFuncN>(&_SELECTOR)
#define AX_CALLFUNC_SELECTOR(_SELECTOR) static_cast<ax::SEL_CallFunc>(&_SELECTOR)
#define AX_CALLFUNCN_SELECTOR(_SELECTOR) static_cast<ax::SEL_CallFuncN>(&_SELECTOR)
#define AX_CALLFUNCND_SELECTOR(_SELECTOR) static_cast<ax::SEL_CallFuncND>(&_SELECTOR)
#define AX_CALLFUNCO_SELECTOR(_SELECTOR) static_cast<ax::SEL_CallFuncO>(&_SELECTOR)
#define AX_MENU_SELECTOR(_SELECTOR) static_cast<ax::SEL_MenuHandler>(&_SELECTOR)
#define AX_SCHEDULE_SELECTOR(_SELECTOR) static_cast<ax::SEL_SCHEDULE>(&_SELECTOR)
#define AX_CALLFUNCO_SELECTOR(_SELECTOR) static_cast<ax::SEL_CallFuncO>(&_SELECTOR)
#define AX_MENU_SELECTOR(_SELECTOR) static_cast<ax::SEL_MenuHandler>(&_SELECTOR)
#define AX_SCHEDULE_SELECTOR(_SELECTOR) static_cast<ax::SEL_SCHEDULE>(&_SELECTOR)

NS_AX_END
// end of base group
/** @} */

namespace axstd
{
template <typename _Ty, typename Enable = void>
struct is_ref_counted : std::false_type
{};

template <typename... _Types>
struct is_ref_counted_helper
{};

template <typename _Ty>
struct is_ref_counted<_Ty,
std::conditional_t<false,
is_ref_counted_helper<decltype(std::declval<_Ty>().retain()),
decltype(std::declval<_Ty>().release()),
decltype(std::declval<_Ty>().getReferenceCount())>,
void>> : public std::true_type
{};

template <typename _Ty>
inline constexpr bool is_ref_counted_v = is_ref_counted<std::remove_pointer_t<_Ty>>::value;
} // namespace axstd

#endif // __BASE_CCREF_H__
11 changes: 6 additions & 5 deletions core/base/RefPtr.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Copyright (c) 2014 PlayFirst Inc.
Copyright (c) 2014-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
Copyright (c) 2019-present Axmol Engine contributors (see AUTHORS.md).
https://axmol.dev/
Expand Down Expand Up @@ -45,7 +46,7 @@ NS_AX_BEGIN
{ \
if (ptr) \
{ \
const_cast<Object*>(static_cast<const Object*>(ptr))->retain(); \
(ptr)->retain(); \
} \
\
} while (0);
Expand All @@ -56,7 +57,7 @@ NS_AX_BEGIN
{ \
if (ptr) \
{ \
const_cast<Object*>(static_cast<const Object*>(ptr))->release(); \
(ptr)->release(); \
} \
\
} while (0);
Expand All @@ -67,7 +68,7 @@ NS_AX_BEGIN
{ \
if (ptr) \
{ \
const_cast<Object*>(static_cast<const Object*>(ptr))->release(); \
(ptr)->release(); \
ptr = nullptr; \
} \
\
Expand Down Expand Up @@ -118,9 +119,9 @@ class RefPtr
{
if (other._ptr != _ptr)
{
AX_REF_PTR_SAFE_RETAIN(other._ptr);
AX_REF_PTR_SAFE_RELEASE(_ptr);
_ptr = other._ptr;
AX_REF_PTR_SAFE_RETAIN(_ptr);
}

return *this;
Expand Down Expand Up @@ -250,7 +251,7 @@ class RefPtr
T* _ptr;

// NOTE: We can ensure T is derived from ax::Object at compile time here.
static_assert(std::is_base_of<Object, typename std::remove_const<T>::type>::value, "T must be derived from Object");
static_assert(axstd::is_ref_counted_v<typename std::remove_const<T>::type>, "T must be derived from Object");
};

template <class T>
Expand Down
9 changes: 5 additions & 4 deletions core/base/Vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ Copyright (c) 2010 ForzeField Studios S.L. http://forzefield.com
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2013-2017 Chukong Technologies
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
Copyright (c) 2019-present Axmol Engine contributors (see AUTHORS.md).
https://axmol.dev/
Expand Down Expand Up @@ -110,7 +111,7 @@ class Vector
/** Constructor. */
Vector() : _data()
{
static_assert(std::is_convertible<T, Object*>::value, "Invalid Type for ax::Vector!");
static_assert(axstd::is_ref_counted_v<T>, "Invalid Type for ax::Vector!");
}

/**
Expand All @@ -119,7 +120,7 @@ class Vector
*/
explicit Vector(ssize_t capacity) : _data()
{
static_assert(std::is_convertible<T, Object*>::value, "Invalid Type for ax::Vector!");
static_assert(axstd::is_ref_counted_v<T>, "Invalid Type for ax::Vector!");
AXLOGV("In the default constructor with capacity of Vector.");
reserve(capacity);
}
Expand All @@ -143,7 +144,7 @@ class Vector
/** Copy constructor. */
Vector(const Vector& other)
{
static_assert(std::is_convertible<T, Object*>::value, "Invalid Type for ax::Vector!");
static_assert(axstd::is_ref_counted_v<T>, "Invalid Type for ax::Vector!");
AXLOGV("In the copy constructor!");
_data = other._data;
addRefForAllObjects();
Expand All @@ -152,7 +153,7 @@ class Vector
/** Constructor with std::move semantic. */
Vector(Vector&& other)
{
static_assert(std::is_convertible<T, Object*>::value, "Invalid Type for ax::Vector!");
static_assert(axstd::is_ref_counted_v<T>, "Invalid Type for ax::Vector!");
AXLOGV("In the move constructor of Vector!");
_data = std::move(other._data);
}
Expand Down
22 changes: 21 additions & 1 deletion core/network/HttpRequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,26 @@ class HttpResponse;

typedef std::function<void(HttpClient* client, HttpResponse* response)> ccHttpRequestCallback;

class TSFRefCountedBase
{
public:
TSFRefCountedBase() : _refCount(1) {}
virtual ~TSFRefCountedBase() {}

void retain() { ++_refCount; }

void release()
{
if (--_refCount == 0)
delete this;
}

int getReferenceCount() const { return _refCount; }

protected:
std::atomic_int _refCount;
};

/**
* Defines the object which users must packed for HttpClient::send(HttpRequest*) method.
* Please refer to tests/test-cpp/Classes/ExtensionTest/NetworkTest/HttpClientTest.cpp as a sample
Expand All @@ -60,7 +80,7 @@ typedef std::function<void(HttpClient* client, HttpResponse* response)> ccHttpRe
* @lua NA
*/

class AX_DLL HttpRequest : public Object
class AX_DLL HttpRequest : public TSFRefCountedBase
{
friend class HttpClient;

Expand Down
2 changes: 1 addition & 1 deletion core/network/HttpResponse.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class HttpClient;
* @since v2.0.2.
* @lua NA
*/
class AX_DLL HttpResponse : public ax::Object
class AX_DLL HttpResponse : public TSFRefCountedBase
{
friend class HttpClient;

Expand Down

0 comments on commit 377f340

Please sign in to comment.