00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include "wvqtstreamclone.moc"
00023
00024
00025
00026 #define NUM_SLOTS 41 // must be prime
00027
00028 WvQtStreamClone::WvQtStreamClone(
WvStream* _cloned,
int msec_timeout) :
00029
WvStreamClone(_cloned), msec_timeout(msec_timeout),
00030 pending_callback(false), first_time(true), select_in_progress(false),
00031 last_max_fd(-1),
00032 notify_readable(
NUM_SLOTS),
00033 notify_writable(
NUM_SLOTS),
00034 notify_exception(
NUM_SLOTS)
00035 {
00036 notify_readable.setAutoDelete(
true);
00037 notify_writable.setAutoDelete(
true);
00038 notify_exception.setAutoDelete(
true);
00039
qt_attach();
00040 }
00041
00042
00043 WvQtStreamClone::~WvQtStreamClone()
00044 {
00045 }
00046
00047
00048
void WvQtStreamClone::pre_poll()
00049 {
00050
00051
bool sure = _build_selectinfo(si, msec_timeout,
00052
false,
false,
false,
true);
00053
if (sure)
00054 {
00055 pending_callback =
true;
00056 si.msec_timeout = 0;
00057 }
00058
00059
00060
00061
00062 select_timer.stop();
00063
if (si.msec_timeout >= 0)
00064 select_timer.start(si.msec_timeout,
true );
00065
00066
00067
00068
for (
int fd = 0; fd <= si.max_fd; ++fd)
00069 {
00070
if (FD_ISSET(fd, &si.read))
00071 {
00072 QSocketNotifier *n = notify_readable.find(fd);
00073
if (! n)
00074 {
00075 n =
new QSocketNotifier(fd, QSocketNotifier::Read);
00076 notify_readable.insert(fd, n);
00077 QObject::connect(n, SIGNAL(activated(
int)),
00078
this, SLOT(fd_readable(
int)));
00079 }
00080 }
else
00081 notify_readable.remove(fd);
00082
00083
if (FD_ISSET(fd, &si.write))
00084 {
00085 QSocketNotifier *n = notify_writable.find(fd);
00086
if (! n)
00087 {
00088 n =
new QSocketNotifier(fd, QSocketNotifier::Write);
00089 notify_writable.insert(fd, n);
00090 QObject::connect(n, SIGNAL(activated(
int)),
00091
this, SLOT(fd_writable(
int)));
00092 }
00093 }
else
00094 notify_writable.remove(fd);
00095
00096
if (FD_ISSET(fd, &si.except))
00097 {
00098 QSocketNotifier *n = notify_exception.find(fd);
00099
if (! n)
00100 {
00101 n =
new QSocketNotifier(fd, QSocketNotifier::Exception);
00102 notify_exception.insert(fd, n);
00103 QObject::connect(n, SIGNAL(activated(
int)),
00104
this, SLOT(fd_exception(
int)));
00105 }
00106 }
else
00107 notify_exception.remove(fd);
00108 }
00109
00110
00111
for (
int fd = si.max_fd + 1; fd <= last_max_fd; ++fd)
00112 {
00113 notify_readable.remove(fd);
00114 notify_writable.remove(fd);
00115 notify_exception.remove(fd);
00116 }
00117 last_max_fd = si.max_fd;
00118
00119
00120 FD_ZERO(&si.read);
00121 FD_ZERO(&si.write);
00122 FD_ZERO(&si.except);
00123 }
00124
00125
00126
void WvQtStreamClone::post_poll()
00127 {
00128
00129
bool sure =
_process_selectinfo(si,
true);
00130
if (sure || pending_callback)
00131 {
00132 pending_callback =
false;
00133
callback();
00134
if (
globalstream)
globalstream->
callback();
00135 }
00136 }
00137
00138
00139 void WvQtStreamClone::set_timeout(
int msec_timeout)
00140 {
00141 this->msec_timeout = msec_timeout;
00142 }
00143
00144
00145
void WvQtStreamClone::qt_begin_event_loop_hook()
00146 {
00147
00148
if (select_in_progress)
return;
00149
00150
00151
if (! first_time)
00152 post_poll();
00153
else
00154 first_time =
false;
00155
00156 pre_poll();
00157 select_in_progress =
true;
00158 }
00159
00160
00161 void WvQtStreamClone::qt_detach()
00162 {
00163
00164
if (! first_time)
00165 {
00166 select_in_progress =
false;
00167 post_poll();
00168 last_max_fd = -1;
00169 first_time =
true;
00170 }
00171
00172 select_timer.stop();
00173 notify_readable.clear();
00174 notify_writable.clear();
00175 notify_exception.clear();
00176 QObject::disconnect(qApp, SIGNAL(guiThreadAwake()),
00177
this, SLOT(qt_begin_event_loop_hook()));
00178 QObject::disconnect(& select_timer, SIGNAL(
timeout()),
00179
this, SLOT(select_timer_expired()));
00180 }
00181
00182
00183 void WvQtStreamClone::qt_attach()
00184 {
00185
00186 QObject::connect(qApp, SIGNAL(guiThreadAwake()),
00187
this, SLOT(qt_begin_event_loop_hook()));
00188 QObject::connect(& select_timer, SIGNAL(
timeout()),
00189
this, SLOT(select_timer_expired()));
00190 }
00191
00192
00193
void WvQtStreamClone::select_timer_expired()
00194 {
00195 select_in_progress =
false;
00196 }
00197
00198
00199
void WvQtStreamClone::fd_readable(
int fd)
00200 {
00201 FD_SET(fd, &si.read);
00202 pending_callback =
true;
00203 select_in_progress =
false;
00204 }
00205
00206
00207
void WvQtStreamClone::fd_writable(
int fd)
00208 {
00209 FD_SET(fd, &si.write);
00210 pending_callback =
true;
00211 select_in_progress =
false;
00212 }
00213
00214
00215
void WvQtStreamClone::fd_exception(
int fd)
00216 {
00217 FD_SET(fd, &si.except);
00218 pending_callback =
true;
00219 select_in_progress =
false;
00220 }
00221
00222
void WvQtStreamClone::execute()
00223 {
00224
WvStreamClone::execute();
00225 }