QtBase  v6.3.1
qcoreevent.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2020 The Qt Company Ltd.
4 ** Copyright (C) 2016 Intel Corporation.
5 ** Contact: https://www.qt.io/licensing/
6 **
7 ** This file is part of the QtCore module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see https://www.qt.io/terms-conditions. For further
16 ** information use the contact form at https://www.qt.io/contact-us.
17 **
18 ** GNU Lesser General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU Lesser
20 ** General Public License version 3 as published by the Free Software
21 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
22 ** packaging of this file. Please review the following information to
23 ** ensure the GNU Lesser General Public License version 3 requirements
24 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25 **
26 ** GNU General Public License Usage
27 ** Alternatively, this file may be used under the terms of the GNU
28 ** General Public License version 2.0 or (at your option) the GNU General
29 ** Public license version 3 or any later version approved by the KDE Free
30 ** Qt Foundation. The licenses are as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32 ** included in the packaging of this file. Please review the following
33 ** information to ensure the GNU General Public License requirements will
34 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35 ** https://www.gnu.org/licenses/gpl-3.0.html.
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40 
41 #include "qcoreevent.h"
42 #include "qcoreapplication.h"
43 #include "qcoreapplication_p.h"
44 
45 #include "qbasicatomic.h"
46 
47 #include <qtcore_tracepoints_p.h>
48 
49 #include <limits>
50 
52 
299  : t(type), m_reserved(0),
300  m_inputEvent(false), m_pointerEvent(false), m_singlePointEvent(false)
301 {
302  Q_TRACE(QEvent_ctor, this, t);
303 }
304 
352 {
353  if (m_posted && QCoreApplication::instance())
355 }
356 
362 { return new QEvent(*this); }
363 
445 namespace {
446 template <size_t N>
447 struct QBasicAtomicBitField {
448  enum {
449  BitsPerInt = std::numeric_limits<uint>::digits,
450  NumInts = (N + BitsPerInt - 1) / BitsPerInt,
451  NumBits = N
452  };
453 
454  // This atomic int points to the next (possibly) free ID saving
455  // the otherwise necessary scan through 'data':
458 
459  constexpr QBasicAtomicBitField() = default;
460 
461  bool allocateSpecific(int which) noexcept
462  {
463  QBasicAtomicInteger<uint> &entry = data[which / BitsPerInt];
464  const uint old = entry.loadRelaxed();
465  const uint bit = 1U << (which % BitsPerInt);
466  return !(old & bit) // wasn't taken
467  && entry.testAndSetRelaxed(old, old | bit); // still wasn't taken
468 
469  // don't update 'next' here - it's unlikely that it will need
470  // to be updated, in the general case, and having 'next'
471  // trailing a bit is not a problem, as it is just a starting
472  // hint for allocateNext(), which, when wrong, will just
473  // result in a few more rounds through the allocateNext()
474  // loop.
475  }
476 
477  int allocateNext() noexcept
478  {
479  // Unroll loop to iterate over ints, then bits? Would save
480  // potentially a lot of cmpxchgs, because we can scan the
481  // whole int before having to load it again.
482 
483  // Then again, this should never execute many iterations, so
484  // leave like this for now:
485  for (uint i = next.loadRelaxed(); i < NumBits; ++i) {
486  if (allocateSpecific(i)) {
487  // remember next (possibly) free id:
488  const uint oldNext = next.loadRelaxed();
489  next.testAndSetRelaxed(oldNext, qMax(i + 1, oldNext));
490  return i;
491  }
492  }
493  return -1;
494  }
495 };
496 
497 } // unnamed namespace
498 
499 typedef QBasicAtomicBitField<QEvent::MaxUser - QEvent::User + 1> UserEventTypeRegistry;
500 
501 static UserEventTypeRegistry userEventTypeRegistry {};
502 
503 static inline int registerEventTypeZeroBased(int id) noexcept
504 {
505  // if the type hint hasn't been registered yet, take it:
506  if (id < UserEventTypeRegistry::NumBits && id >= 0 && userEventTypeRegistry.allocateSpecific(id))
507  return id;
508 
509  // otherwise, ignore hint:
510  return userEventTypeRegistry.allocateNext();
511 }
512 
526 int QEvent::registerEventType(int hint) noexcept
527 {
528  const int result = registerEventTypeZeroBased(QEvent::MaxUser - hint);
529  return result < 0 ? -1 : QEvent::MaxUser - result ;
530 }
531 
558  : QEvent(Timer), id(timerId)
559 {}
560 
565 {
566 }
567 
605  : QEvent(type), c(child)
606 {}
607 
612 {
613 }
614 
661  : QEvent(QEvent::DynamicPropertyChange), n(name)
662 {
663 }
664 
669 {
670 }
671 
685  : QEvent(QEvent::DeferredDelete)
686  , level(0)
687 { }
688 
693 { }
694 
704 
705 #include "moc_qcoreevent.cpp"
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
T loadRelaxed() const noexcept
Definition: qbasicatomic.h:90
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:85
QChildEvent(Type type, QObject *child)
Definition: qcoreevent.cpp:604
static QCoreApplication * instance()
static void removePostedEvent(QEvent *)
QDynamicPropertyChangeEvent(const QByteArray &name)
Definition: qcoreevent.cpp:660
The QEvent class is the base class of all event classes. Event objects contain event parameters.
Definition: qcoreevent.h:58
static int registerEventType(int hint=-1) noexcept
Definition: qcoreevent.cpp:526
@ MaxUser
Definition: qcoreevent.h:301
QEvent(Type type)
Definition: qcoreevent.cpp:298
virtual ~QEvent()
Definition: qcoreevent.cpp:351
virtual QEvent * clone() const
Definition: qcoreevent.cpp:361
The QObject class is the base class of all Qt objects.
Definition: qobject.h:125
QTimerEvent(int timerId)
Definition: qcoreevent.cpp:557
short next
Definition: keywords.cpp:454
QBasicAtomicBitField< QEvent::MaxUser - QEvent::User+1 > UserEventTypeRegistry
Definition: qcoreevent.cpp:499
unsigned int uint
Definition: qglobal.h:334
GLenum GLuint id
[6]
Definition: qopengl.h:270
GLenum type
Definition: qopengl.h:270
GLenum GLuint GLint level
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint name
GLfloat n
const GLubyte * c
Definition: qopenglext.h:12701
GLuint entry
Definition: qopenglext.h:11002
GLdouble GLdouble t
[9]
Definition: qopenglext.h:243
GLuint64EXT * result
[6]
Definition: qopenglext.h:10932
#define Q_TRACE(x,...)
Definition: qtrace_p.h:136
QLayoutItem * child
[0]
Definition: moc.h:48