source: vendor/trolltech/current/src/kernel/qsocketnotifier.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 9.5 KB
Line 
1/****************************************************************************
2** $Id: qsocketnotifier.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Implementation of QSocketNotifier class
5**
6** Created : 951114
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the kernel module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qsocketnotifier.h"
39#include "qapplication.h"
40#include "qevent.h"
41#include "qeventloop.h"
42#include "qplatformdefs.h"
43
44#if defined(Q_OS_UNIX)
45#include <sys/types.h>
46#endif
47
48
49/*!
50 \class QSocketNotifier qsocketnotifier.h
51 \brief The QSocketNotifier class provides support for socket callbacks.
52
53 \ingroup io
54
55 This class makes it possible to write asynchronous socket-based
56 code in Qt. Using synchronous socket operations blocks the
57 program, which is clearly not acceptable for an event-driven GUI
58 program.
59
60 Once you have opened a non-blocking socket (whether for TCP, UDP,
61 a UNIX-domain socket, or any other protocol family your operating
62 system supports), you can create a socket notifier to monitor the
63 socket. Then you connect the activated() signal to the slot you
64 want to be called when a socket event occurs.
65
66 Note for Windows users: the socket passed to QSocketNotifier will
67 become non-blocking, even if it was created as a blocking socket.
68
69 There are three types of socket notifiers (read, write and
70 exception); you must specify one of these in the constructor.
71
72 The type specifies when the activated() signal is to be emitted:
73 \list 1
74 \i QSocketNotifier::Read - There is data to be read (socket read event).
75 \i QSocketNotifier::Write - Data can be written (socket write event).
76 \i QSocketNofifier::Exception - An exception has occurred (socket
77 exception event). We recommend against using this.
78 \endlist
79
80 For example, if you need to monitor both reads and writes for the
81 same socket you must create two socket notifiers.
82
83 Example:
84 \code
85 int sockfd; // socket identifier
86 struct sockaddr_in sa; // should contain host address
87 sockfd = socket( AF_INET, SOCK_STREAM, 0 ); // create TCP socket
88 // make the socket non-blocking here, usually using fcntl( O_NONBLOCK )
89 ::connect( sockfd, (struct sockaddr*)&sa, // connect to host
90 sizeof(sa) ); // NOT QObject::connect()!
91 QSocketNotifier *sn;
92 sn = new QSocketNotifier( sockfd, QSocketNotifier::Read, parent );
93 QObject::connect( sn, SIGNAL(activated(int)),
94 myObject, SLOT(dataReceived()) );
95 \endcode
96
97 The optional \e parent argument can be set to make the socket
98 notifier a child of any QObject, e.g. a widget. This will ensure
99 that it is automatically destroyed when the widget is destroyed.
100
101 For read notifiers it makes little sense to connect the
102 activated() signal to more than one slot because the data can be
103 read from the socket only once.
104
105 Also observe that if you do not read all the available data when
106 the read notifier fires, it fires again and again.
107
108 If you disable the read notifier your program may deadlock. (The
109 same applies to exception notifiers if you must use them, for
110 instance if you \e must use TCP urgent data.)
111
112 For write notifiers, immediately disable the notifier after the
113 activated() signal has been received and you have sent the data to
114 be written on the socket. When you have more data to be written,
115 enable it again to get a new activated() signal. The exception is
116 if the socket data writing operation (send() or equivalent) fails
117 with a "would block" error, which means that some buffer is full
118 and you must wait before sending more data. In that case you do
119 not need to disable and re-enable the write notifier; it will fire
120 again as soon as the system allows more data to be sent.
121
122 The behavior of a write notifier that is left in enabled state
123 after having emitting the first activated() signal (and no "would
124 block" error has occurred) is undefined. Depending on the
125 operating system, it may fire on every pass of the event loop or
126 not at all.
127
128 If you need a time-out for your sockets you can use either \link
129 QObject::startTimer() timer events\endlink or the QTimer class.
130
131 Socket action is detected in the \link QApplication::exec() main
132 event loop\endlink of Qt. The X11 version of Qt has a single UNIX
133 select() call that incorporates all socket notifiers and the X
134 socket.
135
136 Note that on XFree86 for OS/2, select() works only in the thread
137 in which main() is running; you should therefore use that thread
138 for GUI operations.
139
140 \sa QSocket, QServerSocket, QSocketDevice
141*/
142
143/*!
144 \enum QSocketNotifier::Type
145
146 \value Read
147 \value Write
148 \value Exception
149*/
150
151
152/*!
153 Constructs a socket notifier called \a name, with the parent, \a
154 parent. It watches \a socket for \a type events, and enables it.
155
156 It is generally advisable to explicitly enable or disable the
157 socket notifier, especially for write notifiers.
158
159 \sa setEnabled(), isEnabled()
160*/
161
162QSocketNotifier::QSocketNotifier( int socket, Type type, QObject *parent,
163 const char *name )
164 : QObject( parent, name )
165{
166#if defined(QT_CHECK_RANGE)
167 if ( socket < 0 )
168 qWarning( "QSocketNotifier: Invalid socket specified" );
169# if defined(Q_OS_UNIX)
170 if ( socket >= FD_SETSIZE )
171 qWarning( "QSocketNotifier: Socket descriptor too large for select()" );
172# endif
173#endif
174 sockfd = socket;
175 sntype = type;
176 snenabled = TRUE;
177 QApplication::eventLoop()->registerSocketNotifier( this );
178}
179
180/*!
181 Destroys the socket notifier.
182*/
183
184QSocketNotifier::~QSocketNotifier()
185{
186 setEnabled( FALSE );
187}
188
189
190/*!
191 \fn void QSocketNotifier::activated( int socket )
192
193 This signal is emitted under certain conditions specified by the
194 notifier type():
195 \list 1
196 \i QSocketNotifier::Read - There is data to be read (socket read event).
197 \i QSocketNotifier::Write - Data can be written (socket write event).
198 \i QSocketNofifier::Exception - An exception has occurred (socket
199 exception event).
200 \endlist
201
202 The \a socket argument is the \link socket() socket\endlink identifier.
203
204 \sa type(), socket()
205*/
206
207
208/*!
209 \fn int QSocketNotifier::socket() const
210
211 Returns the socket identifier specified to the constructor.
212
213 \sa type()
214*/
215
216/*!
217 \fn Type QSocketNotifier::type() const
218
219 Returns the socket event type specified to the constructor: \c
220 QSocketNotifier::Read, \c QSocketNotifier::Write, or \c
221 QSocketNotifier::Exception.
222
223 \sa socket()
224*/
225
226
227/*!
228 \fn bool QSocketNotifier::isEnabled() const
229
230 Returns TRUE if the notifier is enabled; otherwise returns FALSE.
231
232 \sa setEnabled()
233*/
234
235/*!
236 Enables the notifier if \a enable is TRUE or disables it if \a
237 enable is FALSE.
238
239 The notifier is enabled by default.
240
241 If the notifier is enabled, it emits the activated() signal
242 whenever a socket event corresponding to its \link type()
243 type\endlink occurs. If it is disabled, it ignores socket events
244 (the same effect as not creating the socket notifier).
245
246 Write notifiers should normally be disabled immediately after the
247 activated() signal has been emitted; see discussion of write
248 notifiers in the \link #details class description\endlink above.
249
250 \sa isEnabled(), activated()
251*/
252
253void QSocketNotifier::setEnabled( bool enable )
254{
255 if ( sockfd < 0 )
256 return;
257 if ( snenabled == enable ) // no change
258 return;
259 snenabled = enable;
260
261 QEventLoop *eventloop = QApplication::eventLoop();
262 if ( ! eventloop ) // perhaps application is shutting down
263 return;
264
265 if ( snenabled )
266 eventloop->registerSocketNotifier( this );
267 else
268 eventloop->unregisterSocketNotifier( this );
269}
270
271
272/*!\reimp
273*/
274bool QSocketNotifier::event( QEvent *e )
275{
276 // Emits the activated() signal when a \c QEvent::SockAct is
277 // received.
278 QObject::event( e ); // will activate filters
279 if ( e->type() == QEvent::SockAct ) {
280 emit activated( sockfd );
281 return TRUE;
282 }
283 return FALSE;
284}
Note: See TracBrowser for help on using the repository browser.