diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index 9b724657..77de5ea0 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,8 @@ +2007-10-04 Marcus Brinkmann + + * kdpipeiodevice.h, kdpipeiodevice.cpp, kdpipeiodevice.moc, + w32-qt-io.cpp: New versions from Frank Osterfeld. + 2007-10-02 Marcus Brinkmann * kdpipeiodevice.cpp, kdpipeiodevice.moc: New versions. diff --git a/gpgme/kdpipeiodevice.cpp b/gpgme/kdpipeiodevice.cpp index 0cd4ef8e..1fd0ef02 100644 --- a/gpgme/kdpipeiodevice.cpp +++ b/gpgme/kdpipeiodevice.cpp @@ -99,14 +99,14 @@ public: QWaitCondition bufferNotEmptyCondition; QWaitCondition hasStarted; QWaitCondition readyReadSentCondition; - QWaitCondition notInReadDataCondition; + QWaitCondition blockedConsumerIsDoneCondition; bool cancel; bool eof; bool error; bool eofShortCut; int errorCode; - bool inReadData; - + bool consumerBlocksOnUs; + private: unsigned int rptr, wptr; char buffer[BUFFER_SIZE+1]; // need to keep one byte free to detect empty state @@ -127,7 +127,7 @@ Reader::Reader( int fd_, Qt::HANDLE handle_ ) eofShortCut( false ), errorCode( 0 ), rptr( 0 ), wptr( 0 ), - inReadData( false ) + consumerBlocksOnUs( false ) { } @@ -226,13 +226,13 @@ KDPipeIODevice::Private::Private( KDPipeIODevice * qq ) handle( 0 ), reader( 0 ), writer( 0 ), - triedToStartReader( false ), triedToStartWriter( false ) + triedToStartReader( false ), triedToStartWriter( false ) { } KDPipeIODevice::Private::~Private() { - qDebug( "KDPipeIODevice::~Private(): Destroying %p", this ); + qDebug( "KDPipeIODevice::~Private(): Destroying %p", q ); } KDPipeIODevice::KDPipeIODevice( QObject * p ) @@ -290,11 +290,15 @@ bool KDPipeIODevice::Private::startReaderThread() return true; triedToStartReader = true; if ( reader && !reader->isRunning() && !reader->isFinished() ) { + qDebug("KDPipeIODevice::Private::startReaderThread(): locking reader (CONSUMER THREAD)" ); LOCKED( reader ); - + qDebug("KDPipeIODevice::Private::startReaderThread(): locked reader (CONSUMER THREAD)" ); reader->start( QThread::HighestPriority ); - if ( !reader->hasStarted.wait( &reader->mutex, 1000 ) ) - return false; + qDebug("KDPipeIODevice::Private::startReaderThread(): waiting for hasStarted (CONSUMER THREAD)" ); + const bool hasStarted = reader->hasStarted.wait( &reader->mutex, 1000 ); + qDebug("KDPipeIODevice::Private::startReaderThread(): returned from hasStarted (CONSUMER THREAD)" ); + + return hasStarted; } return true; } @@ -320,11 +324,16 @@ void KDPipeIODevice::Private::emitReadyRead() const int counter = s_counter++; QPointer thisPointer( this ); qDebug( "KDPipeIODevice::Private::emitReadyRead %p, %d", this, counter ); + emit q->readyRead(); + if ( !thisPointer ) return; - LOCKED( reader ); - reader->readyReadSentCondition.wakeAll(); + qDebug( "KDPipeIODevice::Private::emitReadyRead %p, %d: locking reader (CONSUMER THREAD)", this, counter ); + synchronized( reader ) { + qDebug( "KDPipeIODevice::Private::emitReadyRead %p, %d: locked reader (CONSUMER THREAD)", this, counter ); + reader->readyReadSentCondition.wakeAll(); + } qDebug( "KDPipeIODevice::Private::emitReadyRead %p leaving %d", this, counter ); } @@ -342,8 +351,6 @@ bool KDPipeIODevice::Private::doOpen( int fd_, Qt::HANDLE handle_, OpenMode mode if ( !(mode_ & ReadWrite) ) return false; // need to have at least read -or- write - fd = fd_; - handle = handle_; std::auto_ptr reader_; std::auto_ptr writer_; @@ -387,7 +394,10 @@ qint64 KDPipeIODevice::bytesAvailable() const { KDAB_CHECK_THIS; return base; } if ( d->reader ) - synchronized( d->reader ) return base + d->reader->bytesInBuffer(); + synchronized( d->reader ) { + const qint64 inBuffer = d->reader->bytesInBuffer(); + return base + inBuffer; + } return base; } @@ -445,6 +455,7 @@ bool KDPipeIODevice::waitForBytesWritten( int msecs ) { KDAB_CHECK_THIS; } bool KDPipeIODevice::waitForReadyRead( int msecs ) { KDAB_CHECK_THIS; + qDebug( "KDPipeIODEvice::waitForReadyRead()(%p)", this); d->startReaderThread(); if ( ALLOW_QIODEVICE_BUFFERING ) { if ( bytesAvailable() > 0 ) @@ -454,7 +465,10 @@ bool KDPipeIODevice::waitForReadyRead( int msecs ) { KDAB_CHECK_THIS; if ( !r || r->eofShortCut ) return true; LOCKED( r ); - return r->bytesInBuffer() != 0 || r->eof || r->error || r->bufferNotEmptyCondition.wait( &r->mutex, msecs ) ; + if ( r->bytesInBuffer() != 0 || r->eof || r->error ) + return true; + assert( false ); + return r->bufferNotEmptyCondition.wait( &r->mutex, msecs ) ; } template @@ -467,6 +481,22 @@ private: const T oldValue; }; + +bool KDPipeIODevice::readWouldBlock() const +{ + d->startReaderThread(); + LOCKED( d->reader ); + return d->reader->bufferEmpty() && !d->reader->eof && !d->reader->error; +} + +bool KDPipeIODevice::writeWouldBlock() const +{ + d->startWriterThread(); + LOCKED( d->writer ); + return d->writer->bufferFull() && !d->writer->error; +} + + qint64 KDPipeIODevice::readData( char * data, qint64 maxSize ) { KDAB_CHECK_THIS; qDebug( "%p: KDPipeIODevice::readData: data=%p, maxSize=%lld", this, data, maxSize ); d->startReaderThread(); @@ -491,15 +521,17 @@ qint64 KDPipeIODevice::readData( char * data, qint64 maxSize ) { KDAB_CHECK_THIS if ( bytesAvailable() > 0 ) maxSize = std::min( maxSize, bytesAvailable() ); // don't block } - + qDebug( "%p: KDPipeIODevice::readData: try to lock reader (CONSUMER THREAD)" ); LOCKED( r ); - const TemporaryValue tmp( d->reader->inReadData, true ); - assert( d->reader->inReadData ); - while ( /* maxSize > 0 && */ r->bufferEmpty() && !r->error && !r->eof ) { // ### block on maxSize == 0? - qDebug( "%p: KDPipeIODevice::readData: waiting for bufferNotEmptyCondition", this ); - r->readyReadSentCondition.wakeAll(); - r->notInReadDataCondition.wakeAll(); + qDebug( "%p: KDPipeIODevice::readData: locked reader (CONSUMER THREAD)" ); + + r->readyReadSentCondition.wakeAll(); + if ( /* maxSize > 0 && */ r->bufferEmpty() && !r->error && !r->eof ) { // ### block on maxSize == 0? + qDebug( "%p: KDPipeIODevice::readData: waiting for bufferNotEmptyCondition (CONSUMER THREAD)", this ); + const TemporaryValue tmp( d->reader->consumerBlocksOnUs, true ); r->bufferNotEmptyCondition.wait( &r->mutex ); + r->blockedConsumerIsDoneCondition.wakeAll(); + qDebug( "%p: KDPipeIODevice::readData: woke up from bufferNotEmptyCondition (CONSUMER THREAD)", this ); } if ( r->bufferEmpty() ) { @@ -507,7 +539,6 @@ qint64 KDPipeIODevice::readData( char * data, qint64 maxSize ) { KDAB_CHECK_THIS // woken with an empty buffer must mean either EOF or error: assert( r->eof || r->error ); r->eofShortCut = true; - r->notInReadDataCondition.wakeAll(); return r->eof ? 0 : -1 ; } @@ -515,7 +546,7 @@ qint64 KDPipeIODevice::readData( char * data, qint64 maxSize ) { KDAB_CHECK_THIS const qint64 bytesRead = r->readData( data, maxSize ); qDebug( "%p: KDPipeIODevice::readData: read %lld bytes", this, bytesRead ); qDebug( "%p (fd=%d): KDPipeIODevice::readData: %s", this, d->fd, data ); - r->notInReadDataCondition.wakeAll(); + return bytesRead; } @@ -590,13 +621,14 @@ void KDPipeIODevice::Private::stopThreads() assert( q->bytesToWrite() == 0 ); } if ( Reader * & r = reader ) { + disconnect( r, SIGNAL( readyRead() ), this, SLOT( emitReadyRead() ) ); synchronized( r ) { // tell thread to cancel: r->cancel = true; // and wake it, so it can terminate: r->bufferNotFullCondition.wakeAll(); r->readyReadSentCondition.wakeAll(); - } + } } if ( Writer * & w = writer ) { synchronized( w ) { @@ -617,10 +649,14 @@ void KDPipeIODevice::close() { KDAB_CHECK_THIS; emit aboutToClose(); d->stopThreads(); -#define waitAndDelete( t ) if ( t ) { t->wait(); QThread* t2 = t; t = 0; delete t2; } +#define waitAndDelete( t ) if ( t ) { t->wait(); QThread* const t2 = t; t = 0; delete t2; } qDebug( "KPipeIODevice::close(%p): wait and closing writer %p", this, d->writer ); waitAndDelete( d->writer ); qDebug( "KPipeIODevice::close(%p): wait and closing reader %p", this, d->reader ); + { + LOCKED( d->reader ); + d->reader->readyReadSentCondition.wakeAll(); + } waitAndDelete( d->reader ); #undef waitAndDelete #ifdef Q_OS_WIN32 @@ -645,115 +681,102 @@ void Reader::run() { qDebug( "%p: Reader::run: started", this ); while ( true ) { - - if ( !bufferFull() && !bufferEmpty() ) { + if ( !cancel && ( eof || error ) ) { + qDebug( "%p: Reader::run: received eof(%d) or error(%d), waking everyone", this, eof, error ); + notifyReadyRead(); + } else if ( !cancel && !bufferFull() && !bufferEmpty() ) { qDebug( "%p: Reader::run: buffer no longer empty, waking everyone", this ); notifyReadyRead(); } - while ( !cancel && bufferFull() ) { - bufferNotEmptyCondition.wakeAll(); + while ( !error && !cancel && bufferFull() ) { notifyReadyRead(); - if ( !bufferFull() ) - break; - qDebug( "%p: Reader::run: buffer is full, going to sleep", this ); - bufferNotFullCondition.wait( &mutex ); - qDebug( "%p: Reader::run: woke up", this ); - } + if ( bufferFull() ) { + qDebug( "%p: Reader::run: buffer is full, going to sleep", this ); + bufferNotFullCondition.wait( &mutex ); + } + } if ( cancel ) { - qDebug( "%p: Reader::run: detected cancel", this ); + qDebug( "%p: Reader::run: detected cancel", this ); goto leave; } + if ( !eof && !error ) { + if ( rptr == wptr ) // optimize for larger chunks in case the buffer is empty + rptr = wptr = 0; - if ( rptr == wptr ) // optimize for larger chunks in case the buffer is empty - rptr = wptr = 0; + unsigned int numBytes = ( rptr + sizeof buffer - wptr - 1 ) % sizeof buffer; + if ( numBytes > sizeof buffer - wptr ) + numBytes = sizeof buffer - wptr; - unsigned int numBytes = ( rptr + sizeof buffer - wptr - 1 ) % sizeof buffer; - if ( numBytes > sizeof buffer - wptr ) - numBytes = sizeof buffer - wptr; + qDebug( "%p: Reader::run: rptr=%d, wptr=%d -> numBytes=%d", this, rptr, wptr, numBytes ); - qDebug( "%p: Reader::run: rptr=%d, wptr=%d -> numBytes=%d", this, rptr, wptr, numBytes ); + assert( numBytes > 0 ); - assert( numBytes > 0 ); - - qDebug( "%p: Reader::run: trying to read %d bytes", this, numBytes ); + qDebug( "%p: Reader::run: trying to read %d bytes", this, numBytes ); #ifdef Q_OS_WIN32 - DWORD numRead; - mutex.unlock(); - const bool ok = ReadFile( handle, buffer + wptr, numBytes, &numRead, 0 ); - mutex.lock(); - if ( !ok ) { - errorCode = static_cast( GetLastError() ); - if ( errorCode == ERROR_BROKEN_PIPE ) { - assert( numRead == 0 ); - qDebug( "%p: Reader::run: got eof (broken pipe)", this ); - eof = true; - } else { - assert( numRead == 0 ); - qDebug( "%p: Reader::run: got error: %s (%d)", this, strerror( errorCode ), errorCode ); - error = true; + mutex.unlock(); + DWORD numRead; + const bool ok = ReadFile( handle, buffer + wptr, numBytes, &numRead, 0 ); + mutex.lock(); + if ( !ok ) { + errorCode = static_cast( GetLastError() ); + if ( errorCode == ERROR_BROKEN_PIPE ) { + assert( numRead == 0 ); + qDebug( "%p: Reader::run: got eof (broken pipe)", this ); + eof = true; + } else { + assert( numRead == 0 ); + qDebug( "%p: Reader::run: got error: %s (%d)", this, strerror( errorCode ), errorCode ); + error = true; + } } - goto leave; - } #else - qint64 numRead; - mutex.unlock(); - do { - numRead = ::read( fd, buffer + wptr, numBytes ); - } while ( numRead == -1 && errno == EINTR ); - mutex.lock(); + qint64 numRead; + mutex.unlock(); + do { + numRead = ::read( fd, buffer + wptr, numBytes ); + } while ( numRead == -1 && errno == EINTR ); + mutex.lock(); - if ( numRead < 0 ) { - errorCode = errno; - error = true; - qDebug( "%p: Reader::run: got error: %d", this, errorCode ); - goto leave; - } + if ( numRead < 0 ) { + errorCode = errno; + error = true; + qDebug( "%p: Reader::run: got error: %d", this, errorCode ); + } else if ( numRead == 0 ) { + qDebug( "%p: Reader::run: eof detected", this ); + eof = true; + } #endif - qDebug( "%p: Reader::run: read %ld bytes", this, static_cast(numRead) ); - qDebug( "%p (fd=%d): KDPipeIODevice::readData: %s", this, fd, buffer ); - if ( numRead == 0 ) { - qDebug( "%p: Reader::run: eof detected", this ); - eof = true; - goto leave; - } + qDebug( "%p: Reader::run: read %ld bytes", this, static_cast(numRead) ); + qDebug( "%p (fd=%d): KDPipeIODevice::readData: %s", this, fd, buffer ); - if ( cancel ) { - qDebug( "%p: Reader::run: detected cancel", this ); - goto leave; - } - qDebug( "%p: Reader::run: buffer before: rptr=%4d, wptr=%4d", this, rptr, wptr ); - wptr = ( wptr + numRead ) % sizeof buffer; - qDebug( "%p: Reader::run: buffer after: rptr=%4d, wptr=%4d", this, rptr, wptr ); + if ( numRead > 0 ) { + qDebug( "%p: Reader::run: buffer before: rptr=%4d, wptr=%4d", this, rptr, wptr ); + wptr = ( wptr + numRead ) % sizeof buffer; + qDebug( "%p: Reader::run: buffer after: rptr=%4d, wptr=%4d", this, rptr, wptr ); + } + } } leave: - qDebug( "%p: Reader::run: terminating: loop while not canceled and not empty", this ); - while ( !cancel && !bufferEmpty() ) { - notifyReadyRead(); - } - notifyReadyRead(); qDebug( "%p: Reader::run: terminated", this ); } void Reader::notifyReadyRead() { - qDebug( "notifyReadyRead" ); - if ( cancel ) - return; - bufferNotEmptyCondition.wakeAll(); - if ( inReadData ) { - qDebug( "notifyReadyRead: inReadData: waiting" ); - notInReadDataCondition.wait( &mutex ); + qDebug( "notifyReadyRead: %d bytes available", bytesInBuffer() ); + assert( !cancel ); + + if ( consumerBlocksOnUs ) { + bufferNotEmptyCondition.wakeAll(); + blockedConsumerIsDoneCondition.wait( &mutex ); + return; } - if ( cancel || ( !eof && !error && bufferEmpty() ) ) - return; - qDebug( "readyReadData: actually emit signal" ); + qDebug( "notifyReadyRead: emit signal" ); emit readyRead(); - bufferNotEmptyCondition.wakeAll(); readyReadSentCondition.wait( &mutex ); - bufferNotEmptyCondition.wakeAll(); + qDebug( "notifyReadyRead: returning from waiting, leave" ); } void Writer::run() { @@ -796,7 +819,7 @@ void Writer::run() { errorCode = static_cast( GetLastError() ); qDebug( "%p: Writer::run: got error code: %d", this, errorCode ); error = true; - goto leave; + goto leave; } #else qint64 numWritten; @@ -805,17 +828,17 @@ void Writer::run() { } while ( numWritten == -1 && errno == EINTR ); if ( numWritten < 0 ) { - mutex.lock(); + mutex.lock(); errorCode = errno; qDebug( "%p: Writer::run: got error code: %d", this, errorCode ); error = true; - goto leave; + goto leave; } #endif qDebug( "%p (fd=%d): Writer::run: buffer after WriteFile (numBytes=%lld): %s:", this, fd, numBytesInBuffer, buffer ); totalWritten += numWritten; - mutex.lock(); + mutex.lock(); } while ( totalWritten < numBytesInBuffer ); qDebug( "%p: Writer::run: wrote %lld bytes", this, totalWritten ); diff --git a/gpgme/kdpipeiodevice.h b/gpgme/kdpipeiodevice.h index f2eab52d..8da6af68 100644 --- a/gpgme/kdpipeiodevice.h +++ b/gpgme/kdpipeiodevice.h @@ -45,6 +45,9 @@ public: Qt::HANDLE handle() const; int descriptor() const; + bool readWouldBlock() const; + bool writeWouldBlock() const; + /* reimp */ qint64 bytesAvailable() const; /* reimp */ qint64 bytesToWrite() const; /* reimp */ bool canReadLine() const; diff --git a/gpgme/kdpipeiodevice.moc b/gpgme/kdpipeiodevice.moc index b2938900..457f371a 100644 --- a/gpgme/kdpipeiodevice.moc +++ b/gpgme/kdpipeiodevice.moc @@ -1,7 +1,7 @@ /**************************************************************************** ** Meta object code from reading C++ file 'kdpipeiodevice.cpp' ** -** Created: Mon Oct 1 16:08:44 2007 +** Created: Tue Oct 2 19:30:13 2007 ** by: The Qt Meta Object Compiler version 59 (Qt 4.3.1) ** ** WARNING! All changes made in this file will be lost! diff --git a/gpgme/w32-qt-io.cpp b/gpgme/w32-qt-io.cpp index 878b2ce0..dd17e87f 100644 --- a/gpgme/w32-qt-io.cpp +++ b/gpgme/w32-qt-io.cpp @@ -82,30 +82,29 @@ using _gpgme_::KDPipeIODevice; really nice callback interfaces to let the user control all this at a per-context level. */ -#define MAX_SLAFD 50000 +#define MAX_SLAFD 1024 struct DeviceEntry { - DeviceEntry() : iodev( 0 ), actual_fd( -1 ), refCount( 1 ) {} - QIODevice* iodev; - int actual_fd; + DeviceEntry() : iodev( 0 ), refCount( 1 ) {} + KDPipeIODevice* iodev; mutable int refCount; void ref() const { ++refCount; } - int unref() const { return --refCount; } + int unref() const { assert( refCount > 0 ); return --refCount; } }; DeviceEntry* iodevice_table[MAX_SLAFD]; -static QIODevice * +static KDPipeIODevice * find_channel (int fd, int create) { + assert( fd < MAX_SLAFD ); if (fd < 0 || fd >= MAX_SLAFD) return NULL; if (create && !iodevice_table[fd]) { DeviceEntry* entry = new DeviceEntry; - entry->actual_fd = fd; entry->iodev = new KDPipeIODevice (fd, QIODevice::ReadWrite|QIODevice::Unbuffered); iodevice_table[fd] = entry; @@ -117,11 +116,9 @@ find_channel (int fd, int create) BUFLEN. The printable version is the representation on the command line that the child process expects. */ int -_gpgme_io_fd2str (char *buf, int buflen, int fd_) +_gpgme_io_fd2str (char *buf, int buflen, int fd) { - const int actual_fd = iodevice_table[fd_] ? iodevice_table[fd_]->actual_fd : fd_; - return snprintf (buf, buflen, "%ld", (long) _get_osfhandle (actual_fd)); - // return snprintf (buf, buflen, "%d", fd); + return snprintf (buf, buflen, "%d", (long)_get_osfhandle( fd ) ); } @@ -143,7 +140,7 @@ _gpgme_io_read (int fd, void *buffer, size_t count) { int saved_errno = 0; qint64 nread; - QIODevice *chan; + KDPipeIODevice *chan; TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_read", fd, "buffer=%p, count=%u", buffer, count); @@ -175,7 +172,7 @@ int _gpgme_io_write (int fd, const void *buffer, size_t count) { qint64 nwritten; - QIODevice *chan; + KDPipeIODevice *chan; TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_write", fd, "buffer=%p, count=%u", buffer, count); TRACE_LOGBUF ((char *) buffer, count); @@ -204,7 +201,7 @@ _gpgme_io_write (int fd, const void *buffer, size_t count) int _gpgme_io_pipe (int filedes[2], int inherit_idx) { - QIODevice *chan; + KDPipeIODevice *chan; TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_pipe", filedes, "inherit_idx=%i (GPGME uses it for %s)", inherit_idx, inherit_idx ? "reading" : "writing"); @@ -266,7 +263,7 @@ _gpgme_io_pipe (int filedes[2], int inherit_idx) int _gpgme_io_close (int fd) { - QIODevice *chan; + KDPipeIODevice *chan; TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_close", fd); if (fd < 0 || fd >= MAX_SLAFD) @@ -286,27 +283,19 @@ _gpgme_io_close (int fd) /* Then do the close. */ DeviceEntry* const entry = iodevice_table[fd]; - if ( entry ) - { - assert( entry->refCount > 0 ); - const int actual_fd = entry->actual_fd; - assert( actual_fd > 0 ); - if ( !entry->unref() ) { - entry->iodev->close(); - delete entry->iodev; - delete entry; - for ( int i = 0; i < MAX_SLAFD; ++i ) { - if ( iodevice_table[i] == entry ) - iodevice_table[i] = 0; + if ( entry ) { + if ( entry->unref() == 0 ) { + entry->iodev->close(); + delete entry->iodev; + delete entry; + iodevice_table[fd] = 0; } - } - - if ( fd != actual_fd ) - _close( fd ); + } else { + _close( fd ); } - else - _close (fd); + + return 0; } @@ -337,7 +326,6 @@ _gpgme_io_set_nonblocking (int fd) /* Qt always uses non-blocking IO, except for files, maybe, but who uses that? */ TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_set_nonblocking", fd); - return TRACE_SYSRES (0); } @@ -538,6 +526,7 @@ _gpgme_io_spawn (const char *path, char **argv, /* Close the other ends of the pipes. */ for (i = 0; fd_parent_list[i].fd != -1; i++) _gpgme_io_close (fd_parent_list[i].fd); + TRACE_LOG4 ("CreateProcess ready: hProcess=%p, hThread=%p, " "dwProcessID=%d, dwThreadId=%d", @@ -565,8 +554,6 @@ _gpgme_io_spawn (const char *path, char **argv, int _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock) { - int i; - int count; /* Use a 1s timeout. */ void *dbg_help = NULL; @@ -576,30 +563,32 @@ _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock) /* We only implement the special case of nonblock == true. */ assert (nonblock); - count = 0; + int count = 0; TRACE_SEQ (dbg_help, "select on [ "); - for (i = 0; i < nfds; i++) + for (int i = 0; i < nfds; i++) { if (fds[i].fd == -1) { fds[i].signaled = 0; - } - else if (fds[i].for_read) - { - const QIODevice * const chan = find_channel (fds[i].fd, 0); - assert (chan); - fds[i].signaled = chan->bytesAvailable() > 0 ? 1 : 0 ; - TRACE_ADD1 (dbg_help, "w0x%x ", fds[i].fd); - count++; + } + else if (fds[i].for_read ) + { + const KDPipeIODevice * const chan = find_channel (fds[i].fd, 0); + assert (chan); + fds[i].signaled = chan->readWouldBlock() ? 0 : 1; + TRACE_ADD1 (dbg_help, "w0x%x ", fds[i].fd); + if ( fds[i].signaled ) + count++; } else if (fds[i].for_write) { - const QIODevice * const chan = find_channel (fds[i].fd, 0); + const KDPipeIODevice * const chan = find_channel (fds[i].fd, 0); assert (chan); - fds[i].signaled = chan->bytesToWrite() > 0 ? 0 : 1 ; + fds[i].signaled = chan->writeWouldBlock() ? 0 : 1; TRACE_ADD1 (dbg_help, "w0x%x ", fds[i].fd); - count++; + if ( fds[i].signaled ) + count++; } } TRACE_END (dbg_help, "]"); @@ -629,21 +618,8 @@ gpgme_get_giochannel (int fd) int _gpgme_io_dup (int fd) { - DeviceEntry* const existing = iodevice_table[fd]; - if ( existing ) - existing->ref(); - else - find_channel( fd, /*create=*/1 ); + assert( iodevice_table[fd] ); + iodevice_table[fd]->ref(); return fd; - -#if 0 - const int new_fd = _dup( fd ); - iodevice_table[new_fd] = iodevice_table[fd]; - if ( iodevice_table[new_fd] ) - iodevice_table[new_fd]->ref(); - else - find_channel( new_fd, /*create=*/1 ); - return new_fd; -#endif }