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(IWvStream *_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 setclone(_cloned);
00037 disassociate_on_close = true;
00038 notify_readable.setAutoDelete(true);
00039 notify_writable.setAutoDelete(true);
00040 notify_exception.setAutoDelete(true);
00041 qt_attach();
00042 }
00043
00044
00045 WvQtStreamClone::~WvQtStreamClone()
00046 {
00047 }
00048
00049
00050 void WvQtStreamClone::pre_poll()
00051 {
00052
00053 _build_selectinfo(si, msec_timeout,
00054 false, false, false, true);
00055
00056
00057
00058
00059 select_timer.stop();
00060 if (si.msec_timeout >= 0)
00061 select_timer.start(si.msec_timeout, true );
00062
00063
00064
00065 for (int fd = 0; fd <= si.max_fd; ++fd)
00066 {
00067 if (FD_ISSET(fd, &si.read))
00068 {
00069 QSocketNotifier *n = notify_readable.find(fd);
00070 if (! n)
00071 {
00072 n = new QSocketNotifier(fd, QSocketNotifier::Read);
00073 notify_readable.insert(fd, n);
00074 QObject::connect(n, SIGNAL(activated(int)),
00075 this, SLOT(fd_readable(int)));
00076 }
00077 } else
00078 notify_readable.remove(fd);
00079
00080 if (FD_ISSET(fd, &si.write))
00081 {
00082 QSocketNotifier *n = notify_writable.find(fd);
00083 if (! n)
00084 {
00085 n = new QSocketNotifier(fd, QSocketNotifier::Write);
00086 notify_writable.insert(fd, n);
00087 QObject::connect(n, SIGNAL(activated(int)),
00088 this, SLOT(fd_writable(int)));
00089 }
00090 } else
00091 notify_writable.remove(fd);
00092
00093 if (FD_ISSET(fd, &si.except))
00094 {
00095 QSocketNotifier *n = notify_exception.find(fd);
00096 if (! n)
00097 {
00098 n = new QSocketNotifier(fd, QSocketNotifier::Exception);
00099 notify_exception.insert(fd, n);
00100 QObject::connect(n, SIGNAL(activated(int)),
00101 this, SLOT(fd_exception(int)));
00102 }
00103 } else
00104 notify_exception.remove(fd);
00105 }
00106
00107
00108 for (int fd = si.max_fd + 1; fd <= last_max_fd; ++fd)
00109 {
00110 notify_readable.remove(fd);
00111 notify_writable.remove(fd);
00112 notify_exception.remove(fd);
00113 }
00114 last_max_fd = si.max_fd;
00115
00116
00117 FD_ZERO(&si.read);
00118 FD_ZERO(&si.write);
00119 FD_ZERO(&si.except);
00120 }
00121
00122
00123 void WvQtStreamClone::post_poll()
00124 {
00125
00126 bool sure = _process_selectinfo(si, true);
00127 if (sure || pending_callback)
00128 {
00129 pending_callback = false;
00130 callback();
00131 if (globalstream) globalstream->callback();
00132 }
00133 }
00134
00135
00136 void WvQtStreamClone::set_timeout(int msec_timeout)
00137 {
00138 this->msec_timeout = msec_timeout;
00139 }
00140
00141
00142 void WvQtStreamClone::qt_begin_event_loop_hook()
00143 {
00144
00145 if (select_in_progress) return;
00146
00147
00148 if (! first_time)
00149 post_poll();
00150 else
00151 first_time = false;
00152
00153 pre_poll();
00154 select_in_progress = true;
00155 }
00156
00157
00158 void WvQtStreamClone::qt_detach()
00159 {
00160
00161 if (! first_time)
00162 {
00163 select_in_progress = false;
00164 post_poll();
00165 last_max_fd = -1;
00166 first_time = true;
00167 }
00168
00169 select_timer.stop();
00170 notify_readable.clear();
00171 notify_writable.clear();
00172 notify_exception.clear();
00173 QObject::disconnect(qApp, SIGNAL(guiThreadAwake()),
00174 this, SLOT(qt_begin_event_loop_hook()));
00175 QObject::disconnect(& select_timer, SIGNAL(timeout()),
00176 this, SLOT(select_timer_expired()));
00177 }
00178
00179
00180 void WvQtStreamClone::qt_attach()
00181 {
00182
00183 QObject::connect(qApp, SIGNAL(guiThreadAwake()),
00184 this, SLOT(qt_begin_event_loop_hook()));
00185 QObject::connect(& select_timer, SIGNAL(timeout()),
00186 this, SLOT(select_timer_expired()));
00187 }
00188
00189
00190 void WvQtStreamClone::select_timer_expired()
00191 {
00192 select_in_progress = false;
00193 }
00194
00195
00196 void WvQtStreamClone::fd_readable(int fd)
00197 {
00198 FD_SET(fd, &si.read);
00199 pending_callback = true;
00200 select_in_progress = false;
00201 }
00202
00203
00204 void WvQtStreamClone::fd_writable(int fd)
00205 {
00206 FD_SET(fd, &si.write);
00207 pending_callback = true;
00208 select_in_progress = false;
00209 }
00210
00211
00212 void WvQtStreamClone::fd_exception(int fd)
00213 {
00214 FD_SET(fd, &si.except);
00215 pending_callback = true;
00216 select_in_progress = false;
00217 }
00218
00219 void WvQtStreamClone::execute()
00220 {
00221 WvStreamClone::execute();
00222 }
00223
00224
00225 void WvQtStreamClone::setclone(IWvStream *newclone)
00226 {
00227 WvStreamClone::setclone(newclone);
00228
00229 if (newclone != NULL)
00230 my_type = WvString("WvQtStreamClone:%s", newclone->wstype());
00231 else
00232 my_type = "WvQtStreamClone:(none)";
00233 }