Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
codemercenary committed Dec 24, 2014
2 parents ed7719b + e84f8d9 commit 5adbc25
Show file tree
Hide file tree
Showing 336 changed files with 8,230 additions and 38,301 deletions.
19 changes: 18 additions & 1 deletion autowiring/AutoPacket.h
Expand Up @@ -22,6 +22,7 @@
#include EXCEPTION_PTR_HEADER

class AutoPacket;
class AutoPacketInternal;
class AutoPacketFactory;
class AutoPacketProfiler;
struct AutoFilterDescriptor;
Expand All @@ -47,6 +48,7 @@ class AutoPacket:
AutoPacket(AutoPacket&&) = delete;

public:
// Must hold the lock to 'factory' when calling this constructor
AutoPacket(AutoPacketFactory& factory, std::shared_ptr<void>&& outstanding);
~AutoPacket();

Expand All @@ -58,9 +60,12 @@ class AutoPacket:
protected:
// A pointer back to the factory that created us. Used for recording lifetime statistics.
const std::shared_ptr<AutoPacketFactory> m_parentFactory;

// The successor to this packet
std::shared_ptr<AutoPacketInternal> m_successor;

// Hold the time point at which this packet was last initalized.
const std::chrono::high_resolution_clock::time_point m_initTime;
std::chrono::high_resolution_clock::time_point m_initTime;

// Outstanding count local and remote holds:
const std::shared_ptr<void> m_outstanding;
Expand Down Expand Up @@ -507,6 +512,12 @@ class AutoPacket:
return GetSubscribers(typeid(auto_id<T>));
}

/// <returns>All decoration dispositions</returns>
/// <remarks>
/// This method is useful for getting a picture of the entire disposition graph
/// </remarks>
std::list<DecorationDisposition> GetDispositions() const;

/// <returns>All decoration dispositions associated with the data type</returns>
/// <remarks>
/// This method is useful for determining whether flow conditions (broadcast, pipes
Expand All @@ -517,6 +528,12 @@ class AutoPacket:
return GetDispositions(typeid(auto_id<T>));
}

/// <summary>
/// Returns the next packet that will be issued by the packet factory in this context relative to this context
/// </summary>
std::shared_ptr<AutoPacketInternal> SuccessorInternal(void);
std::shared_ptr<AutoPacket> Successor(void);

/// <returns>True if the indicated type has been requested for use by some consumer</returns>
template<class T>
bool HasSubscribers(void) const {
Expand Down
22 changes: 10 additions & 12 deletions autowiring/AutoPacketFactory.h
Expand Up @@ -16,6 +16,7 @@ struct AdjacencyEntry;
class AutoPacketFactory;
class Deferred;
class DispatchQueue;
class AutoPacketInternal;

/// <summary>
/// A configurable factory class for pipeline packets with a built-in object pool
Expand All @@ -40,15 +41,12 @@ class AutoPacketFactory:

// State change notification
std::condition_variable m_stateCondition;

// Have we been signaled to stop
bool m_wasStopped;

// Outstanding reference if this factory is currently running:
std::shared_ptr<Object> m_outstanding;

// Internal outstanding reference for issued packet:
std::weak_ptr<void> m_outstandingInternal;

// The last packet issued from this factory
std::shared_ptr<AutoPacketInternal> m_nextPacket;

// Collection of known subscribers
typedef std::unordered_set<AutoFilterDescriptor, std::hash<AutoFilterDescriptor>> t_autoFilterSet;
Expand Down Expand Up @@ -79,11 +77,9 @@ class AutoPacketFactory:
}

// CoreRunnable overrides:
bool Start(std::shared_ptr<Object> outstanding) override;
void Stop(bool graceful = false) override;
void Wait(void) override;
bool IsRunning(void) const override { return m_outstanding && !m_wasStopped; };
bool ShouldStop(void) const override { return m_wasStopped; };
bool OnStart(void) override;
void OnStop(bool graceful) override;
void DoAdditionalWait(void) override;

/// <summary>
/// Causes this AutoPacketFactory to release all of its packet subscribers
Expand Down Expand Up @@ -134,8 +130,10 @@ class AutoPacketFactory:
/// </summary>
std::shared_ptr<AutoPacket> NewPacket(void);

std::shared_ptr<AutoPacketInternal> ConstructPacket(void);

/// <returns>the number of outstanding AutoPackets</returns>
size_t GetOutstanding(void) const;
size_t GetOutstandingPacketCount(void) const;

/// <summary>
/// Called by each AutoPacket's Finalize method to allow the factory
Expand Down
122 changes: 122 additions & 0 deletions autowiring/AutoPacketGraph.h
@@ -0,0 +1,122 @@
// Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved.
#pragma once
#include "AutoFilterDescriptor.h"
#include "AutoPacket.h"
#include "AutoPacketFactory.h"
#include "Autowired.h"
#include "AutowiringEvents.h"
#include "CoreRunnable.h"
#include STL_UNORDERED_MAP


/// <summary>
/// Represents an edge in the graph from a type to an AutoFilter
/// </summary>
struct DeliveryEdge
{
// The type info
const std::type_info* type_info;

// The AutoFilterDescriptor
AutoFilterDescriptor descriptor;

// Specifies if the argument is an input (type -> descriptor) or output (descriptor -> type)
bool input;

// For the unordered map/hash comparison
bool operator==(const DeliveryEdge& rhs) const {
return
type_info == rhs.type_info &&
descriptor == rhs.descriptor &&
input == rhs.input;
}
};

/// <summary>
/// Using the same hash function as the AutoFilterDescriptor
/// </summary>
namespace std {
template<>
struct hash<DeliveryEdge>
{
size_t operator()(const DeliveryEdge& edge) const {
return (size_t) edge.descriptor.GetAutoFilter()->ptr();
}
};
}

/// <summary>
/// Graphical visualization of AutoPackets
/// </summary>
class AutoPacketGraph:
public AutowiringEvents,
public CoreRunnable
{
public:
AutoPacketGraph();

typedef std::unordered_map<DeliveryEdge, size_t, std::hash<DeliveryEdge>> t_deliveryEdges;

protected:
// A mapping of an edge to the number of times it was delivered
t_deliveryEdges m_deliveryGraph;

// A lock for this type
mutable std::mutex m_lock;

// Reference to the AutoPacketFactory
AutoRequired<AutoPacketFactory> m_factory;

/// <summary>
/// Demangle a type name as well as stripping "auto_in< >"
/// </summary>
/// <remarks>
/// The ">" that encloses the templates will have extra spaces between them, for instance
///
/// auto_in<Class>
/// auto_in<Class<T> >
/// auto_in<Class1<Class2, Class3<Class4> > >
///
/// All we care about is matching "^auto_in<(.*)>$"
/// </remarks>
std::string DemangleTypeName(const std::type_info* type_info) const;

/// <summary>
/// Scan all of the objects and add any AutoFilter's from all of the objects in a system.
/// </summary>
/// <remarks>
/// This function will scan all of the objects (and rescan) and only add new edges to our graph.
/// </remarks>
void LoadEdges();

/// <summary>
/// Record the delivery of a packet and increment the number of times the packet has been delivered
/// </summary>
void RecordDelivery(const std::type_info* ti, const AutoFilterDescriptor& descriptor, bool input);

/// AutowiringEvents overrides
virtual void NewContext(CoreContext&) override {}
virtual void ExpiredContext(CoreContext&) override {}
virtual void EventFired(CoreContext&, const std::type_info&) override {}
virtual void NewObject(CoreContext&, const ObjectTraits&) override;

/// CoreRunnable overrides
virtual bool OnStart(void) override;

public:
/// <summary>
/// Get a copy of the packet via AutoFilter
/// </summary>
void AutoFilter(AutoPacket& packet);

/// <summary>
/// Write the graph to a file in graphviz format
/// </summary>
/// <param name="filename">
/// The name of the file to write the graph to
/// </param>
/// <param name="numPackets">
/// Include the number of times the packet was delivered
/// </param>
bool WriteGV(const std::string& filename, bool numPackets = false) const;
};
19 changes: 4 additions & 15 deletions autowiring/AutoRestarter.h
Expand Up @@ -52,21 +52,18 @@ class AutoRestarter:
const AutoRestarterConfig config;

// CoreRunnable overrides:
bool Start(std::shared_ptr<Object> outstanding) override {
bool OnStart() override {
// Start the enclosed context, do nothing else
auto ctxt = GetContext();
if(ctxt && config.startWhenCreated)
ctxt->Initiate();
return true;
}

void Stop(bool graceful) override {
void OnStop(bool graceful) override {
std::lock_guard<std::mutex> lk(m_lock);
m_context.reset();
}
bool IsRunning(void) const override { return false; }
bool ShouldStop(void) const override { return true; }
void Wait(void) override {}

private:
mutable std::mutex m_lock;
Expand All @@ -84,21 +81,13 @@ class AutoRestarter:
// Parent restarter, we hand control here when we're stopped
AutoRestarter<Sigil>& ar;

bool Start(std::shared_ptr<Object> outstanding) override {
m_outstanding = outstanding;
bool OnStart(void) override {
return true;
}

void Stop(bool graceful) override {
void OnStop(bool graceful) override {
ar.OnContextStopped(*this);
m_outstanding.reset();
}

std::shared_ptr<Object> m_outstanding;

bool IsRunning(void) const override { return false; }
bool ShouldStop(void) const override { return false; }
void Wait(void) {}
};

protected:
Expand Down
6 changes: 5 additions & 1 deletion autowiring/Autowired.h
Expand Up @@ -261,10 +261,14 @@ class AutowiredFast:

// !!!!! Read comment in AutoRequired if you get a compiler error here !!!!!
AutowiredFast(const std::shared_ptr<CoreContext>& ctxt = CoreContext::CurrentContext()) {
if(ctxt)
if (ctxt)
ctxt->FindByTypeRecursive(*this);
}

AutowiredFast(const CoreContext* pCtxt) {
pCtxt->FindByTypeRecursive(*this);
}

operator bool(void) const {
return IsAutowired();
}
Expand Down
50 changes: 10 additions & 40 deletions autowiring/BasicThread.h
Expand Up @@ -167,11 +167,6 @@ class BasicThread:
/// </remarks>
bool ThreadSleep(std::chrono::nanoseconds timeout);

public:
// Accessor methods:
bool ShouldStop(void) const override;
bool IsRunning(void) const override;

/// <summary>
/// Causes a new thread to be created in which the Run method will be invoked
/// </summary>
Expand All @@ -181,8 +176,13 @@ class BasicThread:
/// Start will not be called from more than one place on the same object. The thread
/// will be invoked from the context which was active at the time the thread was created.
/// </remarks>
virtual bool Start(std::shared_ptr<Object> outstanding);
bool OnStart() override;

void OnStop(bool graceful) override;

void DoAdditionalWait() override;

public:
/// <summary>
/// Begins the core thread
/// </summary>
Expand All @@ -194,45 +194,15 @@ class BasicThread:
virtual void Run() = 0;

/// <summary>
/// Waits until the core thread is launched and then terminates
/// </summary>
/// <remarks>
/// Unlike Join, this method may be invoked even if the CoreThread isn't running
/// </remarks>
void Wait(void) override;

/// <summary>
/// Timed version of Wait
/// Provides derived members with a way of obtaining notification that this thread is being stopped
/// </summary>
/// <returns>False if the timeout elapsed, true otherwise</returns>
bool WaitFor(std::chrono::nanoseconds duration);

/// <summary>
/// Timed version of Wait
/// </summary>
/// <returns>False if the timeout elapsed, true otherwise</returns>
template<class TimeType>
bool WaitUntil(TimeType timepoint);

/// <summary>
/// Event which may be used to perform custom handling when the thread is told to stop
/// </summary>
/// <param name="graceful">Set to true to rundown the dispatch queue before quitting</param>
/// <remarks>
/// This method is called when the thread should stop. When invoked, the value of
/// CoreThread::ShouldStop is guaranteed to be true.
///
/// Callers are not required to call CoreThread::OnStop. This method is guaranteed to do
/// nothing by default.
/// Callers must not perform any time-consuming operations in this callback; the method may be called
/// from a time-sensitive context and unacceptable system performance could result if long-duration
/// operations are undertaken here.
/// </remarks>
virtual void OnStop(void) {}

/// <summary>
/// This is an override method that will cause ShouldStop to return true,
/// regardless of what the global stop setting is.
/// </summary>
virtual void Stop(bool graceful = false);

/// <summary>
/// Forces all Autowiring threads to reidentify themselves
/// </summary>
Expand Down
12 changes: 6 additions & 6 deletions autowiring/C++11/boost_future.h
Expand Up @@ -9,10 +9,10 @@
#include <boost/thread/future.hpp>

namespace std {
using boost::future;
using boost::future_status;
using boost::promise;
using boost::future_error;
using boost::async;
using boost::launch;
using AUTOWIRING_BOOST_NAME::future;
using AUTOWIRING_BOOST_NAME::future_status;
using AUTOWIRING_BOOST_NAME::promise;
using AUTOWIRING_BOOST_NAME::future_error;
using AUTOWIRING_BOOST_NAME::async;
using AUTOWIRING_BOOST_NAME::launch;
}

0 comments on commit 5adbc25

Please sign in to comment.