With C++20 coroutines, as a toy example, I thought it would be easy to make a coroutine that returns a task<T> that co_awaits a sleep before co_returning. It looks like Folly can do it?: https://blog.the-pans.com/build-folly-coro/ but maybe cppcoro doesn't?
I realize C++20 coroutines are a raw compiler feature with no standard libraries yet. Does cppcoro support an awaitable sleep? If not, are there other libraries (or is there a one-pager) that I can play with on Compiler Explorer?
You can create a function that will return an awaitable object:
template <typename DurationT>
auto sleep(const DurationT& d) {
struct awaitable : std::suspend_always {
DurationT duration_;
awaitable(const DurationT& duration)
: duration_(duration) {}
void await_suspend(std::coroutine_handle<>) {
std::this_thread::sleep_for(duration_);
}
};
return awaitable {d};
}
Or overload an await_transform from your promise type.
Sample: https://godbolt.org/z/hKP7oezv7
Related
I have a lot of native classes that accept some form of callbacks, usually a boost::signals2::slot-object.
But for simplicity, lets assume the class:
class Test
{
// set a callback that will be invoked at an unspecified time
// will be removed when Test class dies
void SetCallback(std::function<void(bool)> callback);
}
Now I have a managed class that wraps this native class, and I would like to pass a callback method to the native class.
public ref class TestWrapper
{
public:
TestWrapper()
: _native(new Test())
{
}
~TestWrapper()
{
delete _native;
}
private:
void CallbackMethod(bool value);
Test* _native;
};
now usually what I would do is the following:
Declare a method in the managed wrapper that is the callback I want.
Create a managed delegate object to this method.
Use GetFunctionPointerForDelegate to obtain a pointer to a function
Cast the pointer to the correct signature
Pass the pointer to the native class as callback.
I also keep the delegate alive since I fear it will be garbage collected and I will have a dangling function pointer (is this assumption correct?)
this looks kind of like this:
_managedDelegateMember = gcnew ManagedEventHandler(this, &TestWrapper::Callback);
System::IntPtr stubPointer = Marshal::GetFunctionPointerForDelegate(_managedDelegateMember);
UnmanagedEventHandlerFunctionPointer functionPointer = static_cast<UnmanagedEventHandlerFunctionPointer >(stubPointer.ToPointer());
_native->SetCallback(functionPointer);
I Would like to reduce the amount of code and not have to perform any casts nor declare any delegate types. I want to use a lambda expression with no delegate.
This is my new approach:
static void SetCallbackInternal(TestWrapper^ self)
{
gcroot<TestWrapper^> instance(self);
self->_native->SetCallback([instance](bool value)
{
// access managed class from within native code
instance->Value = value;
}
);
}
Declare a static method that accepts this in order to be able to use C++11 lambda.
Use gcroot to capture the managed class in the lambda and extend its lifetime for as long as the lambda is alive.
No casts, no additional delegate type nor members, minimal extra allocation.
Question:
Is this approach safe? I'm fearing I'm missing something and that this can cause a memory leak / undefined behavior in some unanticipated scenario.
EDIT:
this approach leads to a MethodAccessException when the lambda calls a private method of its managed wrapper class. seems like this method must at least be internal.
I think that you should not be using gcroot but a shared pointer. Shared pointer are made to keep an object alive as long as someone is using it.
You should also use a more c++ style in your whole code by replacing raw pointer with smart pointer and template instead of std::function (a lambda can be stored in a compile time type).
For example using the code you posted :
class Test
{
// set a callback that will be invoked at an unspecified time
// will be removed when Test class dies
template <class T>
void SetCallback(T callback); // Replaced std::function<void(bool)> with T
}
public ref class TestWrapper
{
public:
TestWrapper()
: _native()
{}
private:
void CallbackMethod(bool value);
std::unique_ptr<Test> _native; // Replaced Test* with std::unique_ptr<Test>
};
After replacing the old method with this new method all over my code base, I can report that it is safe, more succinct, and as far as I can tell, no memory leaks occur.
Hence I highly recommend this method for passing managed callbacks to native code.
The only caveats I found were the following:
Using lambda expressions forces the use of a static method as a helper for the callback registration. This is kinda hacky. It is unclear to me why the C++-CLI compiler does no permit lambda expressions within standard methods.
The method invoked by the lambda must be marked internal so to not throw MethodAccessException upon invocation. This is sort of make sense as it is not called within the class scope itself. but still, delegates / lambdas with C# don't have that limitation.
I am aware of the lack of reflection and basic template mechanics in C++ so the example below can't work. But maybe there's a hack to achieve the intended purpose in another way?
template <typename OwnerClass>
struct Template
{
OwnerClass *owner;
};
struct Base
{
virtual void funct ()
{
Template <decltype(*this)> temp;
// ...
}
};
struct Derived : public Base
{
void whatever ()
{
// supposed to infer this class and use Template<Derived>
// any chance some macro or constexpr magic could help?
funct();
}
};
In the example, Derived::whatever() calls virtual method Base::funct() and wants it to pass its own class name (Derived) to a template. The compiler complains "'owner' declared as a pointer to a reference of type 'Base &'". Not only does decltype(*this) not provide a typename but a reference, the compiler also can't know in advance that funct is called from Derived, which would require funct() to be made a template.
If funct() was a template however, each derived class needs to pass its own name with every call, which is pretty verbose and redundant.
Is there any hack to get around this limitation and make calls to funct() infer the typename of the calling class? Maybe constexpr or macros to help the compiler infer the correct type and reduce verbosity in derived classes?
You should use CRTP Pattern (Curiously Recurring Template Pattern) for inheritance.
Define a base class:
struct CBase {
virtual ~CBase() {}
virtual void function() = 0;
};
Define a prepared to CRTP class:
template<typename T>
struct CBaseCrtp : public CBase {
virtual ~CBaseCrtp() {}
void function() override {
using DerivedType = T;
//do stuff
}
};
Inherit from the CRTP one:
struct Derived : public CBaseCrtp<Derived> {
};
It should work. The only way to know the Derived type is to give it to the base!
Currently, this can't be done. Base is a Base and nothing else at the time Template <decltype(*this)> is instantiated. You are trying to mix the static type system for an inheritance hierarchy inherently not resolved before runtime. This very same mechanism is the reason for not calling virtual member functions of an object during its construction.
At some point, this limitation might change in the future. One step towards this is demonstrated in the Deducing this proposal.
I am working on a COM-style complier cross-compatible plugin framework relying on compatible virtual table implementations for ABI compatibility.
I define interfaces containing only pure virtual member functions and an overridden delete operator to channel destruction to the place of implementation.
This works well with extern "C" factory functions instantiating the plugin implementation of the interface and returning an interface-type pointer.
However, I was wondering if smart pointers wouldn't be a more modern way to manage the lifetime of the plugin object. I think I have actually managed to
create a standard-layout shared_ptr/weak_ptr that uses a reference count object defined and implemented the same way as the plugin interfaces.
It looks something like this:
class IRefCount
{
public:
virtual void incRef() = 0;
virtual void decRef() = 0;
virtual bool incRefIfNZ() = 0;
virtual void incWRef() = 0;
virtual void decWRef() = 0;
virtual long uses() const = 0;
protected:
~ref_count_base() = default; //prohibit automatic storage
}
template <typename Ty>
class shared_ptr
{
private:
Ty* ptr_;
IRefCount* ref_count_;
public:
//member functions as defined by C++11 spec
}
Three questions:
Before the smart pointer the factory function looked like this:
extern "C" IPlugin* factory() { try { return new Plugin(); } catch (...) { return nullptr; } }
Now, it looks like this:
extern "C" shared_ptr<IPlugin> factory() { try { return shared_ptr<IPlugin>(new Plugin()); } catch (...) { return nullptr; } }
VS2013 is giving me warning C4190: 'factory' has C-linkage specified, but returns UDT 'shared_ptr' which is incompatible with C. According to MSDN this is OK, provided that both caller and callee are C++.
Are there any other potential issues with returning standard-layout objects from "C" linkage functions?
Calling conventions. Should I be specifying __stdcall for all pure-virtual interface functions and factory functions?
I am using <atomic> for the reference count. I am writing platform-independent code and I have not yet tried compiling for ARM. According to http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dht0008a/ch01s02s01.html armcc does not implement std::atomic. Any better compilers/stl out there?
I have a simple task class:
template<typename TType>
class YHMTask
{
public:
YHMTask() {};
template<typename TLambdaFun>
auto then(TLambdaFun f) -> std::future<decltype(f(mTask.get()))>
{
std::move(mTask);
return std::async(std::launch::async, f, mTask.get());
}
std::future<TType> mTask;
private:
};
In this code, .then can be used and return a std::future.
But I want .then to return another YHMTask so that I can call .then after .then.
I tried to change .then code to follow:
template<typename TLambdaFun>
auto then(TLambdaFun f) -> YHMTask<decltype(f())>
{
std::move(mTask);
std::async(std::launch::async, f, mTask.get());
YHMTask<decltype(f())> yhmTask(std::move(this));
return yhmTask;
}
And call .then like this:
auto testTask = YHMCreateTask(PostAsync(L"", L"")).then([=](wstring str)
{
return 1;
});
Compilier give me this error:
error C2672: 'YHMTask<std::wstring>::then': no matching overloaded function found
error C2893: Failed to specialize function template 'YHMTask<unknown-type> YHMTask<std::wstring>::then(TLambdaFun)'
How should I do?
When you create yhmTask you are moving this, which is a pointer. There is no constructor for YHMTask that takes a pointer to a YHMTask so the template specialization fails. You should dereference this before moving it:
YHMTask<decltype(f())> yhmTask(std::move(*this));
Sounds like you are interested in extending std::future to have .then(). I recommend taking a look at Futures for C++ at Facebook. It does what your attempting to do and more.
Lets you chain a sequence tasks using then:
Future<double> fut =
fooFuture(input)
.then(futureA)
.then(futureB)
.then(futureC)
.then(d)
.then([](OutputD outputD) { // lambdas are ok too
return outputD * M_PI;
});
Also provides other compositional building blocks such as collect, map, and reduce. Git repo here. Looks like C++17 may also have support for the .then construct.
Is there any possible way to access the socket handle inside a boost asio async completion handler ? i looked at the boost asio placeholders but there is no variable which stores the socket handle.
You can just arrange for it, anyway you would outside boost or asio.
To bind a function that takes e.g. a socket to expose a void() function you can use bind:
int foo(std::string const& s, int);
std::function<void()> adapted = std::bind(foo, "hello world", 42);
So, usually you'd have code similar to this:
boost::asio::async_connect(socket_.lowest_layer(), endpoint_iterator,
boost::bind(&client::handle_connect, this, boost::asio::placeholders::error));
Note, by using bind and this, we've bound a member function to the completion handler:
struct client
{
// ....
void handle_connect(boost::system::error_code err)
{
// you can just use `this->socket_` here
// ...
}
};
This implies that in handle_connect we can just use the socket_ member variable.
However, if you want to make things complicated you can use free functions as well
boost::asio::async_connect(socket_.lowest_layer(), endpoint_iterator,
boost::bind(&free_handle_connect, boost::ref(socket_), boost::asio::placeholders::error));
Now the implied handler function looks like
static void free_handle_connect(
boost::asio::ip::tcp::socket& socket_,
boost::system::error_code err)
{
// using `socket_` as it was passed in
int fd = _socket.native_handle_type();
}