diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 46b2a2243c..0c19d3f5c6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2577,7 +2577,7 @@ void Application::update(float deltaTime) { // parse voxel packets if (!_enableProcessVoxelsThread) { - _voxelReceiver.threadRoutine(); + _voxelReceiver.process(); } //loop through all the other avatars and simulate them... diff --git a/libraries/shared/src/GenericThread.cpp b/libraries/shared/src/GenericThread.cpp new file mode 100644 index 0000000000..d75e16627c --- /dev/null +++ b/libraries/shared/src/GenericThread.cpp @@ -0,0 +1,62 @@ +// +// GenericThread.cpp +// shared +// +// Created by Brad Hefta-Gaub on 8/12/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// +// Generic Threaded or non-threaded processing class +// + +#include "GenericThread.h" + +GenericThread::GenericThread() : + _stopThread(false), + _isThreaded(false) // assume non-threaded, must call initialize() +{ +} + +GenericThread::~GenericThread() { + terminate(); +} + +void GenericThread::initialize(bool isThreaded) { + _isThreaded = isThreaded; + if (_isThreaded) { + pthread_create(&_thread, NULL, GenericThreadEntry, this); + } +} + +void GenericThread::terminate() { + if (_isThreaded) { + _stopThread = true; + pthread_join(_thread, NULL); + _isThreaded = false; + } +} + +void* GenericThread::threadRoutine() { + while (!_stopThread) { + + // override this function to do whatever your class actually does, return false to exit thread early + if (!process()) { + break; + } + + // In non-threaded mode, this will break each time you call it so it's the + // callers responsibility to continuously call this method + if (!_isThreaded) { + break; + } + } + + if (_isThreaded) { + pthread_exit(0); + } + return NULL; +} + +extern "C" void* GenericThreadEntry(void* arg) { + GenericThread* genericThread = (GenericThread*)arg; + return genericThread->threadRoutine(); +} \ No newline at end of file diff --git a/libraries/shared/src/GenericThread.h b/libraries/shared/src/GenericThread.h new file mode 100644 index 0000000000..e0c372fe00 --- /dev/null +++ b/libraries/shared/src/GenericThread.h @@ -0,0 +1,41 @@ +// +// GenericThread.h +// shared +// +// Created by Brad Hefta-Gaub on 8/12/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// +// Generic Threaded or non-threaded processing class. +// + +#ifndef __shared__GenericThread__ +#define __shared__GenericThread__ + +#include + +class GenericThread { +public: + GenericThread(); + virtual ~GenericThread(); + + // Call to start the thread + void initialize(bool isThreaded); + + // override this function to do whatever your class actually does, return false to exit thread early + virtual bool process() = 0; + + // Call when you're ready to stop the thread + void terminate(); + + // If you're running in non-threaded mode, you must call this regularly + void* threadRoutine(); + +private: + bool _stopThread; + bool _isThreaded; + pthread_t _thread; +}; + +extern "C" void* GenericThreadEntry(void* arg); + +#endif // __shared__GenericThread__ diff --git a/libraries/shared/src/PacketReceiver.cpp b/libraries/shared/src/PacketReceiver.cpp index 9bf4764ebb..39542eb21e 100644 --- a/libraries/shared/src/PacketReceiver.cpp +++ b/libraries/shared/src/PacketReceiver.cpp @@ -10,61 +10,15 @@ #include "PacketReceiver.h" -PacketReceiver::PacketReceiver() : - _stopThread(false), - _isThreaded(false) // assume non-threaded, must call initialize() -{ -} - -PacketReceiver::~PacketReceiver() { - terminate(); -} - -void PacketReceiver::initialize(bool isThreaded) { - _isThreaded = isThreaded; - if (_isThreaded) { - pthread_create(&_thread, NULL, PacketReceiverThreadEntry, this); - } -} - -void PacketReceiver::terminate() { - if (_isThreaded) { - _stopThread = true; - pthread_join(_thread, NULL); - _isThreaded = false; - } -} - void PacketReceiver::queuePacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) { _packets.push_back(NetworkPacket(senderAddress, packetData, packetLength)); } -void PacketReceiver::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) { - // Default implementation does nothing... packet is discarded -} - -void* PacketReceiver::threadRoutine() { - while (!_stopThread) { - while (_packets.size() > 0) { - NetworkPacket& packet = _packets.front(); - processPacket(packet.getSenderAddress(), packet.getData(), packet.getLength()); - _packets.erase(_packets.begin()); - } - - // In non-threaded mode, this will break each time you call it so it's the - // callers responsibility to continuously call this method - if (!_isThreaded) { - break; - } +bool PacketReceiver::process() { + while (_packets.size() > 0) { + NetworkPacket& packet = _packets.front(); + processPacket(packet.getSenderAddress(), packet.getData(), packet.getLength()); + _packets.erase(_packets.begin()); } - - if (_isThreaded) { - pthread_exit(0); - } - return NULL; + return true; // keep running till they terminate us } - -extern "C" void* PacketReceiverThreadEntry(void* arg) { - PacketReceiver* packetReceiver = (PacketReceiver*)arg; - return packetReceiver->threadRoutine(); -} \ No newline at end of file diff --git a/libraries/shared/src/PacketReceiver.h b/libraries/shared/src/PacketReceiver.h index f236b362e6..c4dabb4906 100644 --- a/libraries/shared/src/PacketReceiver.h +++ b/libraries/shared/src/PacketReceiver.h @@ -11,32 +11,21 @@ #ifndef __shared__PacketReceiver__ #define __shared__PacketReceiver__ +#include "GenericThread.h" #include "NetworkPacket.h" -class PacketReceiver { +class PacketReceiver : public GenericThread { public: - PacketReceiver(); - virtual ~PacketReceiver(); // Call this when your network receive gets a packet void queuePacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength); // implement this to process the incoming packets - virtual void processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength); + virtual void processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) = 0; - // Call to start the thread - void initialize(bool isThreaded); - - // Call when you're ready to stop the thread - void terminate(); - - // If you're running in non-threaded mode, you must call this regularly - void* threadRoutine(); + virtual bool process(); private: - bool _stopThread; - bool _isThreaded; - pthread_t _thread; std::vector _packets; };