HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Function object passing for a task scheduler

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
schedulerpassingfunctionforobjecttask

Problem

Here is my full implementation of a generic Functor-like class:

```
#ifndef FUNCTIONHPP
#define FUNCTIONHPP

#include "Types.hpp"
#include
#include

BEGIN_NAMESPACE //This is a define in "Types.hpp"

namespace FN_HELPERS
{
template
struct seq
{
};
template
struct gens : gens
{
};
template
struct gens
{
typedef seq type;
};

//Global Function Pointer Return Type Identification
template
struct returnType;

template
struct returnType
{
typedef R type;
};

template
struct returnType
{
typedef R type;
};

};

//A generic functor to pass between threads
class Function
{
public:
Function() {}
virtual ~Function() {}
Function(const Function&) = delete;
void operator=(const Function&) = delete;
virtual void call()=0;
virtual void* returnValue()=0;
};

template
class GlobalFunction : public Function
{
public:
GlobalFunction(F func,Args&&... args) : m_func(func),
m_args(std::forward(args)...)
{
}
virtual ~GlobalFunction()
{
}
GlobalFunction(const GlobalFunction&) = delete;
void operator=(const GlobalFunction&) = delete;
virtual void call()
{
callFunction(typename FN_HELPERS::gens::type());
}
virtual void* returnValue()
{
return static_cast(&m_returnValue);
}
template
void callFunction(FN_HELPERS::seq)
{
m_returnValue = (*m_func)(std::get(m_args) ...);
}
private:
F m_func;
R m_returnValue;
std::tuple m_args;

};

template
class GlobalFunction : public Function
{
public:
GlobalFunction(F func,Args&&... args) : m_func(func),
m_args(std::forward(args)...)
{
}
virtual ~GlobalFunction()
{
}
GlobalFunction(const GlobalFunction&) = delete;
void operator=(const GlobalFunction&) = de

Solution

Really don't like this.

In the old days (15 years ago) this was used as a trick to help support non conforming compilers that did not have namespace. That's not really relevant now and you use namespace on the next line.

BEGIN_NAMESPACE //This is a define in "Types.hpp"

namespace FN_HELPERS


These helper functions look like they are already supported by the standard std::integer_sequence.

template
struct seq;
template
struct gens : gens;
template
struct gens;


Return types from anonymous functions are covered by std::promise and std::future.

//Global Function Pointer Return Type Identification
template 
struct returnType;

template 
struct returnType;

template 
struct returnType;


Don't see the need to define the default constructor here.

class Function
{
    public:
    Function() {}
    virtual ~Function() {}
    Function(const Function&) = delete;
    void operator=(const Function&) = delete;
    virtual void call()=0;
    virtual void* returnValue()=0;
};


The compiler generated one should work just fine.
But seems like you are re-building the std::function class.

After all that nice template code:

//Create function object
//F - Function Pointer
#define S_FN(F, ... ) \
    _wrapGFn(F, ##__VA_ARGS__)


You now resort to a macro!

Great. But nn_send() has error codes you need to check. You should never use functions like this directly. As they don't guarantee to send all the data first try. This is something that goes in a loop:

Also you need to pass the address of f. &f otherwise you are sending the bytes pointed to by f (after it is cast to void). So that fails. Also your use of C-cast here is horrible. You were using C++ casts before (why change now). Its also un-necessary. All pointers auto convert when used as a void.

Function* f = S_FN(&someFunction,someArg);
nn_send(sockfd,(void*)f,sizeof(f),0); //Send it


A lot of the same problems with the read.

You should check the return value. Use inside a loop to make sure you send it all. You should pass a pointer to buf (as you are writing over that pointer). No need for buf to be a void* that just means an extra cast (which again is a C-Cast).

void* buf;
nn_recv(sockfd,buf,sizeof(Function*),0);
Function* f = (Function*)buf;
f->call();

Code Snippets

BEGIN_NAMESPACE //This is a define in "Types.hpp"

namespace FN_HELPERS
template<int ...>
struct seq;
template<int N,int ...S>
struct gens : gens<N-1,N-1,S...>;
template<int ...S>
struct gens<0, S...>;
//Global Function Pointer Return Type Identification
template <typename R>
struct returnType;

template <typename R, typename ...Args>
struct returnType<R (*)(Args...)>;

template <typename R,typename ...Args>
struct returnType<R (*)(Args...,...)>;
class Function
{
    public:
    Function() {}
    virtual ~Function() {}
    Function(const Function&) = delete;
    void operator=(const Function&) = delete;
    virtual void call()=0;
    virtual void* returnValue()=0;
};
//Create function object
//F - Function Pointer
#define S_FN(F, ... ) \
    _wrapGFn(F, ##__VA_ARGS__)

Context

StackExchange Code Review Q#54943, answer score: 3

Revisions (0)

No revisions yet.