|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "assert.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Qt includes
|
|
Toshihiro Shimizu |
890ddd |
#include <qdatastream></qdatastream>
|
|
Toshihiro Shimizu |
890ddd |
#include <qdebug></qdebug>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tipc.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tipcmsg.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tipcsrvP.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tipcsrv.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//*******************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Diagnostics stuff
|
|
Toshihiro Shimizu |
890ddd |
//*******************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//#define TIPC_DEBUG
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef TIPC_DEBUG
|
|
Toshihiro Shimizu |
890ddd |
#define tipc_debug(expr) expr
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
#define tipc_debug(expr)
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef TIPC_DEBUG
|
|
Toshihiro Shimizu |
890ddd |
#include <qtime></qtime>
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//*******************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// tipc::SocketListener implementation
|
|
Toshihiro Shimizu |
890ddd |
//*******************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void tipc::SocketController::onReadyRead() {
|
|
Shinya Kitaoka |
120a6e |
// Deliver the message to the server for interpretation.
|
|
Shinya Kitaoka |
120a6e |
m_server->dispatchSocket(m_socket);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void tipc::SocketController::onDisconnected() {
|
|
Shinya Kitaoka |
120a6e |
m_socket->QObject::disconnect(SIGNAL(readyRead()));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Auto-delete this
|
|
Shinya Kitaoka |
120a6e |
delete this;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//*******************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Server implementation
|
|
Toshihiro Shimizu |
890ddd |
//*******************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
tipc::Server::Server() : m_lock(false) {
|
|
Shinya Kitaoka |
120a6e |
connect(this, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Add default parsers
|
|
Shinya Kitaoka |
120a6e |
addParser(new DefaultMessageParser<shmem_request>);</shmem_request>
|
|
Shinya Kitaoka |
120a6e |
addParser(new DefaultMessageParser<shmem_release>);</shmem_release>
|
|
Shinya Kitaoka |
120a6e |
addParser(new DefaultMessageParser<tmpfile_request>);</tmpfile_request>
|
|
Shinya Kitaoka |
120a6e |
addParser(new DefaultMessageParser<tmpfile_release>);</tmpfile_release>
|
|
Shinya Kitaoka |
120a6e |
addParser(new DefaultMessageParser<quit_on_error>);</quit_on_error>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
tipc::Server::~Server() {
|
|
Shinya Kitaoka |
120a6e |
// Release parsers
|
|
Shinya Kitaoka |
120a6e |
QHash<qstring, *="" messageparser="">::iterator it;</qstring,>
|
|
Shinya Kitaoka |
120a6e |
for (it = m_parsers.begin(); it != m_parsers.end(); ++it) delete it.value();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void tipc::Server::addParser(MessageParser *parser) {
|
|
Shinya Kitaoka |
120a6e |
m_parsers.insert(parser->header(), parser);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void tipc::Server::removeParser(QString header) {
|
|
Shinya Kitaoka |
120a6e |
MessageParser *parser = m_parsers.take(header);
|
|
Shinya Kitaoka |
120a6e |
if (parser) delete parser;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void tipc::Server::onNewConnection() {
|
|
Shinya Kitaoka |
120a6e |
tipc_debug(qDebug("new connection"));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Accept the connection
|
|
Shinya Kitaoka |
120a6e |
QLocalSocket *socket = nextPendingConnection();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Allocate a controller for the socket
|
|
Shinya Kitaoka |
120a6e |
SocketController *controller = new SocketController;
|
|
Shinya Kitaoka |
120a6e |
controller->m_server = this;
|
|
Shinya Kitaoka |
120a6e |
controller->m_socket = socket;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Connect the controller to the socket's signals
|
|
Shinya Kitaoka |
120a6e |
connect(socket, SIGNAL(readyRead()), controller, SLOT(onReadyRead()));
|
|
Shinya Kitaoka |
120a6e |
connect(socket, SIGNAL(disconnected()), controller, SLOT(onDisconnected()));
|
|
Shinya Kitaoka |
120a6e |
connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
|
|
Shinya Kitaoka |
120a6e |
connect(socket, SIGNAL(error(QLocalSocket::LocalSocketError)), this,
|
|
Shinya Kitaoka |
120a6e |
SLOT(onError(QLocalSocket::LocalSocketError)));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void tipc::Server::onError(QLocalSocket::LocalSocketError error) {
|
|
Shinya Kitaoka |
120a6e |
tipc_debug(qDebug() << "Server error #" << error << ": " << errorString());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void tipc::Server::dispatchSocket(QLocalSocket *socket) {
|
|
Shinya Kitaoka |
120a6e |
// The lock is established when a message is currently being processed.
|
|
Shinya Kitaoka |
120a6e |
// Returning if the lock is set avoids having recursive message processing;
|
|
Shinya Kitaoka |
120a6e |
// which is possible if a parser expects further message packets.
|
|
Shinya Kitaoka |
120a6e |
if (m_lock) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
tipc::Stream stream(socket);
|
|
Shinya Kitaoka |
120a6e |
QString header;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
while (socket->bytesAvailable() > 0) {
|
|
Shinya Kitaoka |
120a6e |
if (!stream.messageReady()) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Message msg;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
stream >> msg;
|
|
Shinya Kitaoka |
120a6e |
msg >> header;
|
|
Shinya Kitaoka |
120a6e |
assert(!header.isEmpty());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
tipc_debug(qDebug() << header << endl);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QHash<qstring, *="" messageparser="">::iterator it = m_parsers.find(header);</qstring,>
|
|
Shinya Kitaoka |
120a6e |
if (it == m_parsers.end()) {
|
|
Shinya Kitaoka |
120a6e |
tipc_debug(qDebug() << "Error: Unrecognized command" << endl);
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_lock = true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
MessageParser *parser = it.value();
|
|
Shinya Kitaoka |
120a6e |
parser->m_socket = socket;
|
|
Shinya Kitaoka |
120a6e |
parser->m_stream = &stream;
|
|
Shinya Kitaoka |
120a6e |
parser->operator()(msg);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_lock = false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// The Message has been read and processed. Send the reply.
|
|
Shinya Kitaoka |
120a6e |
if (msg.ba().size() > 0) stream << msg;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|