mirror of
https://github.com/overte-org/overte.git
synced 2025-04-26 00:56:17 +02:00
merge with cuckoo branch, fix makefile OS X support
This commit is contained in:
commit
f23b08971c
28 changed files with 732 additions and 394 deletions
|
@ -40,12 +40,21 @@ CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
|
||||||
|
|
||||||
if (COMPILER_SUPPORTS_CXX11)
|
if (COMPILER_SUPPORTS_CXX11)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
||||||
|
endif ()
|
||||||
elseif(COMPILER_SUPPORTS_CXX0X)
|
elseif(COMPILER_SUPPORTS_CXX0X)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
||||||
else()
|
else()
|
||||||
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
|
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++0x")
|
||||||
|
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
|
||||||
|
endif ()
|
||||||
|
|
||||||
if (ANDROID)
|
if (ANDROID)
|
||||||
if (NOT ANDROID_QT_CMAKE_PREFIX_PATH)
|
if (NOT ANDROID_QT_CMAKE_PREFIX_PATH)
|
||||||
set(QT_CMAKE_PREFIX_PATH $ENV{HIFI_ANDROID}/qt/5.3/android_armv7/lib/cmake)
|
set(QT_CMAKE_PREFIX_PATH $ENV{HIFI_ANDROID}/qt/5.3/android_armv7/lib/cmake)
|
||||||
|
|
|
@ -439,7 +439,8 @@ int AudioMixer::prepareMixForListeningNode(Node* node) {
|
||||||
|
|
||||||
// loop through all other nodes that have sufficient audio to mix
|
// loop through all other nodes that have sufficient audio to mix
|
||||||
int streamsMixed = 0;
|
int streamsMixed = 0;
|
||||||
foreach (const SharedNodePointer& otherNode, NodeList::getInstance()->getNodeHash()) {
|
|
||||||
|
NodeList::getInstance()->eachNode([&](const SharedNodePointer& otherNode){
|
||||||
if (otherNode->getLinkedData()) {
|
if (otherNode->getLinkedData()) {
|
||||||
AudioMixerClientData* otherNodeClientData = (AudioMixerClientData*) otherNode->getLinkedData();
|
AudioMixerClientData* otherNodeClientData = (AudioMixerClientData*) otherNode->getLinkedData();
|
||||||
|
|
||||||
|
@ -461,7 +462,8 @@ int AudioMixer::prepareMixForListeningNode(Node* node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
return streamsMixed;
|
return streamsMixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,12 +541,11 @@ void AudioMixer::readPendingDatagram(const QByteArray& receivedPacket, const Hif
|
||||||
QByteArray packet = receivedPacket;
|
QByteArray packet = receivedPacket;
|
||||||
populatePacketHeader(packet, PacketTypeMuteEnvironment);
|
populatePacketHeader(packet, PacketTypeMuteEnvironment);
|
||||||
|
|
||||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
nodeList->eachNode([&](const SharedNodePointer& node){
|
||||||
if (node->getType() == NodeType::Agent && node->getActiveSocket() && node->getLinkedData() && node != nodeList->sendingNodeForPacket(receivedPacket)) {
|
if (node->getType() == NodeType::Agent && node->getActiveSocket() && node->getLinkedData() && node != nodeList->sendingNodeForPacket(receivedPacket)) {
|
||||||
nodeList->writeDatagram(packet, packet.size(), node);
|
nodeList->writeDatagram(packet, packet.size(), node);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// let processNodeData handle it.
|
// let processNodeData handle it.
|
||||||
nodeList->processNodeData(senderSockAddr, receivedPacket);
|
nodeList->processNodeData(senderSockAddr, receivedPacket);
|
||||||
|
@ -607,8 +608,9 @@ void AudioMixer::sendStatsPacket() {
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
int clientNumber = 0;
|
int clientNumber = 0;
|
||||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
|
||||||
|
|
||||||
|
|
||||||
|
nodeList->eachNode([&](const SharedNodePointer& node) {
|
||||||
// if we're too large, send the packet
|
// if we're too large, send the packet
|
||||||
if (sizeOfStats > TOO_BIG_FOR_MTU) {
|
if (sizeOfStats > TOO_BIG_FOR_MTU) {
|
||||||
nodeList->sendStatsToDomainServer(statsObject2);
|
nodeList->sendStatsToDomainServer(statsObject2);
|
||||||
|
@ -626,7 +628,7 @@ void AudioMixer::sendStatsPacket() {
|
||||||
somethingToSend = true;
|
somethingToSend = true;
|
||||||
sizeOfStats += property.size() + value.size();
|
sizeOfStats += property.size() + value.size();
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
if (somethingToSend) {
|
if (somethingToSend) {
|
||||||
nodeList->sendStatsToDomainServer(statsObject2);
|
nodeList->sendStatsToDomainServer(statsObject2);
|
||||||
|
@ -764,7 +766,8 @@ void AudioMixer::run() {
|
||||||
_lastPerSecondCallbackTime = now;
|
_lastPerSecondCallbackTime = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
nodeList->eachNode([&](const SharedNodePointer& node) {
|
||||||
|
|
||||||
if (node->getLinkedData()) {
|
if (node->getLinkedData()) {
|
||||||
AudioMixerClientData* nodeData = (AudioMixerClientData*)node->getLinkedData();
|
AudioMixerClientData* nodeData = (AudioMixerClientData*)node->getLinkedData();
|
||||||
|
|
||||||
|
@ -847,7 +850,7 @@ void AudioMixer::run() {
|
||||||
++_sumListeners;
|
++_sumListeners;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
++_numStatFrames;
|
++_numStatFrames;
|
||||||
|
|
||||||
|
@ -905,7 +908,7 @@ void AudioMixer::perSecondActions() {
|
||||||
_timeSpentPerHashMatchCallStats.getWindowSum() / WINDOW_LENGTH_USECS * 100.0,
|
_timeSpentPerHashMatchCallStats.getWindowSum() / WINDOW_LENGTH_USECS * 100.0,
|
||||||
_timeSpentPerHashMatchCallStats.getCurrentIntervalSum() / USECS_PER_SECOND * 100.0);
|
_timeSpentPerHashMatchCallStats.getCurrentIntervalSum() / USECS_PER_SECOND * 100.0);
|
||||||
|
|
||||||
foreach(const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
NodeList::getInstance()->eachNode([](const SharedNodePointer& node) {
|
||||||
if (node->getLinkedData()) {
|
if (node->getLinkedData()) {
|
||||||
AudioMixerClientData* nodeData = (AudioMixerClientData*)node->getLinkedData();
|
AudioMixerClientData* nodeData = (AudioMixerClientData*)node->getLinkedData();
|
||||||
|
|
||||||
|
@ -915,7 +918,7 @@ void AudioMixer::perSecondActions() {
|
||||||
nodeData->printUpstreamDownstreamStats();
|
nodeData->printUpstreamDownstreamStats();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_datagramsReadPerCallStats.currentIntervalComplete();
|
_datagramsReadPerCallStats.currentIntervalComplete();
|
||||||
|
|
|
@ -122,7 +122,7 @@ void AvatarMixer::broadcastAvatarData() {
|
||||||
AvatarMixerClientData* nodeData = NULL;
|
AvatarMixerClientData* nodeData = NULL;
|
||||||
AvatarMixerClientData* otherNodeData = NULL;
|
AvatarMixerClientData* otherNodeData = NULL;
|
||||||
|
|
||||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
nodeList->eachNode([&](const SharedNodePointer& node) {
|
||||||
if (node->getLinkedData() && node->getType() == NodeType::Agent && node->getActiveSocket()
|
if (node->getLinkedData() && node->getType() == NodeType::Agent && node->getActiveSocket()
|
||||||
&& (nodeData = reinterpret_cast<AvatarMixerClientData*>(node->getLinkedData()))->getMutex().tryLock()) {
|
&& (nodeData = reinterpret_cast<AvatarMixerClientData*>(node->getLinkedData()))->getMutex().tryLock()) {
|
||||||
++_sumListeners;
|
++_sumListeners;
|
||||||
|
@ -135,7 +135,7 @@ void AvatarMixer::broadcastAvatarData() {
|
||||||
|
|
||||||
// this is an AGENT we have received head data from
|
// this is an AGENT we have received head data from
|
||||||
// send back a packet with other active node data to this node
|
// send back a packet with other active node data to this node
|
||||||
foreach (const SharedNodePointer& otherNode, nodeList->getNodeHash()) {
|
nodeList->eachNode([&](const SharedNodePointer& otherNode) {
|
||||||
if (otherNode->getLinkedData() && otherNode->getUUID() != node->getUUID()
|
if (otherNode->getLinkedData() && otherNode->getUUID() != node->getUUID()
|
||||||
&& (otherNodeData = reinterpret_cast<AvatarMixerClientData*>(otherNode->getLinkedData()))->getMutex().tryLock()) {
|
&& (otherNodeData = reinterpret_cast<AvatarMixerClientData*>(otherNode->getLinkedData()))->getMutex().tryLock()) {
|
||||||
|
|
||||||
|
@ -203,13 +203,13 @@ void AvatarMixer::broadcastAvatarData() {
|
||||||
|
|
||||||
otherNodeData->getMutex().unlock();
|
otherNodeData->getMutex().unlock();
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
nodeList->writeDatagram(mixedAvatarByteArray, node);
|
nodeList->writeDatagram(mixedAvatarByteArray, node);
|
||||||
|
|
||||||
nodeData->getMutex().unlock();
|
nodeData->getMutex().unlock();
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
_lastFrameTimestamp = QDateTime::currentMSecsSinceEpoch();
|
_lastFrameTimestamp = QDateTime::currentMSecsSinceEpoch();
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,15 +123,17 @@ void EntityServer::pruneDeletedEntities() {
|
||||||
if (tree->hasAnyDeletedEntities()) {
|
if (tree->hasAnyDeletedEntities()) {
|
||||||
|
|
||||||
quint64 earliestLastDeletedEntitiesSent = usecTimestampNow() + 1; // in the future
|
quint64 earliestLastDeletedEntitiesSent = usecTimestampNow() + 1; // in the future
|
||||||
foreach (const SharedNodePointer& otherNode, NodeList::getInstance()->getNodeHash()) {
|
|
||||||
if (otherNode->getLinkedData()) {
|
NodeList::getInstance()->eachNode([&earliestLastDeletedEntitiesSent](const SharedNodePointer& node) {
|
||||||
EntityNodeData* nodeData = static_cast<EntityNodeData*>(otherNode->getLinkedData());
|
if (node->getLinkedData()) {
|
||||||
|
EntityNodeData* nodeData = static_cast<EntityNodeData*>(node->getLinkedData());
|
||||||
quint64 nodeLastDeletedEntitiesSentAt = nodeData->getLastDeletedEntitiesSentAt();
|
quint64 nodeLastDeletedEntitiesSentAt = nodeData->getLastDeletedEntitiesSentAt();
|
||||||
if (nodeLastDeletedEntitiesSentAt < earliestLastDeletedEntitiesSent) {
|
if (nodeLastDeletedEntitiesSentAt < earliestLastDeletedEntitiesSent) {
|
||||||
earliestLastDeletedEntitiesSent = nodeLastDeletedEntitiesSentAt;
|
earliestLastDeletedEntitiesSent = nodeLastDeletedEntitiesSentAt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
tree->forgetEntitiesDeletedBefore(earliestLastDeletedEntitiesSent);
|
tree->forgetEntitiesDeletedBefore(earliestLastDeletedEntitiesSent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -261,7 +261,7 @@ int OctreeInboundPacketProcessor::sendNackPackets() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SharedNodePointer& destinationNode = NodeList::getInstance()->getNodeHash().value(nodeUUID);
|
const SharedNodePointer& destinationNode = NodeList::getInstance()->nodeWithUUID(nodeUUID);
|
||||||
|
|
||||||
// retrieve sequence number stats of node, prune its missing set
|
// retrieve sequence number stats of node, prune its missing set
|
||||||
SequenceNumberStats& sequenceNumberStats = nodeStats.getIncomingEditSequenceNumberStats();
|
SequenceNumberStats& sequenceNumberStats = nodeStats.getIncomingEditSequenceNumberStats();
|
||||||
|
|
|
@ -1193,10 +1193,12 @@ void OctreeServer::aboutToFinish() {
|
||||||
qDebug() << qPrintable(_safeServerName) << "server STARTING about to finish...";
|
qDebug() << qPrintable(_safeServerName) << "server STARTING about to finish...";
|
||||||
qDebug() << qPrintable(_safeServerName) << "inform Octree Inbound Packet Processor that we are shutting down...";
|
qDebug() << qPrintable(_safeServerName) << "inform Octree Inbound Packet Processor that we are shutting down...";
|
||||||
_octreeInboundPacketProcessor->shuttingDown();
|
_octreeInboundPacketProcessor->shuttingDown();
|
||||||
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
|
||||||
|
NodeList::getInstance()->eachNode([this](const SharedNodePointer& node) {
|
||||||
qDebug() << qPrintable(_safeServerName) << "server about to finish while node still connected node:" << *node;
|
qDebug() << qPrintable(_safeServerName) << "server about to finish while node still connected node:" << *node;
|
||||||
forceNodeShutdown(node);
|
forceNodeShutdown(node);
|
||||||
}
|
});
|
||||||
|
|
||||||
qDebug() << qPrintable(_safeServerName) << "server ENDING about to finish...";
|
qDebug() << qPrintable(_safeServerName) << "server ENDING about to finish...";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,10 @@ macro(LINK_HIFI_LIBRARIES)
|
||||||
get_target_property(LINKED_TARGET_DEPENDENCY_LIBRARIES ${HIFI_LIBRARY} DEPENDENCY_LIBRARIES)
|
get_target_property(LINKED_TARGET_DEPENDENCY_LIBRARIES ${HIFI_LIBRARY} DEPENDENCY_LIBRARIES)
|
||||||
list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK ${LINKED_TARGET_DEPENDENCY_LIBRARIES})
|
list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK ${LINKED_TARGET_DEPENDENCY_LIBRARIES})
|
||||||
|
|
||||||
|
# ask the library what its include dependencies are and link them
|
||||||
|
get_target_property(LINKED_TARGET_DEPENDENCY_INCLUDES ${HIFI_LIBRARY} DEPENDENCY_INCLUDES)
|
||||||
|
list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES ${LINKED_TARGET_DEPENDENCY_INCLUDES})
|
||||||
|
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
endmacro(LINK_HIFI_LIBRARIES)
|
endmacro(LINK_HIFI_LIBRARIES)
|
|
@ -17,9 +17,17 @@ macro(LINK_SHARED_DEPENDENCIES)
|
||||||
target_link_libraries(${TARGET_NAME} ${${TARGET_NAME}_LIBRARIES_TO_LINK})
|
target_link_libraries(${TARGET_NAME} ${${TARGET_NAME}_LIBRARIES_TO_LINK})
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
if (${TARGET_NAME}_DEPENDENCY_INCLUDES)
|
||||||
|
list(REMOVE_DUPLICATES ${TARGET_NAME}_DEPENDENCY_INCLUDES)
|
||||||
|
|
||||||
|
# include those in our own target
|
||||||
|
include_directories(SYSTEM ${${TARGET_NAME}_DEPENDENCY_INCLUDES})
|
||||||
|
endif ()
|
||||||
|
|
||||||
# we've already linked our Qt modules, but we need to bubble them up to parents
|
# we've already linked our Qt modules, but we need to bubble them up to parents
|
||||||
list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK "${${TARGET}_QT_MODULES_TO_LINK}")
|
list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK "${${TARGET}_QT_MODULES_TO_LINK}")
|
||||||
|
|
||||||
# set the property on this target so it can be retreived by targets linking to us
|
# set the property on this target so it can be retreived by targets linking to us
|
||||||
set_target_properties(${TARGET_NAME} PROPERTIES DEPENDENCY_LIBRARIES "${${TARGET}_LIBRARIES_TO_LINK}")
|
set_target_properties(${TARGET_NAME} PROPERTIES DEPENDENCY_LIBRARIES "${${TARGET_NAME}_LIBRARIES_TO_LINK}")
|
||||||
|
set_target_properties(${TARGET_NAME} PROPERTIES DEPENDENCY_INCLUDES "${${TARGET_NAME}_DEPENDENCY_INCLUDES}")
|
||||||
endmacro(LINK_SHARED_DEPENDENCIES)
|
endmacro(LINK_SHARED_DEPENDENCIES)
|
283
cmake/modules/FindTBB.cmake
Normal file
283
cmake/modules/FindTBB.cmake
Normal file
|
@ -0,0 +1,283 @@
|
||||||
|
# Locate Intel Threading Building Blocks include paths and libraries
|
||||||
|
# FindTBB.cmake can be found at https://code.google.com/p/findtbb/
|
||||||
|
# Written by Hannes Hofmann <hannes.hofmann _at_ informatik.uni-erlangen.de>
|
||||||
|
# Improvements by Gino van den Bergen <gino _at_ dtecta.com>,
|
||||||
|
# Florian Uhlig <F.Uhlig _at_ gsi.de>,
|
||||||
|
# Jiri Marsik <jiri.marsik89 _at_ gmail.com>
|
||||||
|
|
||||||
|
# The MIT License
|
||||||
|
#
|
||||||
|
# Copyright (c) 2011 Hannes Hofmann
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
# THE SOFTWARE.
|
||||||
|
|
||||||
|
# GvdB: This module uses the environment variable TBB_ARCH_PLATFORM which defines architecture and compiler.
|
||||||
|
# e.g. "ia32/vc8" or "em64t/cc4.1.0_libc2.4_kernel2.6.16.21"
|
||||||
|
# TBB_ARCH_PLATFORM is set by the build script tbbvars[.bat|.sh|.csh], which can be found
|
||||||
|
# in the TBB installation directory (TBB_INSTALL_DIR).
|
||||||
|
#
|
||||||
|
# GvdB: Mac OS X distribution places libraries directly in lib directory.
|
||||||
|
#
|
||||||
|
# For backwards compatibility, you may explicitely set the CMake variables TBB_ARCHITECTURE and TBB_COMPILER.
|
||||||
|
# TBB_ARCHITECTURE [ ia32 | em64t | itanium ]
|
||||||
|
# which architecture to use
|
||||||
|
# TBB_COMPILER e.g. vc9 or cc3.2.3_libc2.3.2_kernel2.4.21 or cc4.0.1_os10.4.9
|
||||||
|
# which compiler to use (detected automatically on Windows)
|
||||||
|
|
||||||
|
# This module respects
|
||||||
|
# TBB_INSTALL_DIR or $ENV{TBB21_INSTALL_DIR} or $ENV{TBB_INSTALL_DIR}
|
||||||
|
|
||||||
|
# This module defines
|
||||||
|
# TBB_INCLUDE_DIRS, where to find task_scheduler_init.h, etc.
|
||||||
|
# TBB_LIBRARY_DIRS, where to find libtbb, libtbbmalloc
|
||||||
|
# TBB_DEBUG_LIBRARY_DIRS, where to find libtbb_debug, libtbbmalloc_debug
|
||||||
|
# TBB_INSTALL_DIR, the base TBB install directory
|
||||||
|
# TBB_LIBRARIES, the libraries to link against to use TBB.
|
||||||
|
# TBB_DEBUG_LIBRARIES, the libraries to link against to use TBB with debug symbols.
|
||||||
|
# TBB_FOUND, If false, don't try to use TBB.
|
||||||
|
# TBB_INTERFACE_VERSION, as defined in tbb/tbb_stddef.h
|
||||||
|
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
# has em64t/vc8 em64t/vc9
|
||||||
|
# has ia32/vc7.1 ia32/vc8 ia32/vc9
|
||||||
|
set(_TBB_DEFAULT_INSTALL_DIR "C:/Program Files/Intel/TBB" "C:/Program Files (x86)/Intel/TBB")
|
||||||
|
set(_TBB_LIB_NAME "tbb")
|
||||||
|
set(_TBB_LIB_MALLOC_NAME "${_TBB_LIB_NAME}malloc")
|
||||||
|
set(_TBB_LIB_DEBUG_NAME "${_TBB_LIB_NAME}_debug")
|
||||||
|
set(_TBB_LIB_MALLOC_DEBUG_NAME "${_TBB_LIB_MALLOC_NAME}_debug")
|
||||||
|
if (MSVC71)
|
||||||
|
set (_TBB_COMPILER "vc7.1")
|
||||||
|
endif(MSVC71)
|
||||||
|
if (MSVC80)
|
||||||
|
set(_TBB_COMPILER "vc8")
|
||||||
|
endif(MSVC80)
|
||||||
|
if (MSVC90)
|
||||||
|
set(_TBB_COMPILER "vc9")
|
||||||
|
endif(MSVC90)
|
||||||
|
if(MSVC10)
|
||||||
|
set(_TBB_COMPILER "vc10")
|
||||||
|
endif(MSVC10)
|
||||||
|
# Todo: add other Windows compilers such as ICL.
|
||||||
|
set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE})
|
||||||
|
endif (WIN32)
|
||||||
|
|
||||||
|
if (UNIX)
|
||||||
|
if (APPLE)
|
||||||
|
# MAC
|
||||||
|
set(_TBB_DEFAULT_INSTALL_DIR "/Library/Frameworks/Intel_TBB.framework/Versions")
|
||||||
|
# libs: libtbb.dylib, libtbbmalloc.dylib, *_debug
|
||||||
|
set(_TBB_LIB_NAME "tbb")
|
||||||
|
set(_TBB_LIB_MALLOC_NAME "${_TBB_LIB_NAME}malloc")
|
||||||
|
set(_TBB_LIB_DEBUG_NAME "${_TBB_LIB_NAME}_debug")
|
||||||
|
set(_TBB_LIB_MALLOC_DEBUG_NAME "${_TBB_LIB_MALLOC_NAME}_debug")
|
||||||
|
# default flavor on apple: ia32/cc4.0.1_os10.4.9
|
||||||
|
# Jiri: There is no reason to presume there is only one flavor and
|
||||||
|
# that user's setting of variables should be ignored.
|
||||||
|
if(NOT TBB_COMPILER)
|
||||||
|
set(_TBB_COMPILER "cc4.0.1_os10.4.9")
|
||||||
|
elseif (NOT TBB_COMPILER)
|
||||||
|
set(_TBB_COMPILER ${TBB_COMPILER})
|
||||||
|
endif(NOT TBB_COMPILER)
|
||||||
|
if(NOT TBB_ARCHITECTURE)
|
||||||
|
set(_TBB_ARCHITECTURE "ia32")
|
||||||
|
elseif(NOT TBB_ARCHITECTURE)
|
||||||
|
set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE})
|
||||||
|
endif(NOT TBB_ARCHITECTURE)
|
||||||
|
else (APPLE)
|
||||||
|
# LINUX
|
||||||
|
set(_TBB_DEFAULT_INSTALL_DIR "/opt/intel/tbb" "/usr/local/include" "/usr/include")
|
||||||
|
set(_TBB_LIB_NAME "tbb")
|
||||||
|
set(_TBB_LIB_MALLOC_NAME "${_TBB_LIB_NAME}malloc")
|
||||||
|
set(_TBB_LIB_DEBUG_NAME "${_TBB_LIB_NAME}_debug")
|
||||||
|
set(_TBB_LIB_MALLOC_DEBUG_NAME "${_TBB_LIB_MALLOC_NAME}_debug")
|
||||||
|
# has em64t/cc3.2.3_libc2.3.2_kernel2.4.21 em64t/cc3.3.3_libc2.3.3_kernel2.6.5 em64t/cc3.4.3_libc2.3.4_kernel2.6.9 em64t/cc4.1.0_libc2.4_kernel2.6.16.21
|
||||||
|
# has ia32/*
|
||||||
|
# has itanium/*
|
||||||
|
set(_TBB_COMPILER ${TBB_COMPILER})
|
||||||
|
set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE})
|
||||||
|
endif (APPLE)
|
||||||
|
endif (UNIX)
|
||||||
|
|
||||||
|
if (CMAKE_SYSTEM MATCHES "SunOS.*")
|
||||||
|
# SUN
|
||||||
|
# not yet supported
|
||||||
|
# has em64t/cc3.4.3_kernel5.10
|
||||||
|
# has ia32/*
|
||||||
|
endif (CMAKE_SYSTEM MATCHES "SunOS.*")
|
||||||
|
|
||||||
|
|
||||||
|
#-- Clear the public variables
|
||||||
|
set (TBB_FOUND "NO")
|
||||||
|
|
||||||
|
|
||||||
|
#-- Find TBB install dir and set ${_TBB_INSTALL_DIR} and cached ${TBB_INSTALL_DIR}
|
||||||
|
# first: use CMake variable TBB_INSTALL_DIR
|
||||||
|
if (TBB_INSTALL_DIR)
|
||||||
|
set (_TBB_INSTALL_DIR ${TBB_INSTALL_DIR})
|
||||||
|
endif (TBB_INSTALL_DIR)
|
||||||
|
# second: use environment variable
|
||||||
|
if (NOT _TBB_INSTALL_DIR)
|
||||||
|
if (NOT "$ENV{TBB_INSTALL_DIR}" STREQUAL "")
|
||||||
|
set (_TBB_INSTALL_DIR $ENV{TBB_INSTALL_DIR})
|
||||||
|
endif (NOT "$ENV{TBB_INSTALL_DIR}" STREQUAL "")
|
||||||
|
# Intel recommends setting TBB21_INSTALL_DIR
|
||||||
|
if (NOT "$ENV{TBB21_INSTALL_DIR}" STREQUAL "")
|
||||||
|
set (_TBB_INSTALL_DIR $ENV{TBB21_INSTALL_DIR})
|
||||||
|
endif (NOT "$ENV{TBB21_INSTALL_DIR}" STREQUAL "")
|
||||||
|
if (NOT "$ENV{TBB22_INSTALL_DIR}" STREQUAL "")
|
||||||
|
set (_TBB_INSTALL_DIR $ENV{TBB22_INSTALL_DIR})
|
||||||
|
endif (NOT "$ENV{TBB22_INSTALL_DIR}" STREQUAL "")
|
||||||
|
if (NOT "$ENV{TBB30_INSTALL_DIR}" STREQUAL "")
|
||||||
|
set (_TBB_INSTALL_DIR $ENV{TBB30_INSTALL_DIR})
|
||||||
|
endif (NOT "$ENV{TBB30_INSTALL_DIR}" STREQUAL "")
|
||||||
|
endif (NOT _TBB_INSTALL_DIR)
|
||||||
|
# third: try to find path automatically
|
||||||
|
if (NOT _TBB_INSTALL_DIR)
|
||||||
|
if (_TBB_DEFAULT_INSTALL_DIR)
|
||||||
|
set (_TBB_INSTALL_DIR ${_TBB_DEFAULT_INSTALL_DIR})
|
||||||
|
endif (_TBB_DEFAULT_INSTALL_DIR)
|
||||||
|
endif (NOT _TBB_INSTALL_DIR)
|
||||||
|
# sanity check
|
||||||
|
if (NOT _TBB_INSTALL_DIR)
|
||||||
|
message ("ERROR: Unable to find Intel TBB install directory. ${_TBB_INSTALL_DIR}")
|
||||||
|
else (NOT _TBB_INSTALL_DIR)
|
||||||
|
# finally: set the cached CMake variable TBB_INSTALL_DIR
|
||||||
|
if (NOT TBB_INSTALL_DIR)
|
||||||
|
set (TBB_INSTALL_DIR ${_TBB_INSTALL_DIR} CACHE PATH "Intel TBB install directory")
|
||||||
|
mark_as_advanced(TBB_INSTALL_DIR)
|
||||||
|
endif (NOT TBB_INSTALL_DIR)
|
||||||
|
|
||||||
|
|
||||||
|
#-- A macro to rewrite the paths of the library. This is necessary, because
|
||||||
|
# find_library() always found the em64t/vc9 version of the TBB libs
|
||||||
|
macro(TBB_CORRECT_LIB_DIR var_name)
|
||||||
|
# if (NOT "${_TBB_ARCHITECTURE}" STREQUAL "em64t")
|
||||||
|
string(REPLACE em64t "${_TBB_ARCHITECTURE}" ${var_name} ${${var_name}})
|
||||||
|
# endif (NOT "${_TBB_ARCHITECTURE}" STREQUAL "em64t")
|
||||||
|
string(REPLACE ia32 "${_TBB_ARCHITECTURE}" ${var_name} ${${var_name}})
|
||||||
|
string(REPLACE vc7.1 "${_TBB_COMPILER}" ${var_name} ${${var_name}})
|
||||||
|
string(REPLACE vc8 "${_TBB_COMPILER}" ${var_name} ${${var_name}})
|
||||||
|
string(REPLACE vc9 "${_TBB_COMPILER}" ${var_name} ${${var_name}})
|
||||||
|
string(REPLACE vc10 "${_TBB_COMPILER}" ${var_name} ${${var_name}})
|
||||||
|
endmacro(TBB_CORRECT_LIB_DIR var_content)
|
||||||
|
|
||||||
|
|
||||||
|
#-- Look for include directory and set ${TBB_INCLUDE_DIR}
|
||||||
|
set (TBB_INC_SEARCH_DIR ${_TBB_INSTALL_DIR}/include)
|
||||||
|
# Jiri: tbbvars now sets the CPATH environment variable to the directory
|
||||||
|
# containing the headers.
|
||||||
|
find_path(TBB_INCLUDE_DIR
|
||||||
|
tbb/task_scheduler_init.h
|
||||||
|
PATHS ${TBB_INC_SEARCH_DIR} ENV CPATH
|
||||||
|
)
|
||||||
|
mark_as_advanced(TBB_INCLUDE_DIR)
|
||||||
|
|
||||||
|
|
||||||
|
#-- Look for libraries
|
||||||
|
# GvdB: $ENV{TBB_ARCH_PLATFORM} is set by the build script tbbvars[.bat|.sh|.csh]
|
||||||
|
if (NOT $ENV{TBB_ARCH_PLATFORM} STREQUAL "")
|
||||||
|
set (_TBB_LIBRARY_DIR
|
||||||
|
${_TBB_INSTALL_DIR}/lib/$ENV{TBB_ARCH_PLATFORM}
|
||||||
|
${_TBB_INSTALL_DIR}/$ENV{TBB_ARCH_PLATFORM}/lib
|
||||||
|
)
|
||||||
|
endif (NOT $ENV{TBB_ARCH_PLATFORM} STREQUAL "")
|
||||||
|
# Jiri: This block isn't mutually exclusive with the previous one
|
||||||
|
# (hence no else), instead I test if the user really specified
|
||||||
|
# the variables in question.
|
||||||
|
if ((NOT ${TBB_ARCHITECTURE} STREQUAL "") AND (NOT ${TBB_COMPILER} STREQUAL ""))
|
||||||
|
# HH: deprecated
|
||||||
|
message(STATUS "[Warning] FindTBB.cmake: The use of TBB_ARCHITECTURE and TBB_COMPILER is deprecated and may not be supported in future versions. Please set \$ENV{TBB_ARCH_PLATFORM} (using tbbvars.[bat|csh|sh]).")
|
||||||
|
# Jiri: It doesn't hurt to look in more places, so I store the hints from
|
||||||
|
# ENV{TBB_ARCH_PLATFORM} and the TBB_ARCHITECTURE and TBB_COMPILER
|
||||||
|
# variables and search them both.
|
||||||
|
set (_TBB_LIBRARY_DIR "${_TBB_INSTALL_DIR}/${_TBB_ARCHITECTURE}/${_TBB_COMPILER}/lib" ${_TBB_LIBRARY_DIR})
|
||||||
|
endif ((NOT ${TBB_ARCHITECTURE} STREQUAL "") AND (NOT ${TBB_COMPILER} STREQUAL ""))
|
||||||
|
|
||||||
|
# GvdB: Mac OS X distribution places libraries directly in lib directory.
|
||||||
|
list(APPEND _TBB_LIBRARY_DIR ${_TBB_INSTALL_DIR}/lib)
|
||||||
|
|
||||||
|
# Jiri: No reason not to check the default paths. From recent versions,
|
||||||
|
# tbbvars has started exporting the LIBRARY_PATH and LD_LIBRARY_PATH
|
||||||
|
# variables, which now point to the directories of the lib files.
|
||||||
|
# It all makes more sense to use the ${_TBB_LIBRARY_DIR} as a HINTS
|
||||||
|
# argument instead of the implicit PATHS as it isn't hard-coded
|
||||||
|
# but computed by system introspection. Searching the LIBRARY_PATH
|
||||||
|
# and LD_LIBRARY_PATH environment variables is now even more important
|
||||||
|
# that tbbvars doesn't export TBB_ARCH_PLATFORM and it facilitates
|
||||||
|
# the use of TBB built from sources.
|
||||||
|
find_library(TBB_LIBRARY ${_TBB_LIB_NAME} HINTS ${_TBB_LIBRARY_DIR}
|
||||||
|
PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH)
|
||||||
|
find_library(TBB_MALLOC_LIBRARY ${_TBB_LIB_MALLOC_NAME} HINTS ${_TBB_LIBRARY_DIR}
|
||||||
|
PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH)
|
||||||
|
|
||||||
|
#Extract path from TBB_LIBRARY name
|
||||||
|
get_filename_component(TBB_LIBRARY_DIR ${TBB_LIBRARY} PATH)
|
||||||
|
|
||||||
|
#TBB_CORRECT_LIB_DIR(TBB_LIBRARY)
|
||||||
|
#TBB_CORRECT_LIB_DIR(TBB_MALLOC_LIBRARY)
|
||||||
|
mark_as_advanced(TBB_LIBRARY TBB_MALLOC_LIBRARY)
|
||||||
|
|
||||||
|
#-- Look for debug libraries
|
||||||
|
# Jiri: Changed the same way as for the release libraries.
|
||||||
|
find_library(TBB_LIBRARY_DEBUG ${_TBB_LIB_DEBUG_NAME} HINTS ${_TBB_LIBRARY_DIR}
|
||||||
|
PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH)
|
||||||
|
find_library(TBB_MALLOC_LIBRARY_DEBUG ${_TBB_LIB_MALLOC_DEBUG_NAME} HINTS ${_TBB_LIBRARY_DIR}
|
||||||
|
PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH)
|
||||||
|
|
||||||
|
# Jiri: Self-built TBB stores the debug libraries in a separate directory.
|
||||||
|
# Extract path from TBB_LIBRARY_DEBUG name
|
||||||
|
get_filename_component(TBB_LIBRARY_DEBUG_DIR ${TBB_LIBRARY_DEBUG} PATH)
|
||||||
|
|
||||||
|
#TBB_CORRECT_LIB_DIR(TBB_LIBRARY_DEBUG)
|
||||||
|
#TBB_CORRECT_LIB_DIR(TBB_MALLOC_LIBRARY_DEBUG)
|
||||||
|
mark_as_advanced(TBB_LIBRARY_DEBUG TBB_MALLOC_LIBRARY_DEBUG)
|
||||||
|
|
||||||
|
|
||||||
|
if (TBB_INCLUDE_DIR)
|
||||||
|
if (TBB_LIBRARY)
|
||||||
|
set (TBB_FOUND "YES")
|
||||||
|
set (TBB_LIBRARIES ${TBB_LIBRARY} ${TBB_MALLOC_LIBRARY} ${TBB_LIBRARIES})
|
||||||
|
set (TBB_DEBUG_LIBRARIES ${TBB_LIBRARY_DEBUG} ${TBB_MALLOC_LIBRARY_DEBUG} ${TBB_DEBUG_LIBRARIES})
|
||||||
|
set (TBB_INCLUDE_DIRS ${TBB_INCLUDE_DIR} CACHE PATH "TBB include directory" FORCE)
|
||||||
|
set (TBB_LIBRARY_DIRS ${TBB_LIBRARY_DIR} CACHE PATH "TBB library directory" FORCE)
|
||||||
|
# Jiri: Self-built TBB stores the debug libraries in a separate directory.
|
||||||
|
set (TBB_DEBUG_LIBRARY_DIRS ${TBB_LIBRARY_DEBUG_DIR} CACHE PATH "TBB debug library directory" FORCE)
|
||||||
|
mark_as_advanced(TBB_INCLUDE_DIRS TBB_LIBRARY_DIRS TBB_DEBUG_LIBRARY_DIRS TBB_LIBRARIES TBB_DEBUG_LIBRARIES)
|
||||||
|
message(STATUS "Found Intel TBB")
|
||||||
|
endif (TBB_LIBRARY)
|
||||||
|
endif (TBB_INCLUDE_DIR)
|
||||||
|
|
||||||
|
if (NOT TBB_FOUND)
|
||||||
|
message("ERROR: Intel TBB NOT found!")
|
||||||
|
message(STATUS "Looked for Threading Building Blocks in ${_TBB_INSTALL_DIR}")
|
||||||
|
# do only throw fatal, if this pkg is REQUIRED
|
||||||
|
if (TBB_FIND_REQUIRED)
|
||||||
|
message(FATAL_ERROR "Could NOT find TBB library.")
|
||||||
|
endif (TBB_FIND_REQUIRED)
|
||||||
|
endif (NOT TBB_FOUND)
|
||||||
|
|
||||||
|
endif (NOT _TBB_INSTALL_DIR)
|
||||||
|
|
||||||
|
if (TBB_FOUND)
|
||||||
|
set(TBB_INTERFACE_VERSION 0)
|
||||||
|
FILE(READ "${TBB_INCLUDE_DIRS}/tbb/tbb_stddef.h" _TBB_VERSION_CONTENTS)
|
||||||
|
STRING(REGEX REPLACE ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1" TBB_INTERFACE_VERSION "${_TBB_VERSION_CONTENTS}")
|
||||||
|
set(TBB_INTERFACE_VERSION "${TBB_INTERFACE_VERSION}")
|
||||||
|
endif (TBB_FOUND)
|
|
@ -821,8 +821,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif
|
||||||
|
|
||||||
if (nodeData->isAuthenticated()) {
|
if (nodeData->isAuthenticated()) {
|
||||||
// if this authenticated node has any interest types, send back those nodes as well
|
// if this authenticated node has any interest types, send back those nodes as well
|
||||||
foreach (const SharedNodePointer& otherNode, nodeList->getNodeHash()) {
|
nodeList->eachNode([&](const SharedNodePointer& otherNode){
|
||||||
|
|
||||||
// reset our nodeByteArray and nodeDataStream
|
// reset our nodeByteArray and nodeDataStream
|
||||||
QByteArray nodeByteArray;
|
QByteArray nodeByteArray;
|
||||||
QDataStream nodeDataStream(&nodeByteArray, QIODevice::Append);
|
QDataStream nodeDataStream(&nodeByteArray, QIODevice::Append);
|
||||||
|
@ -863,7 +862,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif
|
||||||
// append the nodeByteArray to the current state of broadcastDataStream
|
// append the nodeByteArray to the current state of broadcastDataStream
|
||||||
broadcastPacket.append(nodeByteArray);
|
broadcastPacket.append(nodeByteArray);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// always write the last broadcastPacket
|
// always write the last broadcastPacket
|
||||||
|
@ -960,7 +959,7 @@ void DomainServer::readAvailableDatagrams() {
|
||||||
|
|
||||||
void DomainServer::setupPendingAssignmentCredits() {
|
void DomainServer::setupPendingAssignmentCredits() {
|
||||||
// enumerate the NodeList to find the assigned nodes
|
// enumerate the NodeList to find the assigned nodes
|
||||||
foreach (const SharedNodePointer& node, LimitedNodeList::getInstance()->getNodeHash()) {
|
NodeList::getInstance()->eachNode([&](const SharedNodePointer& node){
|
||||||
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(node->getLinkedData());
|
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(node->getLinkedData());
|
||||||
|
|
||||||
if (!nodeData->getAssignmentUUID().isNull() && !nodeData->getWalletUUID().isNull()) {
|
if (!nodeData->getAssignmentUUID().isNull() && !nodeData->getWalletUUID().isNull()) {
|
||||||
|
@ -994,7 +993,7 @@ void DomainServer::setupPendingAssignmentCredits() {
|
||||||
_pendingAssignmentCredits.insert(nodeData->getWalletUUID(), freshTransaction);
|
_pendingAssignmentCredits.insert(nodeData->getWalletUUID(), freshTransaction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DomainServer::sendPendingTransactionsToServer() {
|
void DomainServer::sendPendingTransactionsToServer() {
|
||||||
|
@ -1119,11 +1118,12 @@ void DomainServer::sendHeartbeatToDataServer(const QString& networkAddress) {
|
||||||
|
|
||||||
// add the number of currently connected agent users
|
// add the number of currently connected agent users
|
||||||
int numConnectedAuthedUsers = 0;
|
int numConnectedAuthedUsers = 0;
|
||||||
foreach(const SharedNodePointer& node, LimitedNodeList::getInstance()->getNodeHash()) {
|
|
||||||
|
NodeList::getInstance()->eachNode([&numConnectedAuthedUsers](const SharedNodePointer& node){
|
||||||
if (node->getLinkedData() && !static_cast<DomainServerNodeData*>(node->getLinkedData())->getUsername().isEmpty()) {
|
if (node->getLinkedData() && !static_cast<DomainServerNodeData*>(node->getLinkedData())->getUsername().isEmpty()) {
|
||||||
++numConnectedAuthedUsers;
|
++numConnectedAuthedUsers;
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
const QString DOMAIN_HEARTBEAT_KEY = "heartbeat";
|
const QString DOMAIN_HEARTBEAT_KEY = "heartbeat";
|
||||||
const QString HEARTBEAT_NUM_USERS_KEY = "num_users";
|
const QString HEARTBEAT_NUM_USERS_KEY = "num_users";
|
||||||
|
@ -1242,8 +1242,9 @@ void DomainServer::processDatagram(const QByteArray& receivedPacket, const HifiS
|
||||||
parseNodeDataFromByteArray(packetStream, throwawayNodeType, nodePublicAddress, nodeLocalAddress,
|
parseNodeDataFromByteArray(packetStream, throwawayNodeType, nodePublicAddress, nodeLocalAddress,
|
||||||
senderSockAddr);
|
senderSockAddr);
|
||||||
|
|
||||||
SharedNodePointer checkInNode = nodeList->updateSocketsForNode(nodeUUID,
|
SharedNodePointer checkInNode = nodeList->nodeWithUUID(nodeUUID);
|
||||||
nodePublicAddress, nodeLocalAddress);
|
checkInNode->setPublicSocket(nodePublicAddress);
|
||||||
|
checkInNode->setLocalSocket(nodeLocalAddress);
|
||||||
|
|
||||||
// update last receive to now
|
// update last receive to now
|
||||||
quint64 timeNow = usecTimestampNow();
|
quint64 timeNow = usecTimestampNow();
|
||||||
|
@ -1425,7 +1426,7 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
|
||||||
QJsonObject assignedNodesJSON;
|
QJsonObject assignedNodesJSON;
|
||||||
|
|
||||||
// enumerate the NodeList to find the assigned nodes
|
// enumerate the NodeList to find the assigned nodes
|
||||||
foreach (const SharedNodePointer& node, LimitedNodeList::getInstance()->getNodeHash()) {
|
NodeList::getInstance()->eachNode([this, &assignedNodesJSON](const SharedNodePointer& node){
|
||||||
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(node->getLinkedData());
|
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(node->getLinkedData());
|
||||||
|
|
||||||
if (!nodeData->getAssignmentUUID().isNull()) {
|
if (!nodeData->getAssignmentUUID().isNull()) {
|
||||||
|
@ -1433,7 +1434,7 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
|
||||||
QString uuidString = uuidStringWithoutCurlyBraces(nodeData->getAssignmentUUID());
|
QString uuidString = uuidStringWithoutCurlyBraces(nodeData->getAssignmentUUID());
|
||||||
assignedNodesJSON[uuidString] = jsonObjectForNode(node);
|
assignedNodesJSON[uuidString] = jsonObjectForNode(node);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
assignmentJSON["fulfilled"] = assignedNodesJSON;
|
assignmentJSON["fulfilled"] = assignedNodesJSON;
|
||||||
|
|
||||||
|
@ -1487,12 +1488,10 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
|
||||||
QJsonArray nodesJSONArray;
|
QJsonArray nodesJSONArray;
|
||||||
|
|
||||||
// enumerate the NodeList to find the assigned nodes
|
// enumerate the NodeList to find the assigned nodes
|
||||||
LimitedNodeList* nodeList = LimitedNodeList::getInstance();
|
LimitedNodeList::getInstance()->eachNode([this, &nodesJSONArray](const SharedNodePointer& node){
|
||||||
|
|
||||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
|
||||||
// add the node using the UUID as the key
|
// add the node using the UUID as the key
|
||||||
nodesJSONArray.append(jsonObjectForNode(node));
|
nodesJSONArray.append(jsonObjectForNode(node));
|
||||||
}
|
});
|
||||||
|
|
||||||
rootJSON["nodes"] = nodesJSONArray;
|
rootJSON["nodes"] = nodesJSONArray;
|
||||||
|
|
||||||
|
@ -2020,16 +2019,9 @@ void DomainServer::addStaticAssignmentsToQueue() {
|
||||||
QHash<QUuid, SharedAssignmentPointer>::iterator staticAssignment = staticHashCopy.begin();
|
QHash<QUuid, SharedAssignmentPointer>::iterator staticAssignment = staticHashCopy.begin();
|
||||||
while (staticAssignment != staticHashCopy.end()) {
|
while (staticAssignment != staticHashCopy.end()) {
|
||||||
// add any of the un-matched static assignments to the queue
|
// add any of the un-matched static assignments to the queue
|
||||||
bool foundMatchingAssignment = false;
|
|
||||||
|
|
||||||
// enumerate the nodes and check if there is one with an attached assignment with matching UUID
|
// enumerate the nodes and check if there is one with an attached assignment with matching UUID
|
||||||
foreach (const SharedNodePointer& node, LimitedNodeList::getInstance()->getNodeHash()) {
|
if (!NodeList::getInstance()->nodeWithUUID(staticAssignment->data()->getUUID())) {
|
||||||
if (node->getUUID() == staticAssignment->data()->getUUID()) {
|
|
||||||
foundMatchingAssignment = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!foundMatchingAssignment) {
|
|
||||||
// this assignment has not been fulfilled - reset the UUID and add it to the assignment queue
|
// this assignment has not been fulfilled - reset the UUID and add it to the assignment queue
|
||||||
refreshStaticAssignmentAndAddToQueue(*staticAssignment);
|
refreshStaticAssignmentAndAddToQueue(*staticAssignment);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2414,19 +2414,19 @@ int Application::sendNackPackets() {
|
||||||
char packet[MAX_PACKET_SIZE];
|
char packet[MAX_PACKET_SIZE];
|
||||||
|
|
||||||
// iterates thru all nodes in NodeList
|
// iterates thru all nodes in NodeList
|
||||||
foreach(const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
|
||||||
if (node->getActiveSocket() &&
|
nodeList->eachNode([&](const SharedNodePointer& node){
|
||||||
( node->getType() == NodeType::VoxelServer
|
|
||||||
|| node->getType() == NodeType::EntityServer)
|
if (node->getActiveSocket()
|
||||||
) {
|
&& (node->getType() == NodeType::VoxelServer || node->getType() == NodeType::EntityServer)) {
|
||||||
|
|
||||||
QUuid nodeUUID = node->getUUID();
|
QUuid nodeUUID = node->getUUID();
|
||||||
|
|
||||||
// if there are octree packets from this node that are waiting to be processed,
|
// if there are octree packets from this node that are waiting to be processed,
|
||||||
// don't send a NACK since the missing packets may be among those waiting packets.
|
// don't send a NACK since the missing packets may be among those waiting packets.
|
||||||
if (_octreeProcessor.hasPacketsToProcessFrom(nodeUUID)) {
|
if (_octreeProcessor.hasPacketsToProcessFrom(nodeUUID)) {
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_octreeSceneStatsLock.lockForRead();
|
_octreeSceneStatsLock.lockForRead();
|
||||||
|
@ -2434,7 +2434,7 @@ int Application::sendNackPackets() {
|
||||||
// retreive octree scene stats of this node
|
// retreive octree scene stats of this node
|
||||||
if (_octreeServerSceneStats.find(nodeUUID) == _octreeServerSceneStats.end()) {
|
if (_octreeServerSceneStats.find(nodeUUID) == _octreeServerSceneStats.end()) {
|
||||||
_octreeSceneStatsLock.unlock();
|
_octreeSceneStatsLock.unlock();
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get sequence number stats of node, prune its missing set, and make a copy of the missing set
|
// get sequence number stats of node, prune its missing set, and make a copy of the missing set
|
||||||
|
@ -2475,11 +2475,12 @@ int Application::sendNackPackets() {
|
||||||
numSequenceNumbersAvailable -= numSequenceNumbers;
|
numSequenceNumbersAvailable -= numSequenceNumbers;
|
||||||
|
|
||||||
// send it
|
// send it
|
||||||
NodeList::getInstance()->writeUnverifiedDatagram(packet, dataAt - packet, node);
|
nodeList->writeUnverifiedDatagram(packet, dataAt - packet, node);
|
||||||
packetsSent++;
|
packetsSent++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
return packetsSent;
|
return packetsSent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2512,7 +2513,9 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
|
||||||
int inViewServers = 0;
|
int inViewServers = 0;
|
||||||
int unknownJurisdictionServers = 0;
|
int unknownJurisdictionServers = 0;
|
||||||
|
|
||||||
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
|
||||||
|
nodeList->eachNode([&](const SharedNodePointer& node) {
|
||||||
// only send to the NodeTypes that are serverType
|
// only send to the NodeTypes that are serverType
|
||||||
if (node->getActiveSocket() && node->getType() == serverType) {
|
if (node->getActiveSocket() && node->getType() == serverType) {
|
||||||
totalServers++;
|
totalServers++;
|
||||||
|
@ -2543,7 +2546,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
if (wantExtraDebugging) {
|
if (wantExtraDebugging) {
|
||||||
qDebug("Servers: total %d, in view %d, unknown jurisdiction %d",
|
qDebug("Servers: total %d, in view %d, unknown jurisdiction %d",
|
||||||
|
@ -2570,9 +2573,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
|
||||||
qDebug("perServerPPS: %d perUnknownServer: %d", perServerPPS, perUnknownServer);
|
qDebug("perServerPPS: %d perUnknownServer: %d", perServerPPS, perUnknownServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
nodeList->eachNode([&](const SharedNodePointer& node){
|
||||||
|
|
||||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
|
||||||
// only send to the NodeTypes that are serverType
|
// only send to the NodeTypes that are serverType
|
||||||
if (node->getActiveSocket() && node->getType() == serverType) {
|
if (node->getActiveSocket() && node->getType() == serverType) {
|
||||||
|
|
||||||
|
@ -2660,7 +2661,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
|
||||||
// Feed number of bytes to corresponding channel of the bandwidth meter
|
// Feed number of bytes to corresponding channel of the bandwidth meter
|
||||||
_bandwidthMeter.outputStream(BandwidthMeter::VOXELS).updateValue(packetLength);
|
_bandwidthMeter.outputStream(BandwidthMeter::VOXELS).updateValue(packetLength);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -163,7 +163,7 @@ void MetavoxelSystem::render() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetavoxelSystem::refreshVoxelData() {
|
void MetavoxelSystem::refreshVoxelData() {
|
||||||
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
NodeList::getInstance()->eachNode([](const SharedNodePointer& node){
|
||||||
if (node->getType() == NodeType::MetavoxelServer) {
|
if (node->getType() == NodeType::MetavoxelServer) {
|
||||||
QMutexLocker locker(&node->getMutex());
|
QMutexLocker locker(&node->getMutex());
|
||||||
MetavoxelSystemClient* client = static_cast<MetavoxelSystemClient*>(node->getLinkedData());
|
MetavoxelSystemClient* client = static_cast<MetavoxelSystemClient*>(node->getLinkedData());
|
||||||
|
@ -171,7 +171,7 @@ void MetavoxelSystem::refreshVoxelData() {
|
||||||
QMetaObject::invokeMethod(client, "refreshVoxelData");
|
QMetaObject::invokeMethod(client, "refreshVoxelData");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class RayHeightfieldIntersectionVisitor : public RayIntersectionVisitor {
|
class RayHeightfieldIntersectionVisitor : public RayIntersectionVisitor {
|
||||||
|
@ -685,7 +685,7 @@ MetavoxelClient* MetavoxelSystem::createClient(const SharedNodePointer& node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetavoxelSystem::guideToAugmented(MetavoxelVisitor& visitor, bool render) {
|
void MetavoxelSystem::guideToAugmented(MetavoxelVisitor& visitor, bool render) {
|
||||||
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
NodeList::getInstance()->eachNode([&visitor, &render](const SharedNodePointer& node) {
|
||||||
if (node->getType() == NodeType::MetavoxelServer) {
|
if (node->getType() == NodeType::MetavoxelServer) {
|
||||||
QMutexLocker locker(&node->getMutex());
|
QMutexLocker locker(&node->getMutex());
|
||||||
MetavoxelSystemClient* client = static_cast<MetavoxelSystemClient*>(node->getLinkedData());
|
MetavoxelSystemClient* client = static_cast<MetavoxelSystemClient*>(node->getLinkedData());
|
||||||
|
@ -699,7 +699,7 @@ void MetavoxelSystem::guideToAugmented(MetavoxelVisitor& visitor, bool render) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Throttle::Throttle() :
|
Throttle::Throttle() :
|
||||||
|
|
|
@ -53,8 +53,7 @@ void NodeBounds::draw() {
|
||||||
float selectedScale = 0;
|
float selectedScale = 0;
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
nodeList->eachNode([&](const SharedNodePointer& node){
|
||||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
|
||||||
NodeType_t nodeType = node->getType();
|
NodeType_t nodeType = node->getType();
|
||||||
|
|
||||||
if (nodeType == NodeType::VoxelServer && _showVoxelNodes) {
|
if (nodeType == NodeType::VoxelServer && _showVoxelNodes) {
|
||||||
|
@ -62,7 +61,7 @@ void NodeBounds::draw() {
|
||||||
} else if (nodeType == NodeType::EntityServer && _showEntityNodes) {
|
} else if (nodeType == NodeType::EntityServer && _showEntityNodes) {
|
||||||
serverJurisdictions = &entityServerJurisdictions;
|
serverJurisdictions = &entityServerJurisdictions;
|
||||||
} else {
|
} else {
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QUuid nodeUUID = node->getUUID();
|
QUuid nodeUUID = node->getUUID();
|
||||||
|
@ -124,7 +123,7 @@ void NodeBounds::draw() {
|
||||||
} else {
|
} else {
|
||||||
serverJurisdictions->unlock();
|
serverJurisdictions->unlock();
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
if (selectedNode) {
|
if (selectedNode) {
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
|
|
@ -248,8 +248,8 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser
|
||||||
QLocale locale(QLocale::English);
|
QLocale locale(QLocale::English);
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
nodeList->eachNode([&](const SharedNodePointer& node){
|
||||||
|
|
||||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
|
||||||
// only send to the NodeTypes that are NodeType_t_VOXEL_SERVER
|
// only send to the NodeTypes that are NodeType_t_VOXEL_SERVER
|
||||||
if (node->getType() == serverType) {
|
if (node->getType() == serverType) {
|
||||||
serverCount++;
|
serverCount++;
|
||||||
|
@ -420,7 +420,7 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser
|
||||||
serverDetails << linkDetails.str();
|
serverDetails << linkDetails.str();
|
||||||
_labels[_voxelServerLables[serverCount - 1]]->setText(serverDetails.str().c_str());
|
_labels[_voxelServerLables[serverCount - 1]]->setText(serverDetails.str().c_str());
|
||||||
} // is VOXEL_SERVER
|
} // is VOXEL_SERVER
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void OctreeStatsDialog::reject() {
|
void OctreeStatsDialog::reject() {
|
||||||
|
|
|
@ -329,7 +329,7 @@ void Stats::display(
|
||||||
unsigned long totalPingVoxel = 0;
|
unsigned long totalPingVoxel = 0;
|
||||||
int voxelServerCount = 0;
|
int voxelServerCount = 0;
|
||||||
|
|
||||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
nodeList->eachNode([&totalPingVoxel, &pingVoxelMax, &voxelServerCount](const SharedNodePointer& node){
|
||||||
// TODO: this should also support entities
|
// TODO: this should also support entities
|
||||||
if (node->getType() == NodeType::VoxelServer) {
|
if (node->getType() == NodeType::VoxelServer) {
|
||||||
totalPingVoxel += node->getPingMs();
|
totalPingVoxel += node->getPingMs();
|
||||||
|
@ -338,7 +338,7 @@ void Stats::display(
|
||||||
pingVoxelMax = node->getPingMs();
|
pingVoxelMax = node->getPingMs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
if (voxelServerCount) {
|
if (voxelServerCount) {
|
||||||
pingVoxel = totalPingVoxel/voxelServerCount;
|
pingVoxel = totalPingVoxel/voxelServerCount;
|
||||||
|
|
|
@ -42,7 +42,8 @@ SharedObjectPointer MetavoxelClientManager::findFirstRaySpannerIntersection(cons
|
||||||
const glm::vec3& direction, const AttributePointer& attribute, float& distance) {
|
const glm::vec3& direction, const AttributePointer& attribute, float& distance) {
|
||||||
SharedObjectPointer closestSpanner;
|
SharedObjectPointer closestSpanner;
|
||||||
float closestDistance = FLT_MAX;
|
float closestDistance = FLT_MAX;
|
||||||
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
|
||||||
|
NodeList::getInstance()->eachNode([&](const SharedNodePointer& node){
|
||||||
if (node->getType() == NodeType::MetavoxelServer) {
|
if (node->getType() == NodeType::MetavoxelServer) {
|
||||||
QMutexLocker locker(&node->getMutex());
|
QMutexLocker locker(&node->getMutex());
|
||||||
MetavoxelClient* client = static_cast<MetavoxelClient*>(node->getLinkedData());
|
MetavoxelClient* client = static_cast<MetavoxelClient*>(node->getLinkedData());
|
||||||
|
@ -56,7 +57,8 @@ SharedObjectPointer MetavoxelClientManager::findFirstRaySpannerIntersection(cons
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
if (closestSpanner) {
|
if (closestSpanner) {
|
||||||
distance = closestDistance;
|
distance = closestDistance;
|
||||||
}
|
}
|
||||||
|
@ -115,7 +117,7 @@ MetavoxelClient* MetavoxelClientManager::createClient(const SharedNodePointer& n
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetavoxelClientManager::guide(MetavoxelVisitor& visitor) {
|
void MetavoxelClientManager::guide(MetavoxelVisitor& visitor) {
|
||||||
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
NodeList::getInstance()->eachNode([&visitor](const SharedNodePointer& node){
|
||||||
if (node->getType() == NodeType::MetavoxelServer) {
|
if (node->getType() == NodeType::MetavoxelServer) {
|
||||||
QMutexLocker locker(&node->getMutex());
|
QMutexLocker locker(&node->getMutex());
|
||||||
MetavoxelClient* client = static_cast<MetavoxelClient*>(node->getLinkedData());
|
MetavoxelClient* client = static_cast<MetavoxelClient*>(node->getLinkedData());
|
||||||
|
@ -123,7 +125,7 @@ void MetavoxelClientManager::guide(MetavoxelVisitor& visitor) {
|
||||||
client->getDataCopy().guide(visitor);
|
client->getDataCopy().guide(visitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
MetavoxelUpdater::MetavoxelUpdater(MetavoxelClientManager* clientManager) :
|
MetavoxelUpdater::MetavoxelUpdater(MetavoxelClientManager* clientManager) :
|
||||||
|
|
|
@ -10,8 +10,9 @@ if (WIN32)
|
||||||
target_link_libraries(${TARGET_NAME} ws2_32.lib)
|
target_link_libraries(${TARGET_NAME} ws2_32.lib)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
# find OpenSSL
|
# find required dependencies
|
||||||
find_package(OpenSSL REQUIRED)
|
find_package(OpenSSL REQUIRED)
|
||||||
|
find_package(TBB REQUIRED)
|
||||||
|
|
||||||
if (APPLE AND ${OPENSSL_INCLUDE_DIR} STREQUAL "/usr/include")
|
if (APPLE AND ${OPENSSL_INCLUDE_DIR} STREQUAL "/usr/include")
|
||||||
# this is a user on OS X using system OpenSSL, which is going to throw warnings since they're deprecating for their common crypto
|
# this is a user on OS X using system OpenSSL, which is going to throw warnings since they're deprecating for their common crypto
|
||||||
|
@ -22,7 +23,10 @@ endif ()
|
||||||
include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}")
|
include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}")
|
||||||
|
|
||||||
# append OpenSSL to our list of libraries to link
|
# append OpenSSL to our list of libraries to link
|
||||||
list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK "${OPENSSL_LIBRARIES}")
|
list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK "${OPENSSL_LIBRARIES}" "${TBB_LIBRARIES}")
|
||||||
|
|
||||||
|
# append libcuckoo includes to our list of includes to bubble
|
||||||
|
list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES "${TBB_INCLUDE_DIRS}")
|
||||||
|
|
||||||
# call macro to link our dependencies and bubble them up via a property on our target
|
# call macro to link our dependencies and bubble them up via a property on our target
|
||||||
link_shared_dependencies()
|
link_shared_dependencies()
|
|
@ -21,6 +21,8 @@
|
||||||
|
|
||||||
#include <LogHandler.h>
|
#include <LogHandler.h>
|
||||||
|
|
||||||
|
#include <tbb/parallel_for.h>
|
||||||
|
|
||||||
#include "AccountManager.h"
|
#include "AccountManager.h"
|
||||||
#include "Assignment.h"
|
#include "Assignment.h"
|
||||||
#include "HifiSockAddr.h"
|
#include "HifiSockAddr.h"
|
||||||
|
@ -68,7 +70,6 @@ LimitedNodeList* LimitedNodeList::getInstance() {
|
||||||
LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short dtlsListenPort) :
|
LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short dtlsListenPort) :
|
||||||
_sessionUUID(),
|
_sessionUUID(),
|
||||||
_nodeHash(),
|
_nodeHash(),
|
||||||
_nodeHashMutex(QMutex::Recursive),
|
|
||||||
_nodeSocket(this),
|
_nodeSocket(this),
|
||||||
_dtlsSocket(NULL),
|
_dtlsSocket(NULL),
|
||||||
_localSockAddr(),
|
_localSockAddr(),
|
||||||
|
@ -328,19 +329,9 @@ int LimitedNodeList::findNodeAndUpdateWithDataFromPacket(const QByteArray& packe
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedNodePointer LimitedNodeList::nodeWithUUID(const QUuid& nodeUUID, bool blockingLock) {
|
SharedNodePointer LimitedNodeList::nodeWithUUID(const QUuid& nodeUUID) {
|
||||||
const int WAIT_TIME = 10; // wait up to 10ms in the try lock case
|
NodeHash::const_iterator it = _nodeHash.find(nodeUUID);
|
||||||
SharedNodePointer node;
|
return it == _nodeHash.cend() ? SharedNodePointer() : it->second;
|
||||||
// if caller wants us to block and guarantee the correct answer, then honor that request
|
|
||||||
if (blockingLock) {
|
|
||||||
// this will block till we can get access
|
|
||||||
QMutexLocker locker(&_nodeHashMutex);
|
|
||||||
node = _nodeHash.value(nodeUUID);
|
|
||||||
} else if (_nodeHashMutex.tryLock(WAIT_TIME)) { // some callers are willing to get wrong answers but not block
|
|
||||||
node = _nodeHash.value(nodeUUID);
|
|
||||||
_nodeHashMutex.unlock();
|
|
||||||
}
|
|
||||||
return node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedNodePointer LimitedNodeList::sendingNodeForPacket(const QByteArray& packet) {
|
SharedNodePointer LimitedNodeList::sendingNodeForPacket(const QByteArray& packet) {
|
||||||
|
@ -350,21 +341,21 @@ SharedNodePointer LimitedNodeList::sendingNodeForPacket(const QByteArray& packet
|
||||||
return nodeWithUUID(nodeUUID);
|
return nodeWithUUID(nodeUUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeHash LimitedNodeList::getNodeHash() {
|
|
||||||
QMutexLocker locker(&_nodeHashMutex);
|
|
||||||
return NodeHash(_nodeHash);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LimitedNodeList::eraseAllNodes() {
|
void LimitedNodeList::eraseAllNodes() {
|
||||||
qDebug() << "Clearing the NodeList. Deleting all nodes in list.";
|
qDebug() << "Clearing the NodeList. Deleting all nodes in list.";
|
||||||
|
|
||||||
QMutexLocker locker(&_nodeHashMutex);
|
QSet<SharedNodePointer> killedNodes;
|
||||||
|
eachNode([&killedNodes](const SharedNodePointer& node){
|
||||||
|
killedNodes.insert(node);
|
||||||
|
});
|
||||||
|
|
||||||
NodeHash::iterator nodeItem = _nodeHash.begin();
|
// iterate the current nodes, emit that they are dying and remove them from the hash
|
||||||
|
_nodeMutex.lockForWrite();
|
||||||
|
_nodeHash.clear();
|
||||||
|
_nodeMutex.unlock();
|
||||||
|
|
||||||
// iterate the nodes in the list
|
foreach(const SharedNodePointer& killedNode, killedNodes) {
|
||||||
while (nodeItem != _nodeHash.end()) {
|
handleNodeKill(killedNode);
|
||||||
nodeItem = killNodeAtHashIterator(nodeItem);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,20 +364,17 @@ void LimitedNodeList::reset() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LimitedNodeList::killNodeWithUUID(const QUuid& nodeUUID) {
|
void LimitedNodeList::killNodeWithUUID(const QUuid& nodeUUID) {
|
||||||
QMutexLocker locker(&_nodeHashMutex);
|
NodeHash::iterator it = _nodeHash.find(nodeUUID);
|
||||||
|
if (it != _nodeHash.end()) {
|
||||||
|
SharedNodePointer matchingNode = it->second;
|
||||||
|
|
||||||
NodeHash::iterator nodeItemToKill = _nodeHash.find(nodeUUID);
|
QWriteLocker writeLocker(&_nodeMutex);
|
||||||
if (nodeItemToKill != _nodeHash.end()) {
|
_nodeHash.unsafe_erase(it);
|
||||||
killNodeAtHashIterator(nodeItemToKill);
|
|
||||||
|
handleNodeKill(matchingNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeHash::iterator LimitedNodeList::killNodeAtHashIterator(NodeHash::iterator& nodeItemToKill) {
|
|
||||||
qDebug() << "Killed" << *nodeItemToKill.value();
|
|
||||||
emit nodeKilled(nodeItemToKill.value());
|
|
||||||
return _nodeHash.erase(nodeItemToKill);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LimitedNodeList::processKillNode(const QByteArray& dataByteArray) {
|
void LimitedNodeList::processKillNode(const QByteArray& dataByteArray) {
|
||||||
// read the node id
|
// read the node id
|
||||||
QUuid nodeUUID = QUuid::fromRfc4122(dataByteArray.mid(numBytesForPacketHeader(dataByteArray), NUM_BYTES_RFC4122_UUID));
|
QUuid nodeUUID = QUuid::fromRfc4122(dataByteArray.mid(numBytesForPacketHeader(dataByteArray), NUM_BYTES_RFC4122_UUID));
|
||||||
|
@ -395,66 +383,44 @@ void LimitedNodeList::processKillNode(const QByteArray& dataByteArray) {
|
||||||
killNodeWithUUID(nodeUUID);
|
killNodeWithUUID(nodeUUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LimitedNodeList::handleNodeKill(const SharedNodePointer& node) {
|
||||||
|
qDebug() << "Killed" << *node;
|
||||||
|
emit nodeKilled(node);
|
||||||
|
}
|
||||||
|
|
||||||
SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType,
|
SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType,
|
||||||
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) {
|
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) {
|
||||||
_nodeHashMutex.lock();
|
try {
|
||||||
|
SharedNodePointer matchingNode = _nodeHash.at(uuid);
|
||||||
|
|
||||||
if (!_nodeHash.contains(uuid)) {
|
matchingNode->setPublicSocket(publicSocket);
|
||||||
|
matchingNode->setLocalSocket(localSocket);
|
||||||
|
|
||||||
|
return matchingNode;
|
||||||
|
} catch (std::out_of_range) {
|
||||||
// we didn't have this node, so add them
|
// we didn't have this node, so add them
|
||||||
Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket);
|
Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket);
|
||||||
SharedNodePointer newNodeSharedPointer(newNode, &QObject::deleteLater);
|
SharedNodePointer newNodeSharedPointer(newNode, &QObject::deleteLater);
|
||||||
|
|
||||||
_nodeHash.insert(newNode->getUUID(), newNodeSharedPointer);
|
_nodeHash.insert(UUIDNodePair(newNode->getUUID(), newNodeSharedPointer));
|
||||||
|
|
||||||
_nodeHashMutex.unlock();
|
|
||||||
|
|
||||||
qDebug() << "Added" << *newNode;
|
qDebug() << "Added" << *newNode;
|
||||||
|
|
||||||
emit nodeAdded(newNodeSharedPointer);
|
emit nodeAdded(newNodeSharedPointer);
|
||||||
|
|
||||||
return newNodeSharedPointer;
|
return newNodeSharedPointer;
|
||||||
} else {
|
|
||||||
_nodeHashMutex.unlock();
|
|
||||||
|
|
||||||
return updateSocketsForNode(uuid, publicSocket, localSocket);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedNodePointer LimitedNodeList::updateSocketsForNode(const QUuid& uuid,
|
|
||||||
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) {
|
|
||||||
|
|
||||||
SharedNodePointer matchingNode = nodeWithUUID(uuid);
|
|
||||||
|
|
||||||
if (matchingNode) {
|
|
||||||
// perform appropriate updates to this node
|
|
||||||
QMutexLocker locker(&matchingNode->getMutex());
|
|
||||||
|
|
||||||
// check if we need to change this node's public or local sockets
|
|
||||||
if (publicSocket != matchingNode->getPublicSocket()) {
|
|
||||||
matchingNode->setPublicSocket(publicSocket);
|
|
||||||
qDebug() << "Public socket change for node" << *matchingNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (localSocket != matchingNode->getLocalSocket()) {
|
|
||||||
matchingNode->setLocalSocket(localSocket);
|
|
||||||
qDebug() << "Local socket change for node" << *matchingNode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return matchingNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned LimitedNodeList::broadcastToNodes(const QByteArray& packet, const NodeSet& destinationNodeTypes) {
|
unsigned LimitedNodeList::broadcastToNodes(const QByteArray& packet, const NodeSet& destinationNodeTypes) {
|
||||||
unsigned n = 0;
|
unsigned n = 0;
|
||||||
|
|
||||||
foreach (const SharedNodePointer& node, getNodeHash()) {
|
eachNode([&](const SharedNodePointer& node){
|
||||||
// only send to the NodeTypes we are asked to send to.
|
|
||||||
if (destinationNodeTypes.contains(node->getType())) {
|
if (destinationNodeTypes.contains(node->getType())) {
|
||||||
writeDatagram(packet, node);
|
writeDatagram(packet, node);
|
||||||
++n;
|
++n;
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
@ -493,15 +459,9 @@ QByteArray LimitedNodeList::constructPingReplyPacket(const QByteArray& pingPacke
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedNodePointer LimitedNodeList::soloNodeOfType(char nodeType) {
|
SharedNodePointer LimitedNodeList::soloNodeOfType(char nodeType) {
|
||||||
|
return nodeMatchingPredicate([&](const SharedNodePointer& node){
|
||||||
if (memchr(SOLO_NODE_TYPES, nodeType, sizeof(SOLO_NODE_TYPES))) {
|
return node->getType() == nodeType;
|
||||||
foreach (const SharedNodePointer& node, getNodeHash()) {
|
});
|
||||||
if (node->getType() == nodeType) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return SharedNodePointer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LimitedNodeList::getPacketStats(float& packetsPerSecond, float& bytesPerSecond) {
|
void LimitedNodeList::getPacketStats(float& packetsPerSecond, float& bytesPerSecond) {
|
||||||
|
@ -516,28 +476,28 @@ void LimitedNodeList::resetPacketStats() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LimitedNodeList::removeSilentNodes() {
|
void LimitedNodeList::removeSilentNodes() {
|
||||||
|
QSet<SharedNodePointer> killedNodes;
|
||||||
|
|
||||||
_nodeHashMutex.lock();
|
eachNodeHashIterator([&](NodeHash::iterator& it){
|
||||||
|
SharedNodePointer node = it->second;
|
||||||
NodeHash::iterator nodeItem = _nodeHash.begin();
|
|
||||||
|
|
||||||
while (nodeItem != _nodeHash.end()) {
|
|
||||||
SharedNodePointer node = nodeItem.value();
|
|
||||||
|
|
||||||
node->getMutex().lock();
|
node->getMutex().lock();
|
||||||
|
|
||||||
if ((usecTimestampNow() - node->getLastHeardMicrostamp()) > (NODE_SILENCE_THRESHOLD_MSECS * 1000)) {
|
if ((usecTimestampNow() - node->getLastHeardMicrostamp()) > (NODE_SILENCE_THRESHOLD_MSECS * 1000)) {
|
||||||
// call our private method to kill this node (removes it and emits the right signal)
|
// call the NodeHash erase to get rid of this node
|
||||||
nodeItem = killNodeAtHashIterator(nodeItem);
|
it = _nodeHash.unsafe_erase(it);
|
||||||
|
|
||||||
|
killedNodes.insert(node);
|
||||||
} else {
|
} else {
|
||||||
// we didn't kill this node, push the iterator forwards
|
// we didn't erase this node, push the iterator forwards
|
||||||
++nodeItem;
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
node->getMutex().unlock();
|
node->getMutex().unlock();
|
||||||
}
|
});
|
||||||
|
|
||||||
_nodeHashMutex.unlock();
|
foreach(const SharedNodePointer& killedNode, killedNodes) {
|
||||||
|
handleNodeKill(killedNode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t RFC_5389_MAGIC_COOKIE = 0x2112A442;
|
const uint32_t RFC_5389_MAGIC_COOKIE = 0x2112A442;
|
||||||
|
|
|
@ -20,16 +20,18 @@
|
||||||
#include <unistd.h> // not on windows, not needed for mac or windows
|
#include <unistd.h> // not on windows, not needed for mac or windows
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <QtCore/QElapsedTimer>
|
#include <qelapsedtimer.h>
|
||||||
#include <QtCore/QMutex>
|
#include <qreadwritelock.h>
|
||||||
#include <QtCore/QSet>
|
#include <qset.h>
|
||||||
#include <QtCore/QSettings>
|
#include <qsharedpointer.h>
|
||||||
#include <QtCore/QSharedPointer>
|
#include <QtNetwork/qudpsocket.h>
|
||||||
#include <QtNetwork/QHostAddress>
|
#include <QtNetwork/qhostaddress.h>
|
||||||
#include <QtNetwork/QUdpSocket>
|
|
||||||
|
#include <tbb/concurrent_unordered_map.h>
|
||||||
|
|
||||||
#include "DomainHandler.h"
|
#include "DomainHandler.h"
|
||||||
#include "Node.h"
|
#include "Node.h"
|
||||||
|
#include "UUIDHasher.h"
|
||||||
|
|
||||||
const int MAX_PACKET_SIZE = 1500;
|
const int MAX_PACKET_SIZE = 1500;
|
||||||
|
|
||||||
|
@ -49,9 +51,12 @@ class HifiSockAddr;
|
||||||
typedef QSet<NodeType_t> NodeSet;
|
typedef QSet<NodeType_t> NodeSet;
|
||||||
|
|
||||||
typedef QSharedPointer<Node> SharedNodePointer;
|
typedef QSharedPointer<Node> SharedNodePointer;
|
||||||
typedef QHash<QUuid, SharedNodePointer> NodeHash;
|
|
||||||
Q_DECLARE_METATYPE(SharedNodePointer)
|
Q_DECLARE_METATYPE(SharedNodePointer)
|
||||||
|
|
||||||
|
using namespace tbb;
|
||||||
|
typedef std::pair<QUuid, SharedNodePointer> UUIDNodePair;
|
||||||
|
typedef concurrent_unordered_map<QUuid, SharedNodePointer, UUIDHasher> NodeHash;
|
||||||
|
|
||||||
typedef quint8 PingType_t;
|
typedef quint8 PingType_t;
|
||||||
namespace PingType {
|
namespace PingType {
|
||||||
const PingType_t Agnostic = 0;
|
const PingType_t Agnostic = 0;
|
||||||
|
@ -69,7 +74,6 @@ public:
|
||||||
const QUuid& getSessionUUID() const { return _sessionUUID; }
|
const QUuid& getSessionUUID() const { return _sessionUUID; }
|
||||||
void setSessionUUID(const QUuid& sessionUUID);
|
void setSessionUUID(const QUuid& sessionUUID);
|
||||||
|
|
||||||
|
|
||||||
void rebindNodeSocket();
|
void rebindNodeSocket();
|
||||||
QUdpSocket& getNodeSocket() { return _nodeSocket; }
|
QUdpSocket& getNodeSocket() { return _nodeSocket; }
|
||||||
QUdpSocket& getDTLSSocket();
|
QUdpSocket& getDTLSSocket();
|
||||||
|
@ -91,16 +95,13 @@ public:
|
||||||
|
|
||||||
void(*linkedDataCreateCallback)(Node *);
|
void(*linkedDataCreateCallback)(Node *);
|
||||||
|
|
||||||
NodeHash getNodeHash();
|
|
||||||
int size() const { return _nodeHash.size(); }
|
int size() const { return _nodeHash.size(); }
|
||||||
|
|
||||||
SharedNodePointer nodeWithUUID(const QUuid& nodeUUID, bool blockingLock = true);
|
SharedNodePointer nodeWithUUID(const QUuid& nodeUUID);
|
||||||
SharedNodePointer sendingNodeForPacket(const QByteArray& packet);
|
SharedNodePointer sendingNodeForPacket(const QByteArray& packet);
|
||||||
|
|
||||||
SharedNodePointer addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType,
|
SharedNodePointer addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType,
|
||||||
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
|
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
|
||||||
SharedNodePointer updateSocketsForNode(const QUuid& uuid,
|
|
||||||
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
|
|
||||||
|
|
||||||
const HifiSockAddr& getLocalSockAddr() const { return _localSockAddr; }
|
const HifiSockAddr& getLocalSockAddr() const { return _localSockAddr; }
|
||||||
|
|
||||||
|
@ -125,6 +126,40 @@ public:
|
||||||
|
|
||||||
void sendHeartbeatToIceServer(const HifiSockAddr& iceServerSockAddr,
|
void sendHeartbeatToIceServer(const HifiSockAddr& iceServerSockAddr,
|
||||||
QUuid headerID = QUuid(), const QUuid& connectRequestID = QUuid());
|
QUuid headerID = QUuid(), const QUuid& connectRequestID = QUuid());
|
||||||
|
|
||||||
|
template<typename NodeLambda>
|
||||||
|
void eachNode(NodeLambda functor) {
|
||||||
|
QReadLocker readLock(&_nodeMutex);
|
||||||
|
|
||||||
|
for (NodeHash::const_iterator it = _nodeHash.cbegin(); it != _nodeHash.cend(); ++it) {
|
||||||
|
functor(it->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename BreakableNodeLambda>
|
||||||
|
void eachNodeBreakable(BreakableNodeLambda functor) {
|
||||||
|
QReadLocker readLock(&_nodeMutex);
|
||||||
|
|
||||||
|
for (NodeHash::const_iterator it = _nodeHash.cbegin(); it != _nodeHash.cend(); ++it) {
|
||||||
|
if (!functor(it->second)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename PredLambda>
|
||||||
|
SharedNodePointer nodeMatchingPredicate(const PredLambda predicate) {
|
||||||
|
QReadLocker readLock(&_nodeMutex);
|
||||||
|
|
||||||
|
for (NodeHash::const_iterator it = _nodeHash.cbegin(); it != _nodeHash.cend(); ++it) {
|
||||||
|
if (predicate(it->second)) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SharedNodePointer();
|
||||||
|
}
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void reset();
|
void reset();
|
||||||
void eraseAllNodes();
|
void eraseAllNodes();
|
||||||
|
@ -151,14 +186,13 @@ protected:
|
||||||
qint64 writeDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr,
|
qint64 writeDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr,
|
||||||
const QUuid& connectionSecret);
|
const QUuid& connectionSecret);
|
||||||
|
|
||||||
NodeHash::iterator killNodeAtHashIterator(NodeHash::iterator& nodeItemToKill);
|
|
||||||
|
|
||||||
|
|
||||||
void changeSocketBufferSizes(int numBytes);
|
void changeSocketBufferSizes(int numBytes);
|
||||||
|
|
||||||
|
void handleNodeKill(const SharedNodePointer& node);
|
||||||
|
|
||||||
QUuid _sessionUUID;
|
QUuid _sessionUUID;
|
||||||
NodeHash _nodeHash;
|
NodeHash _nodeHash;
|
||||||
QMutex _nodeHashMutex;
|
QReadWriteLock _nodeMutex;
|
||||||
QUdpSocket _nodeSocket;
|
QUdpSocket _nodeSocket;
|
||||||
QUdpSocket* _dtlsSocket;
|
QUdpSocket* _dtlsSocket;
|
||||||
HifiSockAddr _localSockAddr;
|
HifiSockAddr _localSockAddr;
|
||||||
|
@ -167,6 +201,17 @@ protected:
|
||||||
int _numCollectedPackets;
|
int _numCollectedPackets;
|
||||||
int _numCollectedBytes;
|
int _numCollectedBytes;
|
||||||
QElapsedTimer _packetStatTimer;
|
QElapsedTimer _packetStatTimer;
|
||||||
|
|
||||||
|
template<typename IteratorLambda>
|
||||||
|
void eachNodeHashIterator(IteratorLambda functor) {
|
||||||
|
QWriteLocker writeLock(&_nodeMutex);
|
||||||
|
NodeHash::iterator it = _nodeHash.begin();
|
||||||
|
|
||||||
|
while (it != _nodeHash.end()) {
|
||||||
|
functor(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_LimitedNodeList_h
|
#endif // hifi_LimitedNodeList_h
|
||||||
|
|
|
@ -94,30 +94,48 @@ void Node::updateClockSkewUsec(int clockSkewSample) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::setPublicSocket(const HifiSockAddr& publicSocket) {
|
void Node::setPublicSocket(const HifiSockAddr& publicSocket) {
|
||||||
|
if (publicSocket != _publicSocket) {
|
||||||
if (_activeSocket == &_publicSocket) {
|
if (_activeSocket == &_publicSocket) {
|
||||||
// if the active socket was the public socket then reset it to NULL
|
// if the active socket was the public socket then reset it to NULL
|
||||||
_activeSocket = NULL;
|
_activeSocket = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_publicSocket.isNull()) {
|
||||||
|
qDebug() << "Public socket change for node" << *this;
|
||||||
|
}
|
||||||
|
|
||||||
_publicSocket = publicSocket;
|
_publicSocket = publicSocket;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::setLocalSocket(const HifiSockAddr& localSocket) {
|
void Node::setLocalSocket(const HifiSockAddr& localSocket) {
|
||||||
|
if (localSocket != _localSocket) {
|
||||||
if (_activeSocket == &_localSocket) {
|
if (_activeSocket == &_localSocket) {
|
||||||
// if the active socket was the local socket then reset it to NULL
|
// if the active socket was the local socket then reset it to NULL
|
||||||
_activeSocket = NULL;
|
_activeSocket = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_localSocket.isNull()) {
|
||||||
|
qDebug() << "Local socket change for node" << *this;
|
||||||
|
}
|
||||||
|
|
||||||
_localSocket = localSocket;
|
_localSocket = localSocket;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::setSymmetricSocket(const HifiSockAddr& symmetricSocket) {
|
void Node::setSymmetricSocket(const HifiSockAddr& symmetricSocket) {
|
||||||
|
if (symmetricSocket != _symmetricSocket) {
|
||||||
if (_activeSocket == &_symmetricSocket) {
|
if (_activeSocket == &_symmetricSocket) {
|
||||||
// if the active socket was the symmetric socket then reset it to NULL
|
// if the active socket was the symmetric socket then reset it to NULL
|
||||||
_activeSocket = NULL;
|
_activeSocket = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_symmetricSocket.isNull()) {
|
||||||
|
qDebug() << "Symmetric socket change for node" << *this;
|
||||||
|
}
|
||||||
|
|
||||||
_symmetricSocket = symmetricSocket;
|
_symmetricSocket = symmetricSocket;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::activateLocalSocket() {
|
void Node::activateLocalSocket() {
|
||||||
|
|
|
@ -449,12 +449,12 @@ void NodeList::pingPunchForInactiveNode(const SharedNodePointer& node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeList::pingInactiveNodes() {
|
void NodeList::pingInactiveNodes() {
|
||||||
foreach (const SharedNodePointer& node, getNodeHash()) {
|
eachNode([this](const SharedNodePointer& node){
|
||||||
if (!node->getActiveSocket()) {
|
if (!node->getActiveSocket()) {
|
||||||
// we don't have an active link to this node, ping it to set that up
|
// we don't have an active link to this node, ping it to set that up
|
||||||
pingPunchForInactiveNode(node);
|
pingPunchForInactiveNode(node);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeList::activateSocketFromNodeCommunication(const QByteArray& packet, const SharedNodePointer& sendingNode) {
|
void NodeList::activateSocketFromNodeCommunication(const QByteArray& packet, const SharedNodePointer& sendingNode) {
|
||||||
|
|
|
@ -68,7 +68,7 @@ SequenceNumberStats::ArrivalInfo SequenceNumberStats::sequenceNumberReceived(qui
|
||||||
int expectedInt = (int)expected;
|
int expectedInt = (int)expected;
|
||||||
|
|
||||||
// check if the gap between incoming and expected is reasonable, taking possible rollover into consideration
|
// check if the gap between incoming and expected is reasonable, taking possible rollover into consideration
|
||||||
int absGap = std::abs(incomingInt - expectedInt);
|
int absGap = abs(incomingInt - expectedInt);
|
||||||
if (absGap >= UINT16_RANGE - MAX_REASONABLE_SEQUENCE_GAP) {
|
if (absGap >= UINT16_RANGE - MAX_REASONABLE_SEQUENCE_GAP) {
|
||||||
// rollover likely occurred between incoming and expected.
|
// rollover likely occurred between incoming and expected.
|
||||||
// correct the larger of the two so that it's within [-UINT16_RANGE, -1] while the other remains within [0, UINT16_RANGE-1]
|
// correct the larger of the two so that it's within [-UINT16_RANGE, -1] while the other remains within [0, UINT16_RANGE-1]
|
||||||
|
|
26
libraries/networking/src/UUIDHasher.h
Normal file
26
libraries/networking/src/UUIDHasher.h
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
//
|
||||||
|
// UUIDHasher.h
|
||||||
|
// libraries/networking/src
|
||||||
|
//
|
||||||
|
// Created by Stephen Birarda on 2014-11-05.
|
||||||
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_UUIDHasher_h
|
||||||
|
#define hifi_UUIDHasher_h
|
||||||
|
|
||||||
|
#include "UUID.h"
|
||||||
|
|
||||||
|
class UUIDHasher {
|
||||||
|
public:
|
||||||
|
size_t operator()(const QUuid& uuid) const {
|
||||||
|
return uuid.data1 ^ uuid.data2 ^ (uuid.data3 << 16)
|
||||||
|
^ ((uuid.data4[0] << 24) | (uuid.data4[1] << 16) | (uuid.data4[2] << 8) | uuid.data4[3])
|
||||||
|
^ ((uuid.data4[4] << 24) | (uuid.data4[5] << 16) | (uuid.data4[6] << 8) | uuid.data4[7]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_UUIDHasher_h
|
|
@ -38,14 +38,12 @@ bool JurisdictionListener::queueJurisdictionRequest() {
|
||||||
int sizeOut = populatePacketHeader(reinterpret_cast<char*>(bufferOut), PacketTypeJurisdictionRequest);
|
int sizeOut = populatePacketHeader(reinterpret_cast<char*>(bufferOut), PacketTypeJurisdictionRequest);
|
||||||
int nodeCount = 0;
|
int nodeCount = 0;
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList::getInstance()->eachNode([&](const SharedNodePointer& node) {
|
||||||
|
|
||||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
|
||||||
if (node->getType() == getNodeType() && node->getActiveSocket()) {
|
if (node->getType() == getNodeType() && node->getActiveSocket()) {
|
||||||
_packetSender.queuePacketForSending(node, QByteArray(reinterpret_cast<char*>(bufferOut), sizeOut));
|
_packetSender.queuePacketForSending(node, QByteArray(reinterpret_cast<char*>(bufferOut), sizeOut));
|
||||||
nodeCount++;
|
nodeCount++;
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
if (nodeCount > 0){
|
if (nodeCount > 0){
|
||||||
_packetSender.setPacketsPerSecond(nodeCount);
|
_packetSender.setPacketsPerSecond(nodeCount);
|
||||||
|
|
|
@ -51,11 +51,8 @@ OctreeEditPacketSender::~OctreeEditPacketSender() {
|
||||||
bool OctreeEditPacketSender::serversExist() const {
|
bool OctreeEditPacketSender::serversExist() const {
|
||||||
bool hasServers = false;
|
bool hasServers = false;
|
||||||
bool atLeastOneJurisdictionMissing = false; // assume the best
|
bool atLeastOneJurisdictionMissing = false; // assume the best
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
|
||||||
|
|
||||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
NodeList::getInstance()->eachNodeBreakable([&](const SharedNodePointer& node){
|
||||||
|
|
||||||
// only send to the NodeTypes that are getMyNodeType()
|
|
||||||
if (node->getType() == getMyNodeType() && node->getActiveSocket()) {
|
if (node->getType() == getMyNodeType() && node->getActiveSocket()) {
|
||||||
|
|
||||||
QUuid nodeUUID = node->getUUID();
|
QUuid nodeUUID = node->getUUID();
|
||||||
|
@ -71,10 +68,13 @@ bool OctreeEditPacketSender::serversExist() const {
|
||||||
}
|
}
|
||||||
hasServers = true;
|
hasServers = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (atLeastOneJurisdictionMissing) {
|
if (atLeastOneJurisdictionMissing) {
|
||||||
break; // no point in looking further...
|
return false; // no point in looking further - return false from anonymous function
|
||||||
}
|
} else {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return (hasServers && !atLeastOneJurisdictionMissing);
|
return (hasServers && !atLeastOneJurisdictionMissing);
|
||||||
}
|
}
|
||||||
|
@ -85,13 +85,11 @@ void OctreeEditPacketSender::queuePacketToNode(const QUuid& nodeUUID, unsigned c
|
||||||
size_t length, qint64 satoshiCost) {
|
size_t length, qint64 satoshiCost) {
|
||||||
|
|
||||||
bool wantDebug = false;
|
bool wantDebug = false;
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList::getInstance()->eachNode([&](const SharedNodePointer& node){
|
||||||
|
|
||||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
|
||||||
// only send to the NodeTypes that are getMyNodeType()
|
// only send to the NodeTypes that are getMyNodeType()
|
||||||
if (node->getType() == getMyNodeType() &&
|
if (node->getType() == getMyNodeType()
|
||||||
((node->getUUID() == nodeUUID) || (nodeUUID.isNull()))) {
|
&& ((node->getUUID() == nodeUUID) || (nodeUUID.isNull()))
|
||||||
if (node->getActiveSocket()) {
|
&& node->getActiveSocket()) {
|
||||||
|
|
||||||
// pack sequence number
|
// pack sequence number
|
||||||
int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast<char*>(buffer));
|
int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast<char*>(buffer));
|
||||||
|
@ -128,8 +126,7 @@ void OctreeEditPacketSender::queuePacketToNode(const QUuid& nodeUUID, unsigned c
|
||||||
" transitTimeSoFar=" << transitTime << " usecs";
|
" transitTimeSoFar=" << transitTime << " usecs";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OctreeEditPacketSender::processPreServerExistsPackets() {
|
void OctreeEditPacketSender::processPreServerExistsPackets() {
|
||||||
|
@ -195,7 +192,7 @@ void OctreeEditPacketSender::queuePacketToNodes(unsigned char* buffer, size_t le
|
||||||
// for a different server... So we need to actually manage multiple queued packets... one
|
// for a different server... So we need to actually manage multiple queued packets... one
|
||||||
// for each server
|
// for each server
|
||||||
|
|
||||||
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
NodeList::getInstance()->eachNode([&](const SharedNodePointer& node){
|
||||||
// only send to the NodeTypes that are getMyNodeType()
|
// only send to the NodeTypes that are getMyNodeType()
|
||||||
if (node->getActiveSocket() && node->getType() == getMyNodeType()) {
|
if (node->getActiveSocket() && node->getType() == getMyNodeType()) {
|
||||||
QUuid nodeUUID = node->getUUID();
|
QUuid nodeUUID = node->getUUID();
|
||||||
|
@ -210,7 +207,7 @@ void OctreeEditPacketSender::queuePacketToNodes(unsigned char* buffer, size_t le
|
||||||
queuePacketToNode(nodeUUID, buffer, length, satoshiCost);
|
queuePacketToNode(nodeUUID, buffer, length, satoshiCost);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -247,7 +244,8 @@ void OctreeEditPacketSender::queueOctreeEditMessage(PacketType type, unsigned ch
|
||||||
// for a different server... So we need to actually manage multiple queued packets... one
|
// for a different server... So we need to actually manage multiple queued packets... one
|
||||||
// for each server
|
// for each server
|
||||||
_packetsQueueLock.lock();
|
_packetsQueueLock.lock();
|
||||||
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
|
||||||
|
NodeList::getInstance()->eachNode([&](const SharedNodePointer& node){
|
||||||
// only send to the NodeTypes that are getMyNodeType()
|
// only send to the NodeTypes that are getMyNodeType()
|
||||||
if (node->getActiveSocket() && node->getType() == getMyNodeType()) {
|
if (node->getActiveSocket() && node->getType() == getMyNodeType()) {
|
||||||
QUuid nodeUUID = node->getUUID();
|
QUuid nodeUUID = node->getUUID();
|
||||||
|
@ -296,7 +294,7 @@ void OctreeEditPacketSender::queueOctreeEditMessage(PacketType type, unsigned ch
|
||||||
packetBuffer._satoshiCost += satoshiCost;
|
packetBuffer._satoshiCost += satoshiCost;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
_packetsQueueLock.unlock();
|
_packetsQueueLock.unlock();
|
||||||
|
|
||||||
|
@ -382,7 +380,7 @@ void OctreeEditPacketSender::processNackPacket(const QByteArray& packet) {
|
||||||
// retrieve packet from history
|
// retrieve packet from history
|
||||||
const QByteArray* packet = sentPacketHistory.getPacket(sequenceNumber);
|
const QByteArray* packet = sentPacketHistory.getPacket(sequenceNumber);
|
||||||
if (packet) {
|
if (packet) {
|
||||||
const SharedNodePointer& node = NodeList::getInstance()->getNodeHash().value(sendingNodeUUID);
|
const SharedNodePointer& node = NodeList::getInstance()->nodeWithUUID(sendingNodeUUID);
|
||||||
queuePacketForSending(node, *packet);
|
queuePacketForSending(node, *packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ void OctreeHeadlessViewer::queryOctree() {
|
||||||
int inViewServers = 0;
|
int inViewServers = 0;
|
||||||
int unknownJurisdictionServers = 0;
|
int unknownJurisdictionServers = 0;
|
||||||
|
|
||||||
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
NodeList::getInstance()->eachNode([&](const SharedNodePointer& node){
|
||||||
// only send to the NodeTypes that are serverType
|
// only send to the NodeTypes that are serverType
|
||||||
if (node->getActiveSocket() && node->getType() == serverType) {
|
if (node->getActiveSocket() && node->getType() == serverType) {
|
||||||
totalServers++;
|
totalServers++;
|
||||||
|
@ -113,7 +113,7 @@ void OctreeHeadlessViewer::queryOctree() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
if (wantExtraDebugging) {
|
if (wantExtraDebugging) {
|
||||||
qDebug("Servers: total %d, in view %d, unknown jurisdiction %d",
|
qDebug("Servers: total %d, in view %d, unknown jurisdiction %d",
|
||||||
|
@ -141,12 +141,10 @@ void OctreeHeadlessViewer::queryOctree() {
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
nodeList->eachNode([&](const SharedNodePointer& node){
|
||||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
|
||||||
// only send to the NodeTypes that are serverType
|
// only send to the NodeTypes that are serverType
|
||||||
if (node->getActiveSocket() && node->getType() == serverType) {
|
if (node->getActiveSocket() && node->getType() == serverType) {
|
||||||
|
|
||||||
|
|
||||||
// get the server bounds for this server
|
// get the server bounds for this server
|
||||||
QUuid nodeUUID = node->getUUID();
|
QUuid nodeUUID = node->getUUID();
|
||||||
|
|
||||||
|
@ -234,7 +232,7 @@ void OctreeHeadlessViewer::queryOctree() {
|
||||||
// make sure we still have an active socket
|
// make sure we still have an active socket
|
||||||
nodeList->writeUnverifiedDatagram(reinterpret_cast<const char*>(queryPacket), packetLength, node);
|
nodeList->writeUnverifiedDatagram(reinterpret_cast<const char*>(queryPacket), packetLength, node);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -514,7 +514,7 @@ void ScriptEngine::run() {
|
||||||
|
|
||||||
// write audio packet to AudioMixer nodes
|
// write audio packet to AudioMixer nodes
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
foreach(const SharedNodePointer& node, nodeList->getNodeHash()) {
|
nodeList->eachNode([this, &nodeList, &audioPacket, &numPreSequenceNumberBytes](const SharedNodePointer& node){
|
||||||
// only send to nodes of type AudioMixer
|
// only send to nodes of type AudioMixer
|
||||||
if (node->getType() == NodeType::AudioMixer) {
|
if (node->getType() == NodeType::AudioMixer) {
|
||||||
// pack sequence number
|
// pack sequence number
|
||||||
|
@ -524,7 +524,7 @@ void ScriptEngine::run() {
|
||||||
// send audio packet
|
// send audio packet
|
||||||
nodeList->writeDatagram(audioPacket, node);
|
nodeList->writeDatagram(audioPacket, node);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,15 +12,7 @@
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#include <qcoreapplication.h>
|
||||||
#include <process.h>
|
|
||||||
#define getpid _getpid
|
|
||||||
#define getppid _getpid // hack to build
|
|
||||||
#define pid_t int // hack to build
|
|
||||||
#elif __linux__
|
|
||||||
#include <unistd.h> // for getpid() on linux
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <qdebug.h>
|
#include <qdebug.h>
|
||||||
#include <qtimer.h>
|
#include <qtimer.h>
|
||||||
|
|
||||||
|
@ -122,14 +114,8 @@ QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& cont
|
||||||
prefixString.append(QString(" [%1]").arg(dateString));
|
prefixString.append(QString(" [%1]").arg(dateString));
|
||||||
|
|
||||||
if (_shouldOutputPID) {
|
if (_shouldOutputPID) {
|
||||||
prefixString.append(QString(" [%1").arg(getpid()));
|
prefixString.append(QString(" [%1]").arg(QCoreApplication::instance()->applicationPid()));
|
||||||
|
|
||||||
pid_t parentProcessID = getppid();
|
|
||||||
if (parentProcessID != 0) {
|
|
||||||
prefixString.append(QString(":%1]").arg(parentProcessID));
|
|
||||||
} else {
|
|
||||||
prefixString.append("]");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_targetName.isEmpty()) {
|
if (!_targetName.isEmpty()) {
|
||||||
|
|
Loading…
Reference in a new issue