2007-10-02 Marcus Brinkmann <marcus@g10code.de>
* kdpipeiodevice.cpp, kdpipeiodevice.moc: New versions. * w32-qt-io.cpp (_gpgme_io_fd2str): Print actual_fd if available. (_gpgme_io_dup): Only acquire a reference, do not actually dup. Submitted by Frank Osterfeld.
This commit is contained in:
parent
d8289000fe
commit
228ca8fab2
@ -1,5 +1,10 @@
|
|||||||
2007-10-02 Marcus Brinkmann <marcus@g10code.de>
|
2007-10-02 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
|
* kdpipeiodevice.cpp, kdpipeiodevice.moc: New versions.
|
||||||
|
* w32-qt-io.cpp (_gpgme_io_fd2str): Print actual_fd if available.
|
||||||
|
(_gpgme_io_dup): Only acquire a reference, do not actually dup.
|
||||||
|
Submitted by Frank Osterfeld.
|
||||||
|
|
||||||
* priv-io.h, engine-gpgsm.c: Add comments.
|
* priv-io.h, engine-gpgsm.c: Add comments.
|
||||||
* w32-qt-io.cpp (_gpgme_io_select): Remove code handling frozen FDs.
|
* w32-qt-io.cpp (_gpgme_io_select): Remove code handling frozen FDs.
|
||||||
* w32-glib-io.c (_gpgme_io_close): Always dereference the channel,
|
* w32-glib-io.c (_gpgme_io_close): Always dereference the channel,
|
||||||
|
@ -82,6 +82,8 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void notifyReadyRead();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void readyRead();
|
void readyRead();
|
||||||
|
|
||||||
@ -96,11 +98,15 @@ public:
|
|||||||
QWaitCondition bufferNotFullCondition;
|
QWaitCondition bufferNotFullCondition;
|
||||||
QWaitCondition bufferNotEmptyCondition;
|
QWaitCondition bufferNotEmptyCondition;
|
||||||
QWaitCondition hasStarted;
|
QWaitCondition hasStarted;
|
||||||
|
QWaitCondition readyReadSentCondition;
|
||||||
|
QWaitCondition notInReadDataCondition;
|
||||||
bool cancel;
|
bool cancel;
|
||||||
bool eof;
|
bool eof;
|
||||||
bool error;
|
bool error;
|
||||||
bool eofShortCut;
|
bool eofShortCut;
|
||||||
int errorCode;
|
int errorCode;
|
||||||
|
bool inReadData;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int rptr, wptr;
|
unsigned int rptr, wptr;
|
||||||
char buffer[BUFFER_SIZE+1]; // need to keep one byte free to detect empty state
|
char buffer[BUFFER_SIZE+1]; // need to keep one byte free to detect empty state
|
||||||
@ -120,7 +126,8 @@ Reader::Reader( int fd_, Qt::HANDLE handle_ )
|
|||||||
error( false ),
|
error( false ),
|
||||||
eofShortCut( false ),
|
eofShortCut( false ),
|
||||||
errorCode( 0 ),
|
errorCode( 0 ),
|
||||||
rptr( 0 ), wptr( 0 )
|
rptr( 0 ), wptr( 0 ),
|
||||||
|
inReadData( false )
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -203,6 +210,9 @@ public:
|
|||||||
bool triedToStartReader;
|
bool triedToStartReader;
|
||||||
bool triedToStartWriter;
|
bool triedToStartWriter;
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void emitReadyRead();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int fd;
|
int fd;
|
||||||
Qt::HANDLE handle;
|
Qt::HANDLE handle;
|
||||||
@ -221,7 +231,9 @@ KDPipeIODevice::Private::Private( KDPipeIODevice * qq )
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
KDPipeIODevice::Private::~Private() {}
|
KDPipeIODevice::Private::~Private() {
|
||||||
|
qDebug( "KDPipeIODevice::~Private(): Destroying %p", this );
|
||||||
|
}
|
||||||
|
|
||||||
KDPipeIODevice::KDPipeIODevice( QObject * p )
|
KDPipeIODevice::KDPipeIODevice( QObject * p )
|
||||||
: QIODevice( p ), d( new Private( this ) )
|
: QIODevice( p ), d( new Private( this ) )
|
||||||
@ -302,6 +314,21 @@ bool KDPipeIODevice::Private::startWriterThread()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KDPipeIODevice::Private::emitReadyRead()
|
||||||
|
{
|
||||||
|
static int s_counter = 0;
|
||||||
|
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 leaving %d", this, counter );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
bool KDPipeIODevice::Private::doOpen( int fd_, Qt::HANDLE handle_, OpenMode mode_ ) {
|
bool KDPipeIODevice::Private::doOpen( int fd_, Qt::HANDLE handle_, OpenMode mode_ ) {
|
||||||
|
|
||||||
if ( q->isOpen() || fd_ < 0 )
|
if ( q->isOpen() || fd_ < 0 )
|
||||||
@ -323,13 +350,13 @@ bool KDPipeIODevice::Private::doOpen( int fd_, Qt::HANDLE handle_, OpenMode mode
|
|||||||
|
|
||||||
if ( mode_ & ReadOnly ) {
|
if ( mode_ & ReadOnly ) {
|
||||||
reader_.reset( new Reader( fd_, handle_ ) );
|
reader_.reset( new Reader( fd_, handle_ ) );
|
||||||
qDebug( "KDPipeIODevice::doOpen: created reader for fd %d", fd_ );
|
qDebug( "KDPipeIODevice::doOpen (%p): created reader (%p) for fd %d", this, reader_.get(), fd_ );
|
||||||
connect( reader_.get(), SIGNAL(readyRead()), q,
|
connect( reader_.get(), SIGNAL(readyRead()), this, SLOT(emitReadyRead()),
|
||||||
SIGNAL(readyRead()), Qt::QueuedConnection );
|
Qt::QueuedConnection );
|
||||||
}
|
}
|
||||||
if ( mode_ & WriteOnly ) {
|
if ( mode_ & WriteOnly ) {
|
||||||
writer_.reset( new Writer( fd_, handle_ ) );
|
writer_.reset( new Writer( fd_, handle_ ) );
|
||||||
qDebug( "KDPipeIODevice::doOpen: created writer for fd %d", fd_ );
|
qDebug( "KDPipeIODevice::doOpen (%p): created writer (%p) for fd %d", this, writer_.get(), fd_ );
|
||||||
connect( writer_.get(), SIGNAL(bytesWritten(qint64)), q, SIGNAL(bytesWritten(qint64)),
|
connect( writer_.get(), SIGNAL(bytesWritten(qint64)), q, SIGNAL(bytesWritten(qint64)),
|
||||||
Qt::QueuedConnection );
|
Qt::QueuedConnection );
|
||||||
}
|
}
|
||||||
@ -412,6 +439,8 @@ bool KDPipeIODevice::waitForBytesWritten( int msecs ) { KDAB_CHECK_THIS;
|
|||||||
if ( !w )
|
if ( !w )
|
||||||
return true;
|
return true;
|
||||||
LOCKED( w );
|
LOCKED( w );
|
||||||
|
qDebug( "KDPipeIODevice::waitForBytesWritten (%p,w=%p): entered locked area", this, w
|
||||||
|
);
|
||||||
return w->bufferEmpty() || w->error || w->bufferEmptyCondition.wait( &w->mutex, msecs ) ;
|
return w->bufferEmpty() || w->error || w->bufferEmptyCondition.wait( &w->mutex, msecs ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,17 +457,24 @@ bool KDPipeIODevice::waitForReadyRead( int msecs ) { KDAB_CHECK_THIS;
|
|||||||
return r->bytesInBuffer() != 0 || r->eof || r->error || r->bufferNotEmptyCondition.wait( &r->mutex, msecs ) ;
|
return r->bytesInBuffer() != 0 || r->eof || r->error || r->bufferNotEmptyCondition.wait( &r->mutex, msecs ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class TemporaryValue {
|
||||||
|
public:
|
||||||
|
TemporaryValue( T& var_, const T& tv ) : var( var_ ), oldValue( var_ ) { var = tv; }
|
||||||
|
~TemporaryValue() { var = oldValue; }
|
||||||
|
private:
|
||||||
|
T& var;
|
||||||
|
const T oldValue;
|
||||||
|
};
|
||||||
|
|
||||||
qint64 KDPipeIODevice::readData( char * data, qint64 maxSize ) { KDAB_CHECK_THIS;
|
qint64 KDPipeIODevice::readData( char * data, qint64 maxSize ) { KDAB_CHECK_THIS;
|
||||||
qDebug( "%p: KDPipeIODevice::readData: data=%p, maxSize=%lld", this, data, maxSize );
|
qDebug( "%p: KDPipeIODevice::readData: data=%p, maxSize=%lld", this, data, maxSize );
|
||||||
|
|
||||||
if ( maxSize == 0 )
|
|
||||||
return 0;
|
|
||||||
d->startReaderThread();
|
d->startReaderThread();
|
||||||
|
|
||||||
Reader * const r = d->reader;
|
Reader * const r = d->reader;
|
||||||
|
|
||||||
assert( r );
|
assert( r );
|
||||||
|
|
||||||
|
|
||||||
//assert( r->isRunning() ); // wrong (might be eof, error)
|
//assert( r->isRunning() ); // wrong (might be eof, error)
|
||||||
assert( data || maxSize == 0 );
|
assert( data || maxSize == 0 );
|
||||||
assert( maxSize >= 0 );
|
assert( maxSize >= 0 );
|
||||||
@ -455,10 +491,14 @@ qint64 KDPipeIODevice::readData( char * data, qint64 maxSize ) { KDAB_CHECK_THIS
|
|||||||
if ( bytesAvailable() > 0 )
|
if ( bytesAvailable() > 0 )
|
||||||
maxSize = std::min( maxSize, bytesAvailable() ); // don't block
|
maxSize = std::min( maxSize, bytesAvailable() ); // don't block
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCKED( r );
|
LOCKED( r );
|
||||||
if ( /* maxSize > 0 && */ r->bufferEmpty() && !r->error && !r->eof ) { // ### block on maxSize == 0?
|
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 );
|
qDebug( "%p: KDPipeIODevice::readData: waiting for bufferNotEmptyCondition", this );
|
||||||
|
r->readyReadSentCondition.wakeAll();
|
||||||
|
r->notInReadDataCondition.wakeAll();
|
||||||
r->bufferNotEmptyCondition.wait( &r->mutex );
|
r->bufferNotEmptyCondition.wait( &r->mutex );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -467,6 +507,7 @@ qint64 KDPipeIODevice::readData( char * data, qint64 maxSize ) { KDAB_CHECK_THIS
|
|||||||
// woken with an empty buffer must mean either EOF or error:
|
// woken with an empty buffer must mean either EOF or error:
|
||||||
assert( r->eof || r->error );
|
assert( r->eof || r->error );
|
||||||
r->eofShortCut = true;
|
r->eofShortCut = true;
|
||||||
|
r->notInReadDataCondition.wakeAll();
|
||||||
return r->eof ? 0 : -1 ;
|
return r->eof ? 0 : -1 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -474,6 +515,7 @@ qint64 KDPipeIODevice::readData( char * data, qint64 maxSize ) { KDAB_CHECK_THIS
|
|||||||
const qint64 bytesRead = r->readData( data, maxSize );
|
const qint64 bytesRead = r->readData( data, maxSize );
|
||||||
qDebug( "%p: KDPipeIODevice::readData: read %lld bytes", this, bytesRead );
|
qDebug( "%p: KDPipeIODevice::readData: read %lld bytes", this, bytesRead );
|
||||||
qDebug( "%p (fd=%d): KDPipeIODevice::readData: %s", this, d->fd, data );
|
qDebug( "%p (fd=%d): KDPipeIODevice::readData: %s", this, d->fd, data );
|
||||||
|
r->notInReadDataCondition.wakeAll();
|
||||||
return bytesRead;
|
return bytesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,9 +550,12 @@ qint64 KDPipeIODevice::writeData( const char * data, qint64 size ) { KDAB_CHECK_
|
|||||||
|
|
||||||
LOCKED( w );
|
LOCKED( w );
|
||||||
|
|
||||||
while ( !w->error && !w->bufferEmpty() )
|
while ( !w->error && !w->bufferEmpty() ) {
|
||||||
|
qDebug( "%p: KDPipeIODevice::writeData: wait for empty buffer", this );
|
||||||
w->bufferEmptyCondition.wait( &w->mutex );
|
w->bufferEmptyCondition.wait( &w->mutex );
|
||||||
|
qDebug( "%p: KDPipeIODevice::writeData: empty buffer signaled", this );
|
||||||
|
|
||||||
|
}
|
||||||
if ( w->error )
|
if ( w->error )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -529,10 +574,10 @@ qint64 Writer::writeData( const char * data, qint64 size ) {
|
|||||||
|
|
||||||
numBytesInBuffer = size;
|
numBytesInBuffer = size;
|
||||||
|
|
||||||
if ( !bufferEmpty() )
|
if ( !bufferEmpty() ) {
|
||||||
bufferNotEmptyCondition.wakeAll();
|
bufferNotEmptyCondition.wakeAll();
|
||||||
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KDPipeIODevice::Private::stopThreads()
|
void KDPipeIODevice::Private::stopThreads()
|
||||||
@ -550,6 +595,7 @@ void KDPipeIODevice::Private::stopThreads()
|
|||||||
r->cancel = true;
|
r->cancel = true;
|
||||||
// and wake it, so it can terminate:
|
// and wake it, so it can terminate:
|
||||||
r->bufferNotFullCondition.wakeAll();
|
r->bufferNotFullCondition.wakeAll();
|
||||||
|
r->readyReadSentCondition.wakeAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( Writer * & w = writer ) {
|
if ( Writer * & w = writer ) {
|
||||||
@ -563,7 +609,7 @@ void KDPipeIODevice::Private::stopThreads()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void KDPipeIODevice::close() { KDAB_CHECK_THIS;
|
void KDPipeIODevice::close() { KDAB_CHECK_THIS;
|
||||||
|
qDebug( "KDPipeIODevice::close(%p)", this );
|
||||||
if ( !isOpen() )
|
if ( !isOpen() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -571,12 +617,14 @@ void KDPipeIODevice::close() { KDAB_CHECK_THIS;
|
|||||||
emit aboutToClose();
|
emit aboutToClose();
|
||||||
d->stopThreads();
|
d->stopThreads();
|
||||||
|
|
||||||
#define waitAndDelete( t ) if ( t ) { t->wait(); delete t; t = 0; }
|
#define waitAndDelete( t ) if ( t ) { t->wait(); QThread* t2 = t; t = 0; delete t2; }
|
||||||
|
qDebug( "KPipeIODevice::close(%p): wait and closing writer %p", this, d->writer );
|
||||||
waitAndDelete( d->writer );
|
waitAndDelete( d->writer );
|
||||||
|
qDebug( "KPipeIODevice::close(%p): wait and closing reader %p", this, d->reader );
|
||||||
waitAndDelete( d->reader );
|
waitAndDelete( d->reader );
|
||||||
#undef waitAndDelete
|
#undef waitAndDelete
|
||||||
|
|
||||||
#ifdef Q_OS_WIN32
|
#ifdef Q_OS_WIN32
|
||||||
|
qDebug( "Closing handle" );
|
||||||
CloseHandle( d->handle );
|
CloseHandle( d->handle );
|
||||||
#else
|
#else
|
||||||
::close( d->fd );
|
::close( d->fd );
|
||||||
@ -598,18 +646,27 @@ void Reader::run() {
|
|||||||
|
|
||||||
while ( true ) {
|
while ( true ) {
|
||||||
|
|
||||||
while ( !cancel && bufferFull() ) {
|
if ( !bufferFull() && !bufferEmpty() ) {
|
||||||
bufferNotEmptyCondition.wakeAll();
|
qDebug( "%p: Reader::run: buffer no longer empty, waking everyone", this );
|
||||||
qDebug( "%p: Reader::run: buffer is full, going to sleep", this );
|
notifyReadyRead();
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( !cancel && bufferFull() ) {
|
||||||
|
bufferNotEmptyCondition.wakeAll();
|
||||||
|
notifyReadyRead();
|
||||||
|
if ( !bufferFull() )
|
||||||
|
break;
|
||||||
|
qDebug( "%p: Reader::run: buffer is full, going to sleep", this );
|
||||||
bufferNotFullCondition.wait( &mutex );
|
bufferNotFullCondition.wait( &mutex );
|
||||||
qDebug( "%p: Reader::run: woke up", this );
|
qDebug( "%p: Reader::run: woke up", this );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( cancel ) {
|
if ( cancel ) {
|
||||||
qDebug( "%p: Reader::run: detected cancel", this );
|
qDebug( "%p: Reader::run: detected cancel", this );
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ( rptr == wptr ) // optimize for larger chunks in case the buffer is empty
|
if ( rptr == wptr ) // optimize for larger chunks in case the buffer is empty
|
||||||
rptr = wptr = 0;
|
rptr = wptr = 0;
|
||||||
|
|
||||||
@ -630,9 +687,11 @@ void Reader::run() {
|
|||||||
if ( !ok ) {
|
if ( !ok ) {
|
||||||
errorCode = static_cast<int>( GetLastError() );
|
errorCode = static_cast<int>( GetLastError() );
|
||||||
if ( errorCode == ERROR_BROKEN_PIPE ) {
|
if ( errorCode == ERROR_BROKEN_PIPE ) {
|
||||||
|
assert( numRead == 0 );
|
||||||
qDebug( "%p: Reader::run: got eof (broken pipe)", this );
|
qDebug( "%p: Reader::run: got eof (broken pipe)", this );
|
||||||
eof = true;
|
eof = true;
|
||||||
} else {
|
} else {
|
||||||
|
assert( numRead == 0 );
|
||||||
qDebug( "%p: Reader::run: got error: %s (%d)", this, strerror( errorCode ), errorCode );
|
qDebug( "%p: Reader::run: got error: %s (%d)", this, strerror( errorCode ), errorCode );
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
@ -668,16 +727,33 @@ void Reader::run() {
|
|||||||
qDebug( "%p: Reader::run: buffer before: rptr=%4d, wptr=%4d", this, rptr, wptr );
|
qDebug( "%p: Reader::run: buffer before: rptr=%4d, wptr=%4d", this, rptr, wptr );
|
||||||
wptr = ( wptr + numRead ) % sizeof buffer;
|
wptr = ( wptr + numRead ) % sizeof buffer;
|
||||||
qDebug( "%p: Reader::run: buffer after: rptr=%4d, wptr=%4d", this, rptr, wptr );
|
qDebug( "%p: Reader::run: buffer after: rptr=%4d, wptr=%4d", this, rptr, wptr );
|
||||||
if ( !bufferEmpty() ) {
|
|
||||||
qDebug( "%p: Reader::run: buffer no longer empty, waking everyone", this );
|
|
||||||
bufferNotEmptyCondition.wakeAll();
|
|
||||||
emit readyRead();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
leave:
|
leave:
|
||||||
qDebug( "%p: Reader::run: terminating", this );
|
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();
|
bufferNotEmptyCondition.wakeAll();
|
||||||
|
if ( inReadData ) {
|
||||||
|
qDebug( "notifyReadyRead: inReadData: waiting" );
|
||||||
|
notInReadDataCondition.wait( &mutex );
|
||||||
|
}
|
||||||
|
if ( cancel || ( !eof && !error && bufferEmpty() ) )
|
||||||
|
return;
|
||||||
|
qDebug( "readyReadData: actually emit signal" );
|
||||||
emit readyRead();
|
emit readyRead();
|
||||||
|
bufferNotEmptyCondition.wakeAll();
|
||||||
|
readyReadSentCondition.wait( &mutex );
|
||||||
|
bufferNotEmptyCondition.wakeAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Writer::run() {
|
void Writer::run() {
|
||||||
@ -692,9 +768,11 @@ void Writer::run() {
|
|||||||
while ( true ) {
|
while ( true ) {
|
||||||
|
|
||||||
while ( !cancel && bufferEmpty() ) {
|
while ( !cancel && bufferEmpty() ) {
|
||||||
bufferEmptyCondition.wakeAll();
|
qDebug( "%p: Writer::run: buffer is empty, wake bufferEmptyCond listeners", this );
|
||||||
|
bufferEmptyCondition.wakeAll();
|
||||||
|
emit bytesWritten( 0 );
|
||||||
qDebug( "%p: Writer::run: buffer is empty, going to sleep", this );
|
qDebug( "%p: Writer::run: buffer is empty, going to sleep", this );
|
||||||
bufferNotEmptyCondition.wait( &mutex );
|
bufferNotEmptyCondition.wait( &mutex );
|
||||||
qDebug( "%p: Writer::run: woke up", this );
|
qDebug( "%p: Writer::run: woke up", this );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -707,10 +785,12 @@ void Writer::run() {
|
|||||||
|
|
||||||
qDebug( "%p: Writer::run: Trying to write %u bytes", this, numBytesInBuffer );
|
qDebug( "%p: Writer::run: Trying to write %u bytes", this, numBytesInBuffer );
|
||||||
qint64 totalWritten = 0;
|
qint64 totalWritten = 0;
|
||||||
do {
|
do {
|
||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
#ifdef Q_OS_WIN32
|
#ifdef Q_OS_WIN32
|
||||||
DWORD numWritten;
|
DWORD numWritten;
|
||||||
|
qDebug( "%p (fd=%d): Writer::run: buffer before WriteFile (numBytes=%lld): %s:", this, fd, numBytesInBuffer, buffer );
|
||||||
|
qDebug( "%p (fd=%d): Writer::run: Going into WriteFile", this, fd );
|
||||||
if ( !WriteFile( handle, buffer + totalWritten, numBytesInBuffer - totalWritten, &numWritten, 0 ) ) {
|
if ( !WriteFile( handle, buffer + totalWritten, numBytesInBuffer - totalWritten, &numWritten, 0 ) ) {
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
errorCode = static_cast<int>( GetLastError() );
|
errorCode = static_cast<int>( GetLastError() );
|
||||||
@ -732,6 +812,8 @@ void Writer::run() {
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
qDebug( "%p (fd=%d): Writer::run: buffer after WriteFile (numBytes=%lld): %s:", this, fd, numBytesInBuffer,
|
||||||
|
buffer );
|
||||||
totalWritten += numWritten;
|
totalWritten += numWritten;
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
} while ( totalWritten < numBytesInBuffer );
|
} while ( totalWritten < numBytesInBuffer );
|
||||||
@ -739,12 +821,15 @@ void Writer::run() {
|
|||||||
qDebug( "%p: Writer::run: wrote %lld bytes", this, totalWritten );
|
qDebug( "%p: Writer::run: wrote %lld bytes", this, totalWritten );
|
||||||
|
|
||||||
numBytesInBuffer = 0;
|
numBytesInBuffer = 0;
|
||||||
|
|
||||||
|
qDebug( "%p: Writer::run: buffer is empty, wake bufferEmptyCond listeners", this );
|
||||||
bufferEmptyCondition.wakeAll();
|
bufferEmptyCondition.wakeAll();
|
||||||
emit bytesWritten( totalWritten );
|
emit bytesWritten( totalWritten );
|
||||||
}
|
}
|
||||||
leave:
|
leave:
|
||||||
qDebug( "%p: Writer::run: terminating", this );
|
qDebug( "%p: Writer::run: terminating", this );
|
||||||
numBytesInBuffer = 0;
|
numBytesInBuffer = 0;
|
||||||
|
qDebug( "%p: Writer::run: buffer is empty, wake bufferEmptyCond listeners", this );
|
||||||
bufferEmptyCondition.wakeAll();
|
bufferEmptyCondition.wakeAll();
|
||||||
emit bytesWritten( 0 );
|
emit bytesWritten( 0 );
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
** Meta object code from reading C++ file 'kdpipeiodevice.cpp'
|
** Meta object code from reading C++ file 'kdpipeiodevice.cpp'
|
||||||
**
|
**
|
||||||
** Created: Wed Sep 26 11:05:05 2007
|
** Created: Mon Oct 1 16:08:44 2007
|
||||||
** by: The Qt Meta Object Compiler version 59 (Qt 4.3.1)
|
** by: The Qt Meta Object Compiler version 59 (Qt 4.3.1)
|
||||||
**
|
**
|
||||||
** WARNING! All changes made in this file will be lost!
|
** WARNING! All changes made in this file will be lost!
|
||||||
@ -136,15 +136,18 @@ static const uint qt_meta_data_KDPipeIODevice__Private[] = {
|
|||||||
1, // revision
|
1, // revision
|
||||||
0, // classname
|
0, // classname
|
||||||
0, 0, // classinfo
|
0, 0, // classinfo
|
||||||
0, 0, // methods
|
1, 10, // methods
|
||||||
0, 0, // properties
|
0, 0, // properties
|
||||||
0, 0, // enums/sets
|
0, 0, // enums/sets
|
||||||
|
|
||||||
|
// slots: signature, parameters, type, tag, flags
|
||||||
|
25, 24, 24, 24, 0x0a,
|
||||||
|
|
||||||
0 // eod
|
0 // eod
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char qt_meta_stringdata_KDPipeIODevice__Private[] = {
|
static const char qt_meta_stringdata_KDPipeIODevice__Private[] = {
|
||||||
"KDPipeIODevice::Private\0"
|
"KDPipeIODevice::Private\0\0emitReadyRead()\0"
|
||||||
};
|
};
|
||||||
|
|
||||||
const QMetaObject KDPipeIODevice::Private::staticMetaObject = {
|
const QMetaObject KDPipeIODevice::Private::staticMetaObject = {
|
||||||
@ -170,5 +173,11 @@ int KDPipeIODevice::Private::qt_metacall(QMetaObject::Call _c, int _id, void **_
|
|||||||
_id = QObject::qt_metacall(_c, _id, _a);
|
_id = QObject::qt_metacall(_c, _id, _a);
|
||||||
if (_id < 0)
|
if (_id < 0)
|
||||||
return _id;
|
return _id;
|
||||||
|
if (_c == QMetaObject::InvokeMetaMethod) {
|
||||||
|
switch (_id) {
|
||||||
|
case 0: emitReadyRead(); break;
|
||||||
|
}
|
||||||
|
_id -= 1;
|
||||||
|
}
|
||||||
return _id;
|
return _id;
|
||||||
}
|
}
|
||||||
|
@ -117,9 +117,11 @@ find_channel (int fd, int create)
|
|||||||
BUFLEN. The printable version is the representation on the command
|
BUFLEN. The printable version is the representation on the command
|
||||||
line that the child process expects. */
|
line that the child process expects. */
|
||||||
int
|
int
|
||||||
_gpgme_io_fd2str (char *buf, int buflen, int fd)
|
_gpgme_io_fd2str (char *buf, int buflen, int fd_)
|
||||||
{
|
{
|
||||||
return snprintf (buf, buflen, "%ld", (long) _get_osfhandle (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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -627,6 +629,14 @@ gpgme_get_giochannel (int fd)
|
|||||||
int
|
int
|
||||||
_gpgme_io_dup (int fd)
|
_gpgme_io_dup (int fd)
|
||||||
{
|
{
|
||||||
|
DeviceEntry* const existing = iodevice_table[fd];
|
||||||
|
if ( existing )
|
||||||
|
existing->ref();
|
||||||
|
else
|
||||||
|
find_channel( fd, /*create=*/1 );
|
||||||
|
return fd;
|
||||||
|
|
||||||
|
#if 0
|
||||||
const int new_fd = _dup( fd );
|
const int new_fd = _dup( fd );
|
||||||
iodevice_table[new_fd] = iodevice_table[fd];
|
iodevice_table[new_fd] = iodevice_table[fd];
|
||||||
if ( iodevice_table[new_fd] )
|
if ( iodevice_table[new_fd] )
|
||||||
@ -634,5 +644,6 @@ _gpgme_io_dup (int fd)
|
|||||||
else
|
else
|
||||||
find_channel( new_fd, /*create=*/1 );
|
find_channel( new_fd, /*create=*/1 );
|
||||||
return new_fd;
|
return new_fd;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user