Source Code (Use browser search to find items of interest.)
Class Index
kdelibs'Connection (./kdelibs/kio/connection.h:46)
class Connection : public QObject
{
Q_OBJECT
public:
Connection();
virtual ~Connection();
void init(KSocket *sock);
void connect(QObject *receiver = 0, const char *member = 0);
void close();
int fd_from() const { return fd_in; }
void init(int fd_in, int fd_out);
bool inited() const { return (fd_in != 0) && (f_out != 0); }
// send (queues the command to be sent)
void send(int cmd, const QByteArray &arr = QByteArray());
// send (without queue)
bool sendnow( int _cmd, const QByteArray &data );
/**
* Receive data
*
* @return >=0 indicates the received data size upon success
* -1 indicates error
*/
int read( int* _cmd, QByteArray & );
/**
* Don't handle incoming data until resumed
*/
void suspend();
/**
* Resume handling of incoming data
*/
void resume();
void queueOnly(bool queue);
/**
* @internal
*/
static void sigpipe_handler(int);
protected slots:
void dequeue();
protected:
private:
bool queueonly;
int fd_in;
FILE *f_out;
KSocket *socket;
QSocketNotifier *notifier;
QObject *receiver;
const char *member;
QList<Task> tasks;
int unqueuedTasks;
bool m_suspended;
};
};
kdelibs'Connection::Connection() (./kdelibs/arts/mcop/connection.cc:27)
Connection::Connection() :_refCnt(1)
{
_connState = unknown;
}
kdelibs'Connection::~Connection() (./kdelibs/arts/mcop/connection.cc:32)
Connection::~Connection()
{
assert(_refCnt == 0);
}
kdelibs'Connection::_copy() (./kdelibs/arts/mcop/connection.cc:37)
void Connection::_copy()
{
_refCnt++;
}
kdelibs'Connection::_release() (./kdelibs/arts/mcop/connection.cc:42)
void Connection::_release()
{
assert(_refCnt > 0);
_refCnt--;
if(_refCnt == 0)
delete this;
}
kdelibs'Connection::initReceive() (./kdelibs/arts/mcop/connection.cc:50)
void Connection::initReceive()
{
rcbuf = 0;
receiveHeader = true;
remaining = 12;
}
kdelibs'Connection::receive() (./kdelibs/arts/mcop/connection.cc:57)
void Connection::receive(unsigned char *data, long len)
{
if(len > remaining)
{
unsigned char *data2 = data+remaining;
long len2 = len-remaining;
receive(data,remaining);
/* This could be optimized to a non recursive thing (fixme?) */
receive(data2,len2);
return;
}
// get a buffer for the incoming message:
if(!rcbuf) rcbuf = new Buffer;
remaining -= len;
rcbuf->write(data,len);
#ifdef DEBUG_IO
printf("read %ld bytes\n",len);
#endif
if(remaining == 0)
{
if(receiveHeader)
{
long mcopMagic;
mcopMagic = rcbuf->readLong();
remaining = rcbuf->readLong() - 12;
messageType = rcbuf->readLong();
if(_connState != Connection::established && remaining >= 4096)
{
/*
* don't accept large amounts of data on unauthenticated
* connections
*/
remaining = 0;
}
if(mcopMagic == MCOP_MAGIC)
{
// do we need to receive more data (message body?)
if(remaining)
{
receiveHeader = false;
}
else
{
Buffer *received = rcbuf;
initReceive();
Dispatcher::the()->handle(this,received,messageType);
}
}
else
{
initReceive();
Dispatcher::the()->handleCorrupt(this);
}
}
else
{
Buffer *received = rcbuf;
/*
* it's important to prepare to receive new messages *before*
* calling Dispatcher::the()->handle(...), as handle may
* get into an I/O situation (e.g. when doing an invocation
* itself), and we may receive more messages while handle is
* running
*/
initReceive();
// rcbuf is consumed by the dispatcher
Dispatcher::the()->handle(this,received,messageType);
}
}
}
kdelibs'Connection::Connection() (./kdelibs/kio/connection.cpp:51)
Connection::Connection()
{
signal( SIGPIPE, sigpipe_handler );
f_out = 0;
fd_in = 0;
socket = 0;
notifier = 0;
receiver = 0;
member = 0;
queueonly = false;
m_suspended = false;
unqueuedTasks = 0;
}
kdelibs'Connection::~Connection() (./kdelibs/kio/connection.cpp:65)
Connection::~Connection()
{
close();
}
kdelibs'Connection::suspend() (./kdelibs/kio/connection.cpp:70)
void Connection::suspend()
{
m_suspended = true;
if (notifier)
notifier->setEnabled(false);
}
kdelibs'Connection::resume() (./kdelibs/kio/connection.cpp:77)
void Connection::resume()
{
m_suspended = false;
if (notifier)
notifier->setEnabled(true);
}
kdelibs'Connection::close() (./kdelibs/kio/connection.cpp:84)
void Connection::close()
{
delete notifier;
notifier = 0;
delete socket;
socket = 0;
if (f_out)
fclose(f_out);
f_out = 0;
fd_in = 0;
}
kdelibs'Connection::send() (./kdelibs/kio/connection.cpp:96)
void Connection::send(int cmd, const QByteArray& data)
{
if (!inited() || queueonly || tasks.count() > 0) {
kdDebug(7017) << "pending queue " << cmd << endl;
Task *task = new Task();
task->cmd = cmd;
task->data = data;
tasks.append(task);
} else {
sendnow( cmd, data );
}
if (inited() && tasks.count() > 0 && !queueonly)
QTimer::singleShot(100, this, SLOT(dequeue()));
}
kdelibs'Connection::queueOnly() (./kdelibs/kio/connection.cpp:112)
void Connection::queueOnly(bool queue) {
unqueuedTasks = tasks.count();
kdDebug(7017) << "setting queueOnly to " << queue << endl;
queueonly = queue;
dequeue();
}
kdelibs'Connection::dequeue() (./kdelibs/kio/connection.cpp:119)
void Connection::dequeue()
{
if (tasks.count() == 0 || !inited() || (queueonly && unqueuedTasks == 0))
return;
kdDebug(7017) << "dequeue" << endl;
tasks.first();
Task *task = tasks.take();
sendnow( task->cmd, task->data );
delete task;
if (queueonly)
unqueuedTasks--;
if (tasks.count() > 0 && (!queueonly || unqueuedTasks > 0))
QTimer::singleShot(100, this, SLOT(dequeue()));
}
kdelibs'Connection::init() (./kdelibs/kio/connection.cpp:139)
void Connection::init(int _fd_in, int fd_out)
{
fd_in = _fd_in;
f_out = fdopen( fd_out, "wb" );
}
kdelibs'Connection::init() (./kdelibs/kio/connection.cpp:145)
void Connection::init(KSocket *sock)
{
delete notifier;
notifier = 0;
delete socket;
socket = sock;
fd_in = socket->socket();
f_out = fdopen( socket->socket(), "wb" );
if (receiver && fd_in) {
notifier = new QSocketNotifier(fd_in, QSocketNotifier::Read);
if ( m_suspended )
suspend();
QObject::connect(notifier, SIGNAL(activated(int)), receiver, member);
}
dequeue();
}
kdelibs'Connection::connect() (./kdelibs/kio/connection.cpp:162)
void Connection::connect(QObject *_receiver, const char *_member)
{
receiver = _receiver;
member = _member;
delete notifier;
notifier = 0;
if (receiver && fd_in) {
notifier = new QSocketNotifier(fd_in, QSocketNotifier::Read);
if ( m_suspended )
suspend();
QObject::connect(notifier, SIGNAL(activated(int)), receiver, member);
}
}
kdelibs'Connection::sendnow() (./kdelibs/kio/connection.cpp:176)
bool Connection::sendnow( int _cmd, const QByteArray &data )
{
if (f_out == 0) {
kdDebug(7017) << "write: not yet inited." << endl;
return false;
}
kdDebug(7017) << "sendnow " << _cmd << endl;
static char buffer[ 64 ];
sprintf( buffer, "%6x_%2x_", data.size(), _cmd );
size_t n = fwrite( buffer, 1, 10, f_out );
if ( n != 10 ) {
kdError(7017) << "Could not send header" << endl;
return false;
}
n = fwrite( data.data(), 1, data.size(), f_out );
if ( n != data.size() ) {
kdError(7017) << "Could not write data" << endl;
return false;
}
fflush( f_out );
return true;
}
kdelibs'Connection::read() (./kdelibs/kio/connection.cpp:207)
int Connection::read( int* _cmd, QByteArray &data )
{
kdDebug(7017) << "read\n";
if (!fd_in) {
kdDebug(7017) << "read: not yet inited" << endl;
return -1;
}
static char buffer[ 10 ];
again1:
ssize_t n = ::read( fd_in, buffer, 10);
if ( n == -1 && errno == EINTR )
goto again1;
if ( n == -1) {
kdError(7017) << "Header read failed, errno=" << errno << endl;
}
if ( n != 10 ) {
if ( n ) // 0 indicates end of file
kdError(7017) << "Header has invalid size (" << n << ")" << endl;
return -1;
}
buffer[ 6 ] = 0;
buffer[ 9 ] = 0;
char *p = buffer;
while( *p == ' ' ) p++;
long int len = strtol( p, 0L, 16 );
p = buffer + 7;
while( *p == ' ' ) p++;
long int cmd = strtol( p, 0L, 16 );
kdDebug(7017) << "read cmd " << cmd << endl;
data.resize( len );
if ( len > 0L ) {
int bytesToGo = len;
int bytesRead = 0;
do {
n = ::read(fd_in, data.data()+bytesRead, bytesToGo);
if (n == -1) {
if (errno == EINTR)
continue;
kdError(7017) << "Data read failed, errno=" << errno << endl;
return -1;
}
if (n != bytesToGo) {
kdDebug(7017) << "Not enough data read (" << n << " instead of " << bytesToGo << ") cmd=" << cmd << "d" << endl;
}
bytesRead += n;
bytesToGo -= n;
}
while(bytesToGo);
}
*_cmd = cmd;
kdDebug(7017) << "finished reading cmd " << cmd << endl;
return len;
}
kdelibs'Connection::sigpipe_handler() (./kdelibs/kio/connection.cpp:275)
void Connection::sigpipe_handler(int)
{
kdDebug() << "*** SIGPIPE ***" << endl;
// Do nothing.
// dispatch will return false and that will trigger ERR_SLAVE_DIED in slave.cpp
// (or connection with app lost if this connection is in a slave)
}