~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/corelib/kernel/qsocketnotifier.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the core module of the Qt Toolkit.
 
6
**
 
7
** This file may be distributed under the terms of the Q Public License
 
8
** as defined by Trolltech AS of Norway and appearing in the file
 
9
** LICENSE.QPL included in the packaging of this file.
 
10
**
 
11
** This file may be distributed and/or modified under the terms of the
 
12
** GNU General Public License version 2 as published by the Free Software
 
13
** Foundation and appearing in the file LICENSE.GPL included in the
 
14
** packaging of this file.
 
15
**
 
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
 
17
**   information about Qt Commercial License Agreements.
 
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
 
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#include "qsocketnotifier.h"
 
30
 
 
31
#include "qplatformdefs.h"
 
32
 
 
33
#include "qabstracteventdispatcher.h"
 
34
#include "qcoreapplication.h"
 
35
 
 
36
 
 
37
/*!
 
38
    \class QSocketNotifier
 
39
    \brief The QSocketNotifier class provides support for monitoring
 
40
    activity on a file descriptor.
 
41
 
 
42
    \ingroup io
 
43
 
 
44
    The QSocketNotifier makes it possible to integrate Qt's event
 
45
    loop with other event loops based on file descriptors. For
 
46
    example, the QtCorba Solution uses it to process CORBA events.
 
47
    File descriptor action is detected in Qt's main event loop
 
48
    (QCoreApplication::exec()).
 
49
 
 
50
    Once you have opened a device using a low-level (usually
 
51
    platform-specific) API, you can create a socket notifier to
 
52
    monitor the file descriptor. You can then connect the activated()
 
53
    signal to the slot you want to be called whenever an event
 
54
    occurs.
 
55
 
 
56
    Although the class is called QSocketNotifier, it is normally used
 
57
    for other types of devices than sockets. QTcpSocket and
 
58
    QUdpSocket provide notification through signals, so there is
 
59
    normally no need to use a QSocketNotifier on them.
 
60
 
 
61
    \target write notifiers
 
62
 
 
63
    There are three types of socket notifiers: read, write, and
 
64
    exception. You must specify one of these in the constructor.
 
65
 
 
66
    The type specifies when the activated() signal is to be emitted:
 
67
    \list 1
 
68
    \o QSocketNotifier::Read - There is data to be read.
 
69
    \o QSocketNotifier::Write - Data can be written.
 
70
    \o QSocketNotifier::Exception - An exception has occurred.
 
71
       We recommend against using this.
 
72
    \endlist
 
73
 
 
74
    If you need to monitor both reads and writes for the same file
 
75
    descriptor, you must create two socket notifiers.
 
76
 
 
77
    \sa QFile, QProcess, QTcpSocket, QUdpSocket
 
78
*/
 
79
 
 
80
/*!
 
81
    \enum QSocketNotifier::Type
 
82
 
 
83
    The socket notifier can be used to inform the application of the
 
84
    following types of event:
 
85
 
 
86
    \value Read       There is incoming data.
 
87
    \value Write      Data can be written.
 
88
    \value Exception  An exception has occurred.
 
89
*/
 
90
 
 
91
/*!
 
92
    Constructs a socket notifier with the given \a parent. It enables
 
93
    the \a socket, and watches for events of the given \a type.
 
94
 
 
95
    It is generally advisable to explicitly enable or disable the
 
96
    socket notifier, especially for write notifiers.
 
97
 
 
98
    \sa setEnabled(), isEnabled()
 
99
*/
 
100
 
 
101
QSocketNotifier::QSocketNotifier(int socket, Type type, QObject *parent)
 
102
    : QObject(parent)
 
103
{
 
104
    if (socket < 0)
 
105
        qWarning("QSocketNotifier: Invalid socket specified");
 
106
#if defined(Q_OS_UNIX)
 
107
    if (socket >= FD_SETSIZE)
 
108
        qWarning("QSocketNotifier: Socket descriptor too large for select()");
 
109
#endif
 
110
    sockfd = socket;
 
111
    sntype = type;
 
112
    snenabled = true;
 
113
 
 
114
    QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(thread());
 
115
    if (!eventDispatcher) {
 
116
        qWarning("QSocketNotifier can only be used with threads started with QThread");
 
117
    } else {
 
118
        eventDispatcher->registerSocketNotifier(this);
 
119
    }
 
120
}
 
121
 
 
122
#ifdef QT3_SUPPORT
 
123
/*!
 
124
  \obsolete
 
125
 
 
126
    Constructs a socket notifier called \a name, with the given
 
127
    \a parent. It enables the \a socket, and watches for events of the
 
128
    given \a type.
 
129
 
 
130
    It is generally advisable to explicitly enable or disable the
 
131
    socket notifier, especially for write notifiers.
 
132
 
 
133
    \sa setEnabled(), isEnabled()
 
134
*/
 
135
 
 
136
QSocketNotifier::QSocketNotifier(int socket, Type type, QObject *parent,
 
137
                                  const char *name)
 
138
    : QObject(parent)
 
139
{
 
140
    setObjectName(QString::fromAscii(name));
 
141
    if (socket < 0)
 
142
        qWarning("QSocketNotifier: Invalid socket specified");
 
143
#if defined(Q_OS_UNIX)
 
144
    if (socket >= FD_SETSIZE)
 
145
        qWarning("QSocketNotifier: Socket descriptor too large for select()");
 
146
#endif
 
147
    sockfd = socket;
 
148
    sntype = type;
 
149
    snenabled = true;
 
150
 
 
151
    QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(thread());
 
152
    if (!eventDispatcher) {
 
153
        qWarning("QSocketNotifier can only be used with threads started with QThread");
 
154
    } else {
 
155
        eventDispatcher->registerSocketNotifier(this);
 
156
    }
 
157
}
 
158
#endif
 
159
/*!
 
160
    Destroys the socket notifier.
 
161
*/
 
162
 
 
163
QSocketNotifier::~QSocketNotifier()
 
164
{
 
165
    setEnabled(false);
 
166
}
 
167
 
 
168
 
 
169
/*!
 
170
    \fn void QSocketNotifier::activated(int socket)
 
171
 
 
172
    This signal is emitted under certain conditions specified by the
 
173
    notifier type():
 
174
    \list 1
 
175
    \i QSocketNotifier::Read - There is data to be read (socket read event).
 
176
    \i QSocketNotifier::Write - Data can be written (socket write event).
 
177
    \i QSocketNotifier::Exception - An exception has occurred (socket
 
178
    exception event).
 
179
    \endlist
 
180
 
 
181
    The \a socket is the socket identifier.
 
182
 
 
183
    \sa type(), socket()
 
184
*/
 
185
 
 
186
 
 
187
/*!
 
188
    \fn int QSocketNotifier::socket() const
 
189
 
 
190
    Returns the socket identifier specified to the constructor.
 
191
 
 
192
    \sa type()
 
193
*/
 
194
 
 
195
/*!
 
196
    \fn Type QSocketNotifier::type() const
 
197
 
 
198
    Returns the socket event type specified to the constructor.
 
199
 
 
200
    \sa socket()
 
201
*/
 
202
 
 
203
 
 
204
/*!
 
205
    \fn bool QSocketNotifier::isEnabled() const
 
206
 
 
207
    Returns true if the notifier is enabled; otherwise returns false.
 
208
 
 
209
    \sa setEnabled()
 
210
*/
 
211
 
 
212
/*!
 
213
    If \a enable is true, the notifier is enabled; otherwise the notifier
 
214
    is disabled.
 
215
 
 
216
    The notifier is enabled by default.
 
217
 
 
218
    If the notifier is enabled, it emits the activated() signal
 
219
    whenever a socket event corresponding to its \l{type()}{type}
 
220
    occurs. If it is disabled, it ignores socket events (the same
 
221
    effect as not creating the socket notifier).
 
222
 
 
223
    Write notifiers should normally be disabled immediately after the
 
224
    activated() signal has been emitted; see discussion of write
 
225
    notifiers in the \l{write notifiers}{class description} above.
 
226
 
 
227
    \sa isEnabled(), activated()
 
228
*/
 
229
 
 
230
void QSocketNotifier::setEnabled(bool enable)
 
231
{
 
232
    if (sockfd < 0)
 
233
        return;
 
234
    if (snenabled == enable)                        // no change
 
235
        return;
 
236
    snenabled = enable;
 
237
 
 
238
    QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(thread());
 
239
    if (!eventDispatcher) // perhaps application/thread is shutting down
 
240
        return;
 
241
    if (snenabled)
 
242
        eventDispatcher->registerSocketNotifier(this);
 
243
    else
 
244
        eventDispatcher->unregisterSocketNotifier(this);
 
245
}
 
246
 
 
247
 
 
248
/*!\reimp
 
249
*/
 
250
bool QSocketNotifier::event(QEvent *e)
 
251
{
 
252
    // Emits the activated() signal when a QEvent::SockAct is
 
253
    // received.
 
254
    if (e->type() == QEvent::ThreadChange) {
 
255
        if (snenabled) {
 
256
            QMetaObject::invokeMethod(this, "setEnabled", Qt::QueuedConnection,
 
257
                                      Q_ARG(bool, snenabled));
 
258
            setEnabled(false);
 
259
        }
 
260
    }
 
261
    QObject::event(e);                        // will activate filters
 
262
    if (e->type() == QEvent::SockAct) {
 
263
        emit activated(sockfd);
 
264
        return true;
 
265
    }
 
266
    return false;
 
267
}