diff options
| -rw-r--r-- | gpgme/ChangeLog | 5 | ||||
| -rw-r--r-- | gpgme/kdpipeiodevice.cpp | 245 | ||||
| -rw-r--r-- | gpgme/kdpipeiodevice.h | 3 | ||||
| -rw-r--r-- | gpgme/kdpipeiodevice.moc | 2 | ||||
| -rw-r--r-- | gpgme/w32-qt-io.cpp | 104 | 
5 files changed, 183 insertions, 176 deletions
| 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  <[email protected]> + +	* kdpipeiodevice.h, kdpipeiodevice.cpp, kdpipeiodevice.moc, +	w32-qt-io.cpp: New versions from Frank Osterfeld. +  2007-10-02  Marcus Brinkmann  <[email protected]>  	* 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<Private> 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> reader_;      std::auto_ptr<Writer> 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 <typename T> @@ -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<bool> 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<bool> 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<int>( 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<int>( 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(); - -	if ( numRead < 0 ) { -	    errorCode = errno; -	    error = true; -	    qDebug( "%p: Reader::run: got error: %d", this, errorCode ); -	    goto leave; -	} -#endif -	qDebug( "%p: Reader::run: read %ld bytes", this, static_cast<long>(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; -	} +	    qint64 numRead; +	    mutex.unlock(); +	    do { +	        numRead = ::read( fd, buffer + wptr, numBytes ); +	    } while ( numRead == -1 && errno == EINTR ); +	    mutex.lock(); -	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 ) { +	        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<long>(numRead) ); +	    qDebug( "%p (fd=%d): KDPipeIODevice::readData: %s", this, fd, buffer ); + +	    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<int>( 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  } | 
