X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcommon%2Fsignalproxy.cpp;h=ac39e3640b6a22117bb24e1bd24585536a232e48;hp=a7387151a375644eaaca4a4cb2a956aa218314e1;hb=dfcf836c5f1f57cadcdbea5c5a7a7034d21ce332;hpb=27de4d2719454c4deb5f6e24b82bdd8991e45260 diff --git a/src/common/signalproxy.cpp b/src/common/signalproxy.cpp index a7387151..ac39e364 100644 --- a/src/common/signalproxy.cpp +++ b/src/common/signalproxy.cpp @@ -120,7 +120,7 @@ void SignalProxy::SignalRelay::detachSignal(QObject *sender, int signalId) { if(slotIter->sender == sender && (signalId == -1 || slotIter->signalId == signalId)) { slotIter = _slots.erase(slotIter); if(signalId != -1) - break; + break; } else { slotIter++; } @@ -146,12 +146,12 @@ int SignalProxy::SignalRelay::qt_metacall(QMetaObject::Call _c, int _id, void ** const QList &argTypes = eMeta->argTypes(signal.signalId); for(int i = 0; i < argTypes.size(); i++) { - if(argTypes[i] == 0) { - qWarning() << "SignalRelay::qt_metacall(): received invalid data for argument number" << i << "of signal" << QString("%1::%2").arg(caller->metaObject()->className()).arg(caller->metaObject()->method(_id).signature()); - qWarning() << " - make sure all your data types are known by the Qt MetaSystem"; - return _id; - } - params << QVariant(argTypes[i], _a[i+1]); + if(argTypes[i] == 0) { + qWarning() << "SignalRelay::qt_metacall(): received invalid data for argument number" << i << "of signal" << QString("%1::%2").arg(caller->metaObject()->className()).arg(caller->metaObject()->method(_id).signature()); + qWarning() << " - make sure all your data types are known by the Qt MetaSystem"; + return _id; + } + params << QVariant(argTypes[i], _a[i+1]); } proxy()->dispatchSignal(SignalProxy::RpcCall, params); @@ -167,7 +167,7 @@ int SignalProxy::SignalRelay::qt_metacall(QMetaObject::Call _c, int _id, void ** void SignalProxy::IODevicePeer::dispatchSignal(const RequestType &requestType, const QVariantList ¶ms) { QVariantList packedFunc; packedFunc << (qint16)requestType - << params; + << params; dispatchPackedFunc(QVariant(packedFunc)); } @@ -209,7 +209,9 @@ void SignalProxy::SignalProxyPeer::dispatchSignal(const RequestType &requestType // SignalProxy // ================================================== SignalProxy::SignalProxy(QObject* parent) - : QObject(parent) + : QObject(parent), + _heartBeatInterval(30), + _maxHeartBeatCount(2) { setProxyMode(Client); init(); @@ -231,16 +233,17 @@ SignalProxy::SignalProxy(ProxyMode mode, QIODevice* device, QObject* parent) } SignalProxy::~SignalProxy() { - QList syncObjects; QHash::iterator classIter = _syncSlave.begin(); while(classIter != _syncSlave.end()) { - syncObjects << classIter->values(); + ObjectId::iterator objIter = classIter->begin(); + while(objIter != classIter->end()) { + SyncableObject *obj = objIter.value(); + objIter = classIter->erase(objIter); + obj->stopSynchronize(this); + } classIter++; } _syncSlave.clear(); - foreach(SyncableObject *obj, syncObjects) { - obj->stopSynchronize(this); - } removeAllPeers(); } @@ -251,8 +254,8 @@ void SignalProxy::setProxyMode(ProxyMode mode) { if((*peer)->type() != AbstractPeer::IODevicePeer) { IODevicePeer *ioPeer = static_cast(*peer); if(ioPeer->isOpen()) { - qWarning() << "SignalProxy: Cannot change proxy mode while connected"; - return; + qWarning() << "SignalProxy: Cannot change proxy mode while connected"; + return; } } if((*peer)->type() != AbstractPeer::SignalProxyPeer) { @@ -272,7 +275,9 @@ void SignalProxy::setProxyMode(ProxyMode mode) { void SignalProxy::init() { _signalRelay = new SignalRelay(this); connect(&_heartBeatTimer, SIGNAL(timeout()), this, SLOT(sendHeartBeat())); - _heartBeatTimer.start(30 * 1000); + setHeartBeatInterval(30); + setMaxHeartBeatCount(2); + _heartBeatTimer.start(); _secure = false; updateSecureState(); } @@ -323,6 +328,17 @@ bool SignalProxy::addPeer(QIODevice* iodev) { return true; } +void SignalProxy::setHeartBeatInterval(int secs) { + if(secs != _heartBeatInterval) { + _heartBeatInterval = secs; + _heartBeatTimer.setInterval(secs * 1000); + } +} + +void SignalProxy::setMaxHeartBeatCount(int max) { + _maxHeartBeatCount = max; +} + bool SignalProxy::addPeer(SignalProxy* proxy) { if(!proxy) return false; @@ -414,10 +430,6 @@ void SignalProxy::renameObject(const SyncableObject *obj, const QString &newname } void SignalProxy::objectRenamed(const QByteArray &classname, const QString &newname, const QString &oldname) { - qDebug() << "SignalProxy::objectRenamed" << classname << newname << oldname; - if(proxyMode() == Server) - return; - if(_syncSlave.contains(classname) && _syncSlave[classname].contains(oldname) && oldname != newname) { SyncableObject *obj = _syncSlave[classname][newname] = _syncSlave[classname].take(oldname); requestInit(obj); @@ -540,11 +552,11 @@ void SignalProxy::dispatchSignal(const RequestType &requestType, const QVariantL switch((*peer)->type()) { case AbstractPeer::IODevicePeer: { - IODevicePeer *ioPeer = static_cast(*peer); - if(ioPeer->isOpen()) - ioPeer->dispatchPackedFunc(packedFunc); - else - QCoreApplication::postEvent(this, new RemovePeerEvent(peer.key())); + IODevicePeer *ioPeer = static_cast(*peer); + if(ioPeer->isOpen()) + ioPeer->dispatchPackedFunc(packedFunc); + else + QCoreApplication::postEvent(this, new RemovePeerEvent(peer.key())); } break; case AbstractPeer::SignalProxyPeer: @@ -637,7 +649,7 @@ void SignalProxy::handleSync(AbstractPeer *sender, QVariantList params) { if(!_syncSlave.contains(className) || !_syncSlave[className].contains(objectName)) { qWarning() << QString("no registered receiver for sync call: %1::%2 (objectName=\"%3\"). Params are:").arg(QString(className)).arg(QString(slot)).arg(objectName) - << params; + << params; return; } @@ -645,7 +657,7 @@ void SignalProxy::handleSync(AbstractPeer *sender, QVariantList params) { ExtendedMetaObject *eMeta = extendedMetaObject(receiver); if(!eMeta->slotMap().contains(slot)) { qWarning() << QString("no matching slot for sync call: %1::%2 (objectName=\"%3\"). Params are:").arg(QString(className)).arg(QString(slot)).arg(objectName) - << params; + << params; return; } @@ -666,8 +678,8 @@ void SignalProxy::handleSync(AbstractPeer *sender, QVariantList params) { int receiverId = eMeta->receiveMap()[slotId]; QVariantList returnParams; returnParams << className - << objectName - << eMeta->methodName(receiverId); + << objectName + << eMeta->methodName(receiverId); //QByteArray(receiver->metaObject()->method(receiverId).signature()); if(eMeta->argTypes(receiverId).count() > 1) returnParams << params; @@ -682,7 +694,7 @@ void SignalProxy::handleSync(AbstractPeer *sender, QVariantList params) { void SignalProxy::handleInitRequest(AbstractPeer *sender, const QVariantList ¶ms) { if(params.count() != 2) { qWarning() << "SignalProxy::handleInitRequest() received initRequest with invalid param Count:" - << params; + << params; return; } @@ -691,13 +703,13 @@ void SignalProxy::handleInitRequest(AbstractPeer *sender, const QVariantList &pa if(!_syncSlave.contains(className)) { qWarning() << "SignalProxy::handleInitRequest() received initRequest for unregistered Class:" - << className; + << className; return; } if(!_syncSlave[className].contains(objectName)) { qWarning() << "SignalProxy::handleInitRequest() received initRequest for unregistered Object:" - << className << objectName; + << className << objectName; return; } @@ -705,8 +717,8 @@ void SignalProxy::handleInitRequest(AbstractPeer *sender, const QVariantList &pa QVariantList params_; params_ << className - << objectName - << initData(obj); + << objectName + << initData(obj); sender->dispatchSignal(InitData, params_); } @@ -715,7 +727,7 @@ void SignalProxy::handleInitData(AbstractPeer *sender, const QVariantList ¶m Q_UNUSED(sender) if(params.count() != 3) { qWarning() << "SignalProxy::handleInitData() received initData with invalid param Count:" - << params; + << params; return; } @@ -725,13 +737,13 @@ void SignalProxy::handleInitData(AbstractPeer *sender, const QVariantList ¶m if(!_syncSlave.contains(className)) { qWarning() << "SignalProxy::handleInitData() received initData for unregistered Class:" - << className; + << className; return; } if(!_syncSlave[className].contains(objectName)) { qWarning() << "SignalProxy::handleInitData() received initData for unregistered Object:" - << className << objectName; + << className << objectName; return; } @@ -771,8 +783,8 @@ bool SignalProxy::invokeSlot(QObject *receiver, int methodId, const QVariantList } void *_a[] = {0, // return type... - 0, 0, 0, 0 , 0, // and 10 args - that's the max size qt can handle with signals and slots - 0, 0, 0, 0 , 0}; + 0, 0, 0, 0 , 0, // and 10 args - that's the max size qt can handle with signals and slots + 0, 0, 0, 0 , 0}; // check for argument compatibility and build params array for(int i = 0; i < numArgs; i++) { @@ -887,8 +899,8 @@ bool SignalProxy::readDataFromDevice(QIODevice *dev, quint32 &blockSize, QVarian if(nbytes <= 4) { const char *data = rawItem.constData(); if(nbytes < 4 || (data[0]!=0 || data[1]!=0 || data[2]!=0 || data[3]!=0)) { - disconnectDevice(dev, tr("Peer sent corrupted compressed data!")); - return false; + disconnectDevice(dev, tr("Peer sent corrupted compressed data!")); + return false; } } @@ -915,7 +927,7 @@ void SignalProxy::requestInit(SyncableObject *obj) { QVariantList params; params << obj->syncMetaObject()->className() - << obj->objectName(); + << obj->objectName(); dispatchSignal(InitRequest, params); } @@ -935,23 +947,28 @@ void SignalProxy::setInitData(SyncableObject *obj, const QVariantMap &properties void SignalProxy::sendHeartBeat() { QVariantList heartBeatParams; heartBeatParams << QTime::currentTime(); + QList toClose; + PeerHash::iterator peer = _peers.begin(); while(peer != _peers.end()) { if((*peer)->type() == AbstractPeer::IODevicePeer) { IODevicePeer *ioPeer = static_cast(*peer); ioPeer->dispatchSignal(SignalProxy::HeartBeat, heartBeatParams); if(ioPeer->sentHeartBeats > 0) { - updateLag(ioPeer, ioPeer->sentHeartBeats * _heartBeatTimer.interval()); - } - if(ioPeer->sentHeartBeats > 1) { - qWarning() << "SignalProxy: Disconnecting peer:" << ioPeer->address() - << "(didn't receive a heartbeat for over" << ioPeer->sentHeartBeats * _heartBeatTimer.interval() / 1000 << "seconds)"; - ioPeer->close(); - } else { - ioPeer->sentHeartBeats++; + updateLag(ioPeer, ioPeer->sentHeartBeats * _heartBeatTimer.interval()); } + if(maxHeartBeatCount() >= 0 && ioPeer->sentHeartBeats >= maxHeartBeatCount()) + toClose.append(ioPeer); + else + ioPeer->sentHeartBeats++; } - peer++; + ++peer; + } + + foreach(IODevicePeer *ioPeer, toClose) { + qWarning() << "SignalProxy: Disconnecting peer:" << ioPeer->address() + << "(didn't receive a heartbeat for over" << ioPeer->sentHeartBeats * _heartBeatTimer.interval() / 1000 << "seconds)"; + ioPeer->close(); } } @@ -1142,19 +1159,19 @@ const QHash &SignalProxy::ExtendedMetaObject::receiveMap() { for(int i = 0; i < methodCount; i++) { requestSlot = _meta->method(i); if(requestSlot.methodType() != QMetaMethod::Slot) - continue; + continue; returnTypeName = requestSlot.typeName(); if(QMetaType::Void == (QMetaType::Type)returnType(i)) - continue; + continue; signature = QByteArray(requestSlot.signature()); if(!signature.startsWith("request")) - continue; + continue; paramsPos = signature.indexOf('('); if(paramsPos == -1) - continue; + continue; methodName = signature.left(paramsPos); params = signature.mid(paramsPos); @@ -1166,13 +1183,12 @@ const QHash &SignalProxy::ExtendedMetaObject::receiveMap() { receiverId = _meta->indexOfSlot(signature); if(receiverId == -1) { - signature = QMetaObject::normalizedSignature(methodName + "(" + returnTypeName + ")"); - receiverId = _meta->indexOfSlot(signature); + signature = QMetaObject::normalizedSignature(methodName + "(" + returnTypeName + ")"); + receiverId = _meta->indexOfSlot(signature); } if(receiverId != -1) { - receiveMap[i] = receiverId; - qDebug() << requestSlot.signature() << _meta->method(receiverId).signature() << "---" << i << receiverId; + receiveMap[i] = receiverId; } } _receiveMap = receiveMap;