boost asio and libcurl mutiple handler - boost

im learning libcurl and boost:asio from this nice post http://www.lijoantony.com/?p=76
though i do have one question about the source code at:
sample code
the main function looks like:
int main(int argc, char **argv)
{
GlobalInfo g;
CURLMcode rc;
(void)argc;
(void)argv;
memset(&g, 0, sizeof(GlobalInfo));
g.multi = curl_multi_init();
curl_multi_setopt(g.multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
curl_multi_setopt(g.multi, CURLMOPT_SOCKETDATA, &g);
curl_multi_setopt(g.multi, CURLMOPT_TIMERFUNCTION, multi_timer_cb);
curl_multi_setopt(g.multi, CURLMOPT_TIMERDATA, &g);
new_conn((char *)"http://us.download.nvidia.com/XFree86/Linux-x86_64/331.79/NVIDIA-Linux-x86_64-331.79.run", &g); /* add a URL */
/* enter io_service run loop */
io_service.run();
curl_multi_cleanup(g.multi);
fprintf(MSG_OUT, "\ndone.\n");
return 0;
}
i see there is no place calling the curl function curl_multi_perform()
how does the tasks get started at the very begining?

I see there is no place calling the curl function curl_multi_perform()
This is because this sample code uses an alternative API called curl_multi_socket_action:
curl_multi_socket_action is then used instead of curl_multi_perform.
(see the MULTI_SOCKET section of the official documentation for more details)
how does the tasks get started at the very begining?
The magic occurs thanks to the CURLMOPT_TIMERFUNCTION option, curl_multi_add_handle function and corresponding timer logic.
If you refer to the static void new_conn(char *url, GlobalInfo *g ) function you can see that:
static void new_conn(char *url, GlobalInfo *g )
{
/* ... */
rc = curl_multi_add_handle(g->multi, conn->easy);
mcode_or_die("new_conn: curl_multi_add_handle", rc);
/* note that the add_handle() will set a time-out to trigger very soon so
that the necessary socket_action() call will be called by this app */
}
So in practice everything starts by calling new_conn(...) which in turn will trigger multi_timer_cb which then calls timer_cb.
And timer_cb performs the curl_multi_socket_action.

Related

Creating custom gcc attribute to instrument specific functions: whitelisting, not blacklisting

I'm using gcc's -finstrument-functions option. To minimize the overhead, I want to instrument only a few functions. However, gcc only lets you blacklist functions (with the no_instrument_function attribute, or by providing a list of paths). It doesn't let you whitelist functions.
So I wrote a small gcc plugin adding an instrument_function attribute. This lets me set the instrumentation "flag" for a specific function (or, rather, clear the no instrumentation flag):
tree handle_instrument_function_attribute(
tree * node,
tree name,
tree args,
int flags,
bool * no_add_attrs)
{
tree decl = *node;
DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT(decl) = 0;
return NULL_TREE;
}
However, from my understanding, this does not work. Looking at the gcc source, for this flag to actually do anything, you need to also use -finstrument-functions. See gcc/gimplify.c:14436:
...
/* If we're instrumenting function entry/exit, then prepend the call to
the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
catch the exit hook. */
/* ??? Add some way to ignore exceptions for this TFE. */
if (flag_instrument_function_entry_exit
&& !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
/* Do not instrument extern inline functions. */
&& !(DECL_DECLARED_INLINE_P (fndecl)
&& DECL_EXTERNAL (fndecl)
&& DECL_DISREGARD_INLINE_LIMITS (fndecl))
&& !flag_instrument_functions_exclude_p (fndecl))
...
It first checks that the global -finstrument-functions flag is enabled. Then it checks a specific function's flag, which, from what I understand, is enabled by default. So all other functions that don't have my instrument_function attribute would still be instrumented.
Is there a way to clear this flag for all functions first, then handle my instrument_function attribute to set the flag for those functions only?
The trick was only defining the attribute, but not actually using any handling function, and do the processing elsewhere.
We still use -finstrument-functions to enable instrumentation for all functions at first. We can register a callback for PLUGIN_FINISH_PARSE_FUNCTION, which checks everything. For every function declaration, it checks its attributes. If it has the instrument_function attribute, it sets the flag for the instrumentation to be added later as usual. If the function doesn't have the attribute, it clears the flag.
#include <stdio.h>
#include "gcc-plugin.h"
#include "plugin-version.h"
#include "tree.h"
int plugin_is_GPL_compatible;
static struct plugin_info info = {
"0.0.1",
"This plugin provides the instrument_function attribute.",
};
static struct attribute_spec instrument_function_attr =
{
"instrument_function",
0,
-1,
false,
false,
false,
NULL, // No need for a handling function
};
static void register_attributes(void * event_data, void * data)
{
register_attribute(&instrument_function_attr);
}
void handle(void * event_data, void * data)
{
tree fndecl = (tree) event_data;
// Make sure it's a function
if (TREE_CODE(fndecl) == FUNCTION_DECL)
{
// If the function has our attribute, enable instrumentation,
// otherwise explicitly disable it
if (lookup_attribute("instrument_function", DECL_ATTRIBUTES(fndecl)) != NULL_TREE)
{
printf("instrument_function: (%s:%d) %s\n",
DECL_SOURCE_FILE(fndecl),
DECL_SOURCE_LINE(fndecl),
get_name(fndecl));
DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT(fndecl) = 0;
}
else
{
DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT(fndecl) = 1;
}
}
}
int plugin_init(
struct plugin_name_args * plugin_info,
struct plugin_gcc_version * version)
{
register_callback(
plugin_info->base_name,
PLUGIN_INFO,
NULL,
&info);
register_callback(
plugin_info->base_name,
PLUGIN_FINISH_PARSE_FUNCTION,
handle,
NULL);
register_callback(
plugin_info->base_name,
PLUGIN_ATTRIBUTES,
register_attributes,
NULL);
return 0;
}

wxTimer not calling overriden Notify()

I'm running into an issue where I implemented a derived wxTimer class to override the Notify() call since I'm not using an owner implementation as described in the documentation.
When I debug the run, I can see
the timer is being instantiated
my_timer_instance->IsRunning() returns true
MyTimer::Notify() is never called
This leads me to believe that the timer is being set and running, but when it expires it's calling the base class Notify() procedure and not my override it's not calling notify() but I'm not sure why.
EDIT: I added frame->getTimer()->Notify(); to my app and the correct procedure was called. Therefore, the timer just isn't calling Notify when it expires.
EDIT2: Added this minimal working example, and the timer works as expected. I'll try to compare the two and see what the problem is.
MyApp.hpp
#pragma once
#ifndef __NONAME_H__
#define __NONAME_H__
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/statusbr.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/string.h>
#include <wx/frame.h>
#include <wx/timer.h>
///////////////////////////////////////////////////////////////////////////
class MyTimerClass : public wxTimer
{
wxFrame* MyFrame;
public:
MyTimerClass(wxFrame* frame): MyFrame(frame) {};
void Notify() override;
};
///////////////////////////////////////////////////////////////////////////////
/// Class MyFrame1
///////////////////////////////////////////////////////////////////////////////
class MyFrame1 : public wxFrame
{
private:
protected:
wxStatusBar* m_statusBar1;
MyTimerClass* MyTimer;
public:
void StartTimer(int TimeInSeconds);
MyFrame1(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(500, 300), long style = wxDEFAULT_FRAME_STYLE | wxTAB_TRAVERSAL);
~MyFrame1();
};
#endif //__NONAME_H__
MyApp.cpp
#include "MyApp.hpp"
#include "wx/wxprec.h"
// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWidgets headers)
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
///////////////////////////////////////////////////////////////////////////
void MyTimerClass::Notify()
{
MyFrame->SetStatusText("Timer popped", 0);
}
MyFrame1::MyFrame1(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style)
{
MyTimer = new MyTimerClass(this);
this->SetSizeHints(wxDefaultSize, wxDefaultSize);
m_statusBar1 = this->CreateStatusBar(1, wxSTB_SIZEGRIP, wxID_ANY);
this->Centre(wxBOTH);
this->StartTimer(5);
}
void MyFrame1::StartTimer(int TimeInSeconds)
{
SetStatusText("Timer started with " + std::to_string(TimeInSeconds) + " seconds.");
MyTimer->Start(TimeInSeconds * 1000);
}
MyFrame1::~MyFrame1()
{
}
// ----------------------------------------------------------------------------
// resources
// ----------------------------------------------------------------------------
// the application icon (under Windows it is in resources and even
// though we could still include the XPM here it would be unused)
#ifndef wxHAS_IMAGES_IN_RESOURCES
#include "../sample.xpm"
#endif
// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------
class MyApp : public wxApp
{
public:
virtual bool OnInit() wxOVERRIDE;
};
enum
{
// menu items
Minimal_Quit = wxID_EXIT,
Minimal_About = wxID_ABOUT
};
wxIMPLEMENT_APP(MyApp);
bool MyApp::OnInit()
{
// call the base class initialization method, currently it only parses a
// few common command-line options but it could be do more in the future
if (!wxApp::OnInit())
return false;
// create the main application window
MyFrame1 *frame = new MyFrame1(NULL, -1, "Test Frame");
frame->Show(true);
return true;
}
#BobbyTables,
From the documentation:
This member should be overridden by the user if the default
constructor was used and SetOwner() wasn't called.
Is it the case?
Nothing seems to be wrong in the code you show (although I'd change a few things, such as using raw pointer for my_timer_instance), so the problem must be elsewhere. As usual, the best would be to come up with a SSCCE, without it I can only offer some guesses as to what the problem actually is.
Are you running the event loop? The timers will only fire when it's running, so if you block doing some computation, this wouldn't happen.
Also, what is frame in Notify()? Is this a global (I'd rather pass it as parameter to MyTimer ctor)?
So after mimicking the code provided in the question, the following changes were made:
Instead of using a getter and setter to access the private timer member, I instead use
void refreshTimer(int time_in_seconds) in my parent frame class and create the timer in the parent frame's constructor rather than letting the app create it and pass it in.
I don't see why either of those two things would change the behavior of the timer but the timer now works as expected. I apologize for not being able to identify a concrete bug as the source of the problem.
NOTE: This behavior was caused by the timer being invoked outside the wxwindow's thread. Be careful when creating multithreaded programs using wxwidgets as a GUI. To circumvent this issue since I needed the timer to be invoked in a different thread, I created my own timer class that works correctly.

Periodically hid_hw_raw_request in kernel module, how to?

I'm writing a kernel module that need to ask an hid raw device periodically.
I tried hrtimer and a simple timer and each time I call hid_hw_raw_request I got a "BUG: scheduling while atomic".
If I try the same function outside my timer function (eg in the init), it works fine (no bug).
How could periodically call this function without generating any bug ?
You need to use a work queue to issue your hid_hw_raw_request as deferred work. This can be done as in the following example module:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/workqueue.h>
static void hid_work_handler(struct work_struct *hid_work);
static struct workqueue_struct *hid_workqueue;
static DECLARE_WORK(hid_work, hid_work_handler);
static void hid_work_handler(struct work_struct *hid_work)
{
...
hid_hw_raw_request(...);
...
}
static int __init hid_work_init(void)
{
if (!hid_workqueue)
hid_workqueue = create_singlethread_workqueue("hid_workqueue");
if (hid_workqueue)
queue_work(hid_workqueue, &hid_work);
return 0;
}
static void __exit hid_work_exit(void)
{
if (hid_workqueue) {
flush_workqueue(hid_workqueue);
destroy_workqueue(hid_workqueue);
}
}
module_init(hid_work_init);
module_exit(hid_work_exit);
MODULE_DESCRIPTION("hid_work_test");
MODULE_LICENSE("GPL");
Note that for the real implementation you'll need to create your own data struct with an included struct work_struct to be queued. This data struct will likely contain the hiddev, buffer, etc. that the hid_work_handler needs to do the actual transfer. See LDD3 Chapter 7 for more details (albeit syntax of calls is outdated, the basic explanation still applies).

C++/CLI unhandled exception passing 3 or more parameters to delegate

Just stumbled upon strange behavior.
I have an unmanaged class (actually wrapper around some native lib):
//.h
class Wrapper
{
private:
void(*pCallback)(int, int /*, int*/);
public:
void SetCallback(void(*callback)(int, int /*, int*/));
void InvokeCallback();
};
//.cpp
void Wrapper::SetCallback(void(*callback)(int, int /*, int*/))
{
pCallback = callback;
}
void Wrapper::InvokeCallback()
{
pCallback(0, 0 /*, 0*/); //(1)
//(3)
}
And managed class which is winforms control and uses unmanaged wrapper described above:
public ref class MineControl : public System::Windows::Forms::Control
{
private:
Wrapper *pWrapper;
delegate void CallbackDelegate(int, int /*, int*/);
public:
MineControl()
{
/* rest of initialization here */
pWrapper = new Wrapper;
auto dlg = gcnew CallbackDelegate(this, &MineControl::Method);
auto ptr = System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(dlg);
void(*callback)(int, int /*, int*/) = (void(*)(int, int /*, int*/))(ptr.ToPointer());
pWrapper->SetCallback(callback);
pWrapper->InvokeCallback();
}
void Method(int a, int b /*, int c*/)
{
//some code or even nothing at all
//(2)
}
}
This works fine.
Until I uncomment third parameter. After that I put breakpoint on (1). I can enter to MineControl::Mehod - (2). But everything fails on exiting this method. Point (3) become unreachable. I'm getting unhandled exception on exiting that method. Moreover being attached, VS still cannot handle that exception (all settings to debug unmanaged and managed code are set - this is the only case VS cannot catch exception). So Windows tries to handle it - standard App has stopped working window with two options - Debug and Close program. But I cannot debug because VS is still attached and either do not want to detach or app dies on VS detach.
I can wrap all parameters into some structure and this will work well. However can someone explain me why adding third parameter makes it impossible to get back from managed to unmanaged code?
I have no idea what is going on.
Environment: VS2013, x86 project, .net4.5
Ok, I'll post answer by myself. Solution is actually in Hans's comment.
Default calling convention is sdtcall but in my case I need cdecl calling convention.
Decorating delegate with [UnmanagedFunctionPointer(CallingConvention.Cdecl)] attribute solved my problem.
There is also а valuable note that keep delegate in a local variable is a bad idea.

C++11 Lambda function compilation error

i am new using c++11 features and also tryng to use SDL_Widget-2 lib for build a simple Gui for my project. But i am getting stuck in the problem :
#include "sdl-widgets.h"
class Builder
{
public:
Builder():top_win(nullptr)
,but(nullptr)
{
top_win=new TopWin("Hello",Rect(100,100,120,100),0,0,false,
[]() {
top_win->clear();
draw_title_ttf->draw_string(top_win->render,"Hello world!",Point(20,40));
}
);
but=new Button(top_win,0,Rect(5,10,60,0),"catch me",
[](Button *b) {
static int dy=60;
b->hide();
b->move(0,dy);
b->hidden=false;
dy= dy==60 ? -60 : 60;
});
}
private:
TopWin * top_win;
Button *but;
};
int main(int,char**) {
Builder aViewBuilder;
get_events();
return 0;
}
with the error in the compilation stage:
In lambda function:
error: 'this' was not captured for this lambda function
error: 'this' was not captured for this lambda function
this error is printed out twice int the console.
I have try :
[this](){}
[=](){}
and
[&](){}
with different compile error but a cannot go more further.
Can any see a fix?
You do need to capture with [this] or [&]. I suspect that the TopWin and Button constructors take raw function pointers, and need to take std::functions instead.
A plain vanilla function pointer is not compatible with capturing lambdas. std::function is able to work like a function pointer that also allows safe storage of captured data. (i.e. the captured objects will need to be properly copied or destroyed when the function object is itself copied or destroyed)

Resources