IPC: QNativeIpcKey: enable the slow path

I had designed this to be fast for the common, new case of using
QNativeIpcKey objects with a key, a type and maybe in the future we'd
need a flag or two. Turns out that the very first thing I'll need is a
QString, so enable this code path.

This isn't currently exercised because it's not possible to enter it,
yet. It'll come in the next commit.

Change-Id: Idd5e1bb52be047d7b4fffffd17506af2f2de3060
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
bb10
Thiago Macieira 2023-03-27 17:37:32 -06:00
parent d31a046956
commit 5b6f59d6e7
3 changed files with 67 additions and 18 deletions

View File

@ -343,7 +343,6 @@ QNativeIpcKey::Type QNativeIpcKey::defaultTypeForOs_internal() noexcept
}
#endif
/*!
\fn QNativeIpcKey::QNativeIpcKey(Type type) noexcept
\fn QNativeIpcKey::QNativeIpcKey(const QString &key, Type type)
@ -360,19 +359,35 @@ QNativeIpcKey::Type QNativeIpcKey::defaultTypeForOs_internal() noexcept
Copies or moves the content of \a other.
*/
void QNativeIpcKey::copy_internal(const QNativeIpcKey &)
void QNativeIpcKey::copy_internal(const QNativeIpcKey &other)
{
Q_UNREACHABLE();
auto copy = new QNativeIpcKeyPrivate(*other.d_func());
d = quintptr(copy) & 1;
}
void QNativeIpcKey::move_internal(QNativeIpcKey &&) noexcept
{
Q_UNREACHABLE();
// inline code already moved properly, nothing for us to do here
}
QNativeIpcKey &QNativeIpcKey::assign_internal(const QNativeIpcKey &)
QNativeIpcKey &QNativeIpcKey::assign_internal(const QNativeIpcKey &other)
{
Q_UNREACHABLE_RETURN(*this);
QNativeIpcKeyPrivate *us = (d & 1) ? d_func() : nullptr;
const QNativeIpcKeyPrivate *them = (other.d & 1) ? other.d_func() : nullptr;
if (us && !them) {
// don't need the extra info, reset to skinny object
typeAndFlags = {};
typeAndFlags.type = us->type;
delete us;
} else {
// do need the extra info, so create if necessary
if (us)
*us = *them;
else
us = new QNativeIpcKeyPrivate(*them);
d = quintptr(us) | 1;
}
return *this;
}
/*!
@ -382,8 +397,8 @@ QNativeIpcKey &QNativeIpcKey::assign_internal(const QNativeIpcKey &)
*/
void QNativeIpcKey::destroy_internal() noexcept
{
Q_ASSERT(isSlowPath());
Q_UNREACHABLE();
Q_D(QNativeIpcKey);
delete d;
}
/*!
@ -424,8 +439,8 @@ void QNativeIpcKey::destroy_internal() noexcept
*/
QNativeIpcKey::Type QNativeIpcKey::type_internal() const noexcept
{
Q_ASSERT(isSlowPath());
Q_UNREACHABLE_RETURN({});
Q_D(const QNativeIpcKey);
return d->type;
}
/*!
@ -435,9 +450,10 @@ QNativeIpcKey::Type QNativeIpcKey::type_internal() const noexcept
\sa type(), setNativeKey()
*/
void QNativeIpcKey::setType_internal(Type)
void QNativeIpcKey::setType_internal(Type type)
{
Q_UNREACHABLE();
Q_D(QNativeIpcKey);
d->type = type;
}
/*!
@ -455,6 +471,9 @@ void QNativeIpcKey::setType_internal(Type)
\sa nativeKey(), setType()
*/
void QNativeIpcKey::setNativeKey_internal(const QString &)
{
}
/*!
\fn bool QNativeIpcKey::operator==(const QNativeIpcKey &lhs, const QNativeIpcKey &rhs) noexcept
@ -462,9 +481,9 @@ void QNativeIpcKey::setType_internal(Type)
Returns true if the \a lhs and \a rhs objects hold the same (or different) contents.
*/
int QNativeIpcKey::compare_internal(const QNativeIpcKey &, const QNativeIpcKey &) noexcept
int QNativeIpcKey::compare_internal(const QNativeIpcKey &lhs, const QNativeIpcKey &rhs) noexcept
{
Q_UNREACHABLE_RETURN(0);
return *lhs.d_func() == *rhs.d_func() ? 0 : 1;
}
/*!
@ -479,8 +498,7 @@ int QNativeIpcKey::compare_internal(const QNativeIpcKey &, const QNativeIpcKey &
*/
QString QNativeIpcKey::toString() const
{
Q_ASSERT(!isSlowPath());
QString prefix = typeToString(typeAndFlags.type);
QString prefix = typeToString(type());
if (prefix.isEmpty()) {
Q_ASSERT(prefix.isNull());
return prefix;

View File

@ -71,10 +71,10 @@ public:
QNativeIpcKey &operator=(const QNativeIpcKey &other)
{
key = other.key;
if (isSlowPath() || other.isSlowPath())
return assign_internal(other);
d = other.d;
key = other.key;
return *this;
}
@ -112,7 +112,11 @@ public:
QString nativeKey() const noexcept
{ return key; }
void setNativeKey(const QString &newKey)
{ key = newKey; }
{
key = newKey;
if (isSlowPath())
setNativeKey_internal(newKey);
}
Q_CORE_EXPORT QString toString() const;
Q_CORE_EXPORT static QNativeIpcKey fromString(const QString &string);
@ -144,6 +148,9 @@ private:
QString key;
friend class QNativeIpcKeyPrivate;
QNativeIpcKeyPrivate *d_func();
const QNativeIpcKeyPrivate *d_func() const;
constexpr bool isSlowPath() const noexcept
{ return Q_UNLIKELY(typeAndFlags.isExtended); }
@ -168,6 +175,7 @@ private:
Q_CORE_EXPORT void destroy_internal() noexcept;
Q_DECL_PURE_FUNCTION Q_CORE_EXPORT Type type_internal() const noexcept;
Q_CORE_EXPORT void setType_internal(Type);
Q_CORE_EXPORT void setNativeKey_internal(const QString &);
Q_DECL_PURE_FUNCTION Q_CORE_EXPORT static int
compare_internal(const QNativeIpcKey &lhs, const QNativeIpcKey &rhs) noexcept;

View File

@ -28,6 +28,29 @@
QT_BEGIN_NAMESPACE
class QNativeIpcKeyPrivate
{
public:
QNativeIpcKey::Type type = {};
friend bool operator==(const QNativeIpcKeyPrivate &lhs, const QNativeIpcKeyPrivate &rhs)
{
return lhs.type == rhs.type;
}
};
inline QNativeIpcKeyPrivate *QNativeIpcKey::d_func()
{
Q_ASSERT(d & 1); // Q_ASSERT(isSlowPath) but without the unlikely
return reinterpret_cast<QNativeIpcKeyPrivate *>(d & ~1);
}
inline const QNativeIpcKeyPrivate *QNativeIpcKey::d_func() const
{
Q_ASSERT(d & 1); // Q_ASSERT(isSlowPath) but without the unlikely
return reinterpret_cast<QNativeIpcKeyPrivate *>(d & ~1);
}
namespace QtIpcCommon {
enum class IpcType {
SharedMemory,