[svn] gpgme - r1267 - trunk/gpgme

svn author marcus cvs at cvs.gnupg.org
Fri Sep 28 00:21:20 CEST 2007


Author: marcus
Date: 2007-09-28 00:21:10 +0200 (Fri, 28 Sep 2007)
New Revision: 1267

Modified:
   trunk/gpgme/ChangeLog
   trunk/gpgme/kdpipeiodevice.cpp
   trunk/gpgme/kdpipeiodevice.moc
   trunk/gpgme/w32-qt-io.cpp
Log:
2007-09-28  Marcus Brinkmann  <marcus at g10code.de>

	* kdpipeiodevice.moc, w32-qt-io.cpp, kdpipeiodevice.cpp: New
	versions from Frank Osterfeld.


Modified: trunk/gpgme/ChangeLog
===================================================================
--- trunk/gpgme/ChangeLog	2007-09-27 13:01:54 UTC (rev 1266)
+++ trunk/gpgme/ChangeLog	2007-09-27 22:21:10 UTC (rev 1267)
@@ -1,3 +1,8 @@
+2007-09-28  Marcus Brinkmann  <marcus at g10code.de>
+
+	* kdpipeiodevice.moc, w32-qt-io.cpp, kdpipeiodevice.cpp: New
+	versions from Frank Osterfeld.
+
 2007-09-27  Marcus Brinkmann  <marcus at g10code.de>
 
 	* w32-glib-io.c (_gpgme_io_spawn),

Modified: trunk/gpgme/kdpipeiodevice.cpp
===================================================================
--- trunk/gpgme/kdpipeiodevice.cpp	2007-09-27 13:01:54 UTC (rev 1266)
+++ trunk/gpgme/kdpipeiodevice.cpp	2007-09-27 22:21:10 UTC (rev 1267)
@@ -51,7 +51,7 @@
 const bool ALLOW_QIODEVICE_BUFFERING = true;
 
 // comment to get trace output:
-#define qDebug if(1){}else qDebug
+//#define qDebug if(1){}else qDebug
 
 namespace {
 class Reader : public QThread {
@@ -81,7 +81,7 @@
 		return true;
 	return false;
     }
-	
+        
 Q_SIGNALS:
     void readyRead();
 
@@ -188,7 +188,8 @@
 Writer::~Writer() {}
 
 
-class KDPipeIODevice::Private {
+class KDPipeIODevice::Private : public QObject {
+Q_OBJECT
     friend class ::KDPipeIODevice;
     KDPipeIODevice * const q;
 public:
@@ -196,6 +197,11 @@
     ~Private();
 
     bool doOpen( int, Qt::HANDLE, OpenMode );
+    bool startReaderThread(); 
+    bool startWriterThread(); 
+    void stopThreads();
+    bool triedToStartReader;
+    bool triedToStartWriter;
 
 private:
     int fd;
@@ -205,19 +211,18 @@
 };
 
 KDPipeIODevice::Private::Private( KDPipeIODevice * qq )
-    : q( qq ),
+    : QObject( qq ), q( qq ),
       fd( -1 ),
       handle( 0 ),
       reader( 0 ),
-      writer( 0 )
+      writer( 0 ),
+      triedToStartReader( false ), triedToStartWriter( false )
 {
 
 }
 
-
 KDPipeIODevice::Private::~Private() {}
 
-
 KDPipeIODevice::KDPipeIODevice( QObject * p )
     : QIODevice( p ), d( new Private( this ) )
 {
@@ -267,6 +272,36 @@
 
 }
 
+bool KDPipeIODevice::Private::startReaderThread()
+{
+   if ( triedToStartReader )
+       return true;
+   triedToStartReader = true;    
+   if ( reader && !reader->isRunning() && !reader->isFinished() ) {
+       LOCKED( reader );
+       
+       reader->start( QThread::HighestPriority );
+       if ( !reader->hasStarted.wait( &reader->mutex, 1000 ) )
+            return false;
+   }
+   return true;
+}
+
+bool KDPipeIODevice::Private::startWriterThread()
+{
+   if ( triedToStartWriter )
+       return true;
+   triedToStartWriter = true;    
+   if ( writer && !writer->isRunning() && !writer->isFinished() ) {
+       LOCKED( writer );
+       
+       writer->start( QThread::HighestPriority );
+       if ( !writer->hasStarted.wait( &writer->mutex, 1000 ) )
+            return false;
+   }
+   return true;
+}
+
 bool KDPipeIODevice::Private::doOpen( int fd_, Qt::HANDLE handle_, OpenMode mode_ ) {
 
     if ( q->isOpen() || fd_ < 0 )
@@ -288,19 +323,15 @@
 
     if ( mode_ & ReadOnly ) {
 	reader_.reset( new Reader( fd_, handle_ ) );
-	LOCKED( reader_ );
-	reader_->start( QThread::HighestPriority );
-	if ( !reader_->hasStarted.wait( &reader_->mutex, 1000 ) )
-	    return false;
-	connect( reader_.get(), SIGNAL(readyRead()), q, SIGNAL(readyRead()), Qt::QueuedConnection );
+        qDebug( "KDPipeIODevice::doOpen: created reader for fd %d", fd_ ); 
+	connect( reader_.get(), SIGNAL(readyRead()), q, 
+SIGNAL(readyRead()), Qt::QueuedConnection );
     }
     if ( mode_ & WriteOnly ) {
 	writer_.reset( new Writer( fd_, handle_ ) );
-	LOCKED( writer_ );
-	writer_->start( QThread::HighestPriority );
-	if ( !writer_->hasStarted.wait( &writer_->mutex, 1000 ) )
-	    return false;
-	connect( writer_.get(), SIGNAL(bytesWritten(qint64)), q, SIGNAL(bytesWritten(qint64)), Qt::QueuedConnection );
+        qDebug( "KDPipeIODevice::doOpen: created writer for fd %d", fd_ ); 
+        connect( writer_.get(), SIGNAL(bytesWritten(qint64)), q, SIGNAL(bytesWritten(qint64)), 
+Qt::QueuedConnection );
     }
 
     // commit to *this:
@@ -310,7 +341,6 @@
     writer = writer_.release();
 
     q->setOpenMode( mode_|Unbuffered );
-
     return true;
 }
 
@@ -318,18 +348,24 @@
     return d->fd;
 }
 
+
 Qt::HANDLE KDPipeIODevice::handle() const { KDAB_CHECK_THIS;
     return d->handle;
 }
 
 qint64 KDPipeIODevice::bytesAvailable() const { KDAB_CHECK_THIS;
     const qint64 base = QIODevice::bytesAvailable();
+    if ( !d->triedToStartReader ) {
+         d->startReaderThread();
+         return base;
+    }
     if ( d->reader )
 	synchronized( d->reader ) return base + d->reader->bytesInBuffer();
     return base;
 }
 
 qint64 KDPipeIODevice::bytesToWrite() const { KDAB_CHECK_THIS;
+    d->startWriterThread();
     const qint64 base = QIODevice::bytesToWrite();
     if ( d->writer )
 	synchronized( d->writer ) return base + d->writer->bytesInBuffer();
@@ -337,7 +373,8 @@
 }
 
 bool KDPipeIODevice::canReadLine() const { KDAB_CHECK_THIS;
-    if ( QIODevice::canReadLine() )
+    d->startReaderThread();
+   if ( QIODevice::canReadLine() )
 	return true;
     if ( d->reader )
 	synchronized( d->reader ) return d->reader->bufferContains( '\n' );
@@ -349,8 +386,9 @@
 }
 
 bool KDPipeIODevice::atEnd() const { KDAB_CHECK_THIS;
+    d->startReaderThread();
     if ( !QIODevice::atEnd() ) {
-	qDebug( "KDPipeIODevice::atEnd returns false since QIODevice::atEnd does (with bytesAvailable=%ld)", static_cast<long>(bytesAvailable()) );
+	qDebug( "%p: KDPipeIODevice::atEnd returns false since QIODevice::atEnd does (with bytesAvailable=%ld)", this, static_cast<long>(bytesAvailable()) );
 	return false;
     }
     if ( !isOpen() )
@@ -361,14 +399,15 @@
     const bool eof = ( d->reader->error || d->reader->eof ) && d->reader->bufferEmpty();
     if ( !eof ) {
 	if ( !d->reader->error && !d->reader->eof )
-	    qDebug( "KDPipeIODevice::atEnd returns false since !reader->error && !reader->eof" );
+	    qDebug( "%p: KDPipeIODevice::atEnd returns false since !reader->error && !reader->eof", this );
 	if ( !d->reader->bufferEmpty() )
-	    qDebug( "KDPipeIODevice::atEnd returns false since !reader->bufferEmpty()" );
+	    qDebug( "%p: KDPipeIODevice::atEnd returns false since !reader->bufferEmpty()", this );
     }
     return eof;
 }
 
 bool KDPipeIODevice::waitForBytesWritten( int msecs ) { KDAB_CHECK_THIS;
+    d->startWriterThread();
     Writer * const w = d->writer;
     if ( !w )
 	return true;
@@ -377,6 +416,7 @@
 }
 
 bool KDPipeIODevice::waitForReadyRead( int msecs ) { KDAB_CHECK_THIS;
+    d->startReaderThread();
     if ( ALLOW_QIODEVICE_BUFFERING ) {
 	if ( bytesAvailable() > 0 )
 	    return true;
@@ -389,18 +429,22 @@
 }
 
 qint64 KDPipeIODevice::readData( char * data, qint64 maxSize ) { KDAB_CHECK_THIS;
+    qDebug( "%p: KDPipeIODevice::readData: data=%p, maxSize=%lld", this, data, maxSize );
 
-    qDebug( "KDPipeIODevice::readData: data=%p, maxSize=%lld", data, maxSize );
+    if ( maxSize == 0 )
+        return 0;
+    d->startReaderThread();
 
     Reader * const r = d->reader;
 
     assert( r );
+
     //assert( r->isRunning() ); // wrong (might be eof, error)
     assert( data || maxSize == 0 );
     assert( maxSize >= 0 );
 
     if ( r->eofShortCut ) {
-	qDebug( "KDPipeIODevice::readData: hit eofShortCut, returning 0" );
+	qDebug( "%p: KDPipeIODevice::readData: hit eofShortCut, returning 0", this );
 	return 0;
     }
 
@@ -414,31 +458,31 @@
 
     LOCKED( r );
     if ( /* maxSize > 0 && */ r->bufferEmpty() && !r->error && !r->eof ) { // ### block on maxSize == 0?
-	qDebug( "KDPipeIODevice::readData: waiting for bufferNotEmptyCondition" );
+	qDebug( "%p: KDPipeIODevice::readData: waiting for bufferNotEmptyCondition", this );
 	r->bufferNotEmptyCondition.wait( &r->mutex );
     }
 
     if ( r->bufferEmpty() ) {
-	qDebug( "KDPipeIODevice::readData: got empty buffer, signal eof" );
+	qDebug( "%p: KDPipeIODevice::readData: got empty buffer, signal eof", this );
 	// woken with an empty buffer must mean either EOF or error:
 	assert( r->eof || r->error );
 	r->eofShortCut = true;
 	return r->eof ? 0 : -1 ;
     }
 
-    qDebug( "KDPipeIODevice::readData: got bufferNotEmptyCondition, trying to read %lld bytes", maxSize );
+    qDebug( "%p: KDPipeIODevice::readData: got bufferNotEmptyCondition, trying to read %lld bytes", this, maxSize );
     const qint64 bytesRead = r->readData( data, maxSize );
-    qDebug( "KDPipeIODevice::readData: read %lld bytes", bytesRead );
+    qDebug( "%p: KDPipeIODevice::readData: read %lld bytes", this, bytesRead );
+    qDebug( "%p (fd=%d): KDPipeIODevice::readData: %s", this, d->fd, data );
     return bytesRead;
 }
 
 qint64 Reader::readData( char * data, qint64 maxSize ) {
-
     qint64 numRead = rptr < wptr ? wptr - rptr : sizeof buffer - rptr ;
     if ( numRead > maxSize )
 	numRead = maxSize;
 
-    qDebug( "KDPipeIODevice::readData: data=%p, maxSize=%lld; rptr=%u, wptr=%u (bytesInBuffer=%u); -> numRead=%lld",
+    qDebug( "%p: KDPipeIODevice::readData: data=%p, maxSize=%lld; rptr=%u, wptr=%u (bytesInBuffer=%u); -> numRead=%lld", this,
 	    data, maxSize, rptr, wptr, bytesInBuffer(), numRead );
 
     std::memcpy( data, buffer + rptr, numRead );
@@ -446,7 +490,7 @@
     rptr = ( rptr + numRead ) % sizeof buffer ;
 
     if ( !bufferFull() ) {
-	qDebug( "KDPipeIODevice::readData: signal bufferNotFullCondition" );
+	qDebug( "%p: KDPipeIODevice::readData: signal bufferNotFullCondition", this );
 	bufferNotFullCondition.wakeAll();
     }
 
@@ -454,7 +498,7 @@
 }
 
 qint64 KDPipeIODevice::writeData( const char * data, qint64 size ) { KDAB_CHECK_THIS;
-
+    d->startWriterThread();
     Writer * const w = d->writer;
 
     assert( w );
@@ -476,7 +520,6 @@
 }
 
 qint64 Writer::writeData( const char * data, qint64 size ) {
-
     assert( bufferEmpty() );
 
     if ( size > static_cast<qint64>( sizeof buffer ) )
@@ -492,40 +535,47 @@
     return size;
 }
 
-void KDPipeIODevice::close() { KDAB_CHECK_THIS;
+void KDPipeIODevice::Private::stopThreads()
+{
+    if ( triedToStartWriter )
+    {
+        if ( writer && q->bytesToWrite() > 0 )
+	    q->waitForBytesWritten( -1 );
 
-    if ( !isOpen() )
-	return;
-
-    // tell clients we're about to close:
-    emit aboutToClose();
-
-    if ( d->writer && bytesToWrite() > 0 )
-	waitForBytesWritten( -1 );
-
-    assert( bytesToWrite() == 0 );
-
-    if ( Reader * & r = d->reader ) {
+        assert( q->bytesToWrite() == 0 );
+    }
+    if ( Reader * & r = reader ) {
 	synchronized( r ) {
 	    // tell thread to cancel:
 	    r->cancel = true;
 	    // and wake it, so it can terminate:
 	    r->bufferNotFullCondition.wakeAll();
 	}
-	r->wait();
-	delete r; r = 0;
     }
-    if ( Writer * & w = d->writer ) {
+    if ( Writer * & w = writer ) {
 	synchronized( w ) {
 	    // tell thread to cancel:
 	    w->cancel = true;
 	    // and wake it, so it can terminate:
 	    w->bufferNotEmptyCondition.wakeAll();
 	}
-	w->wait();
-	delete w; w = 0;
     }
+}
 
+void KDPipeIODevice::close() { KDAB_CHECK_THIS;
+
+    if ( !isOpen() )
+	return;
+
+    // tell clients we're about to close:
+    emit aboutToClose();
+    d->stopThreads();
+
+#define waitAndDelete( t ) if ( t ) { t->wait(); delete t; t = 0; }
+    waitAndDelete( d->writer );
+    waitAndDelete( d->reader );
+#undef waitAndDelete
+
 #ifdef Q_OS_WIN32
     CloseHandle( d->handle );
 #else
@@ -544,19 +594,19 @@
     // too bad QThread doesn't have that itself; a signal isn't enough
     hasStarted.wakeAll();
 
-    qDebug( "Reader::run: started" );
+    qDebug( "%p: Reader::run: started", this );
 
     while ( true ) {
 
 	while ( !cancel && bufferFull() ) {
 	    bufferNotEmptyCondition.wakeAll();
-	    qDebug( "Reader::run: buffer is full, going to sleep" );
+	    qDebug( "%p: Reader::run: buffer is full, going to sleep", this );
 	    bufferNotFullCondition.wait( &mutex );
-	    qDebug( "Reader::run: woke up" );
+	    qDebug( "%p: Reader::run: woke up", this );
 	}
 
 	if ( cancel ) {
-	    qDebug( "Reader::run: detected cancel" );
+	    qDebug( "%p: Reader::run: detected cancel", this );
 	    goto leave;
 	}
 
@@ -567,11 +617,11 @@
 	if ( numBytes > sizeof buffer - wptr )
 	    numBytes = sizeof buffer - wptr;
 
-	qDebug( "Reader::run: rptr=%d, wptr=%d -> numBytes=%d", rptr, wptr, numBytes );
+	qDebug( "%p: Reader::run: rptr=%d, wptr=%d -> numBytes=%d", this, rptr, wptr, numBytes );
 
 	assert( numBytes > 0 );
 
-	qDebug( "Reader::run: trying to read %d bytes", numBytes );
+	qDebug( "%p: Reader::run: trying to read %d bytes", this, numBytes );
 #ifdef Q_OS_WIN32
 	DWORD numRead;
 	mutex.unlock();
@@ -580,10 +630,10 @@
 	if ( !ok ) {
 	    errorCode = static_cast<int>( GetLastError() );
 	    if ( errorCode == ERROR_BROKEN_PIPE ) {
-		qDebug( "Reader::run: got eof" );
+		qDebug( "%p: Reader::run: got eof (broken pipe)", this );
 		eof = true;
 	    } else {
-		qDebug( "Reader::run: got error: %d", errorCode );
+		qDebug( "%p: Reader::run: got error: %s (%d)", this, strerror( errorCode ), errorCode );
 		error = true;
 	    }
 	    goto leave;
@@ -599,32 +649,33 @@
 	if ( numRead < 0 ) {
 	    errorCode = errno;
 	    error = true;
-	    qDebug( "Reader::run: got error: %d", errorCode );
+	    qDebug( "%p: Reader::run: got error: %d", this, errorCode );
 	    goto leave;
 	}
 #endif
-	qDebug( "Reader::run: read %ld bytes", static_cast<long>(numRead) );
+	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( "Reader::run: eof detected" );
+	    qDebug( "%p: Reader::run: eof detected", this );
 	    eof = true;
 	    goto leave;
 	}
 
 	if ( cancel ) {
-	    qDebug( "Reader::run: detected cancel" );
+	    qDebug( "%p: Reader::run: detected cancel", this );
 	    goto leave;
 	}
-	qDebug( "Reader::run: buffer before: rptr=%4d, wptr=%4d", rptr, wptr );
+	qDebug( "%p: Reader::run: buffer before: rptr=%4d, wptr=%4d", this, rptr, wptr );
 	wptr = ( wptr + numRead ) % sizeof buffer;
-	qDebug( "Reader::run: buffer after:  rptr=%4d, wptr=%4d", rptr, wptr );
+	qDebug( "%p: Reader::run: buffer after:  rptr=%4d, wptr=%4d", this, rptr, wptr );
 	if ( !bufferEmpty() ) {
-	    qDebug( "Reader::run: buffer no longer empty, waking everyone" );
+	    qDebug( "%p: Reader::run: buffer no longer empty, waking everyone", this );
 	    bufferNotEmptyCondition.wakeAll();
 	    emit readyRead();
 	}
     }
  leave:
-    qDebug( "Reader::run: terminating" );
+    qDebug( "%p: Reader::run: terminating", this );
     bufferNotEmptyCondition.wakeAll();
     emit readyRead();
 }
@@ -636,25 +687,25 @@
     // too bad QThread doesn't have that itself; a signal isn't enough
     hasStarted.wakeAll();
 
-    qDebug( "Writer::run: started" );
+    qDebug( "%p: Writer::run: started", this );
 
     while ( true ) {
 
 	while ( !cancel && bufferEmpty() ) {
 	    bufferEmptyCondition.wakeAll();
-	    qDebug( "Writer::run: buffer is empty, going to sleep" );
+	    qDebug( "%p: Writer::run: buffer is empty, going to sleep", this );
 	    bufferNotEmptyCondition.wait( &mutex );
-	    qDebug( "Writer::run: woke up" );
+	    qDebug( "%p: Writer::run: woke up", this );
 	}
 
 	if ( cancel ) {
-	    qDebug( "Writer::run: detected cancel" );
+	    qDebug( "%p: Writer::run: detected cancel", this );
 	    goto leave;
 	}
 
 	assert( numBytesInBuffer > 0 );
 
-	qDebug( "Writer::run: Trying to write %u bytes", numBytesInBuffer );
+	qDebug( "%p: Writer::run: Trying to write %u bytes", this, numBytesInBuffer );
 	qint64 totalWritten = 0;
 	do { 
 	    mutex.unlock();
@@ -663,7 +714,7 @@
 	    if ( !WriteFile( handle, buffer + totalWritten, numBytesInBuffer - totalWritten, &numWritten, 0 ) ) {
 		mutex.lock();
 		errorCode = static_cast<int>( GetLastError() );
-		qDebug( "Writer::run: got error code: %d", errorCode );
+		qDebug( "%p: Writer::run: got error code: %d", this, errorCode );
 		error = true;
 		goto leave;
 	    }
@@ -676,7 +727,7 @@
 	    if ( numWritten < 0 ) {
 		mutex.lock();
 		errorCode = errno;
-		qDebug( "Writer::run: got error code: %d", errorCode );
+		qDebug( "%p: Writer::run: got error code: %d", this, errorCode );
 		error = true;
 		goto leave;
 	    }
@@ -685,14 +736,14 @@
 	    mutex.lock();
 	} while ( totalWritten < numBytesInBuffer );
 
-	qDebug( "Writer::run: wrote %lld bytes", totalWritten );
+	qDebug( "%p: Writer::run: wrote %lld bytes", this, totalWritten );
 
 	numBytesInBuffer = 0;
 	bufferEmptyCondition.wakeAll();
 	emit bytesWritten( totalWritten );
     }
  leave:
-    qDebug( "Writer::run: terminating" );
+    qDebug( "%p: Writer::run: terminating", this );
     numBytesInBuffer = 0;
     bufferEmptyCondition.wakeAll();
     emit bytesWritten( 0 );

Modified: trunk/gpgme/kdpipeiodevice.moc
===================================================================
--- trunk/gpgme/kdpipeiodevice.moc	2007-09-27 13:01:54 UTC (rev 1266)
+++ trunk/gpgme/kdpipeiodevice.moc	2007-09-27 22:21:10 UTC (rev 1267)
@@ -1,8 +1,8 @@
 /****************************************************************************
 ** Meta object code from reading C++ file 'kdpipeiodevice.cpp'
 **
-** Created: Mon Aug 27 15:17:18 2007
-**      by: The Qt Meta Object Compiler version 59 (Qt 4.3.0)
+** Created: Wed Sep 26 11:05:05 2007
+**      by: The Qt Meta Object Compiler version 59 (Qt 4.3.1)
 **
 ** WARNING! All changes made in this file will be lost!
 *****************************************************************************/
@@ -10,7 +10,7 @@
 #if !defined(Q_MOC_OUTPUT_REVISION)
 #error "The header file 'kdpipeiodevice.cpp' doesn't include <QObject>."
 #elif Q_MOC_OUTPUT_REVISION != 59
-#error "This file was generated using the moc from 4.3.0. It"
+#error "This file was generated using the moc from 4.3.1. It"
 #error "cannot be used with the include files from this version of Qt."
 #error "(The moc has changed too much.)"
 #endif
@@ -130,3 +130,45 @@
     void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
     QMetaObject::activate(this, &staticMetaObject, 0, _a);
 }
+static const uint qt_meta_data_KDPipeIODevice__Private[] = {
+
+ // content:
+       1,       // revision
+       0,       // classname
+       0,    0, // classinfo
+       0,    0, // methods
+       0,    0, // properties
+       0,    0, // enums/sets
+
+       0        // eod
+};
+
+static const char qt_meta_stringdata_KDPipeIODevice__Private[] = {
+    "KDPipeIODevice::Private\0"
+};
+
+const QMetaObject KDPipeIODevice::Private::staticMetaObject = {
+    { &QObject::staticMetaObject, qt_meta_stringdata_KDPipeIODevice__Private,
+      qt_meta_data_KDPipeIODevice__Private, 0 }
+};
+
+const QMetaObject *KDPipeIODevice::Private::metaObject() const
+{
+    return &staticMetaObject;
+}
+
+void *KDPipeIODevice::Private::qt_metacast(const char *_clname)
+{
+    if (!_clname) return 0;
+    if (!strcmp(_clname, qt_meta_stringdata_KDPipeIODevice__Private))
+	return static_cast<void*>(const_cast< Private*>(this));
+    return QObject::qt_metacast(_clname);
+}
+
+int KDPipeIODevice::Private::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+    _id = QObject::qt_metacall(_c, _id, _a);
+    if (_id < 0)
+        return _id;
+    return _id;
+}

Modified: trunk/gpgme/w32-qt-io.cpp
===================================================================
--- trunk/gpgme/w32-qt-io.cpp	2007-09-27 13:01:54 UTC (rev 1266)
+++ trunk/gpgme/w32-qt-io.cpp	2007-09-27 22:21:10 UTC (rev 1267)
@@ -82,12 +82,20 @@
    really nice callback interfaces to let the user control all this at
    a per-context level.  */
 
-
-#define MAX_SLAFD 256
+#define MAX_SLAFD 50000
 
-QIODevice *iodevice_table[MAX_SLAFD];
+struct DeviceEntry {
+  DeviceEntry() : iodev( 0 ), actual_fd( -1 ), refCount( 1 ) {}
+    QIODevice* iodev;
+    int actual_fd;
+    mutable int refCount;
+    void ref() const { ++refCount; }
+    int unref() const { return --refCount; }
+};
 
+DeviceEntry* iodevice_table[MAX_SLAFD];
 
+
 static QIODevice *
 find_channel (int fd, int create)
 {
@@ -95,13 +103,16 @@
     return NULL;
 
   if (create && !iodevice_table[fd])
-    iodevice_table[fd] = new KDPipeIODevice
-      (fd, QIODevice::ReadOnly|QIODevice::Unbuffered);
-
-  return iodevice_table[fd];
+  {
+    DeviceEntry* entry = new DeviceEntry;
+    entry->actual_fd = fd;
+    entry->iodev = new KDPipeIODevice
+      (fd, QIODevice::ReadWrite|QIODevice::Unbuffered);
+    iodevice_table[fd] = entry; 
+  }
+  return iodevice_table[fd] ? iodevice_table[fd]->iodev : 0;
 }
 
-
 /* Write the printable version of FD to the buffer BUF of length
    BUFLEN.  The printable version is the representation on the command
    line that the child process expects.  */
@@ -232,7 +243,9 @@
 
   /* Now we have a pipe with the right end inheritable.  The other end
      should have a giochannel.  */
+
   chan = find_channel (filedes[1 - inherit_idx], 1);
+
   if (!chan)
     {
       int saved_errno = errno;
@@ -248,7 +261,6 @@
 	  chan);
 }
 
-
 int
 _gpgme_io_close (int fd)
 {
@@ -270,16 +282,29 @@
     }
 
   /* Then do the close.  */    
-  chan = iodevice_table[fd];
-  if (chan)
-    {
-      chan->close();
-      delete chan;
-      iodevice_table[fd] = NULL;
+  
+  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 ( fd != actual_fd )
+      _close( fd );       
+  }
   else
     _close (fd);
-
+  
   return 0;
 }
 
@@ -334,7 +359,7 @@
       /* The leading double-quote.  */
       n++;
       while (*p)
-	{
+      {
 	  /* An extra one for each literal that must be escaped.  */
 	  if (*p == '\\' || *p == '"')
 	    n++;
@@ -586,13 +611,6 @@
 }
 
 
-int
-_gpgme_io_dup (int fd)
-{
-  return _dup (fd);
-}
-
-
 /* Look up the qiodevice for file descriptor FD.  */
 extern "C"
 void *
@@ -610,3 +628,16 @@
   return NULL;
 }
 
+
+int
+_gpgme_io_dup (int fd)
+{
+  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;
+}
+




More information about the Gnupg-commits mailing list