Callback with XPCOM - c++

I would like to implement the observer pattern similar to Timer component. Instead of calling a callback by time expiration, the callbacks that are observers of a topic would be called from system events (like new file created, or a new e-mail received, etc.). I tried using nsIObserverService in the component XPCOM, but it seems that functions from component aren't able to call observers in JavaScript by using NotifyObservers. The NotifyObservers only works when is called from JavaScript.
Thanks in advance

Example::Example always runs on the main thread (because it's being created by your script). So it never creates a proxy to the observer service. But the call to Example::Call from Ex::Run happens on the background thread, and I think in this case the call to NotifyObservers returns NS_ERROR_UNEXPECTED (which you ignore).

Related

how to use boost::bind with std::thread (in Wt c++)

I'm using Wt C++ framework and need to connect a push button with a class function. The below code works fine but it's needed to run the function doors_open_all on a thread to allow usage of other actions at the same time.
Wt::WPushButton *open_doors_button = new Wt::WPushButton("open all");
container_box->addWidget(open_doors_button);
open_doors_button->clicked().connect(boost::bind(&Servicemode::doors_open_all, this));
Something along the lines is needed:
open_doors_button->clicked().connect(boost::threaded_bind(&Servicemode::doors_open_all, this));
If I understand question corrently you need to run doors_open_all function in a new thread.
boost::thread constructor is internaly using boost::bind You don't need to be explicit.
So open_doors_button->clicked().connect(boost:: thread(&Servicemode::doors_open_all, this)); should do the job.
Version with boost::thread and boost::bind:
open_doors_button->clicked().connect(boost::thread(boost::bind(&Servicemode::doors_open_all, this)));
Edit:
You can also try using std::async for this purpouse too.
What does Servicemode::doors_open_all() do?
If I assume that what is taking a long time is just all backend stuff, so no widgets are being created, deleted or modified, then you can spawn a thread inside Servicemode::doors_open_all() to do all of that backend stuff. When it's done you have two possibilities:
Use WServer::post(), passing it the session id of your WApplication and a function, to notify the application that it should update its UI, and do all of your creating, deleting and modifying of widgets in that callback.
Grab the update lock of the WApplication:
// Assuming that app is a Wt::WApplication*
Wt::WApplication::UpdateLock lock(app); // lock is released when it goes out of scope
When you have the update lock, you can go ahead and modify the widget tree.
In any case, when doing this, you have to also do these two things:
Enable server push beforehand by calling app->enableUpdates(true). When the thread is done you can again disable server push with app->enableUpdates(false).
When you have modified the widget tree, notify Wt that it should push these changes to the client with app->triggerUpdate().
If what takes a long time is UI-related, then there's not much you can do, since Wt assumes that you only modify a WApplication and its widgets from a single thread at a time, i.e. when you have the update lock. The update lock is always grabbed automatically when handling an event coming from the client, like WPushButton::clicked().
Server push is demonstrated in the serverpush example. You can find that under examples/feature/serverpush in the Wt source tree.

Qt : qt cannot send events to objects owned by a different thread - Why

I am developing an application with Qt whereby I want to update my GUI from another unrelated class with functions executing in a different thread.
I registered a callback function from the Qt GUI class to the other class using standard C++ constructs std::function and std::bind.
On trying to execute the GUI callback function from the other class, my program crashes with "qt cannot send events to objects owned by a different thread".
My questions are, what is happening here exactly. Why is it not permissive to communicate between two threads like this. Is it possible to resolve this in some way , or does Qt just not allow other unrelated functions to update the GUI in this way ?
For information , I am using portaudio libraries on windows. It executes a callback in a different thread. When I receive audio, I try to update my GUI.
Thank you in advance
You're probably being thrown off by the "send events" phrase. In Qt, this phrase has a strict technical meaning. Namely:
to send events means to use QCoreApplication::sendEvent, which then immediately invokes QObject::event on the receiver. It is an error to send events when the sending and receiving threads are different.
to post events means to use QCoreApplication::postEvent, which posts the event to the receiving object thread's event queue. The QObject::event on the receiver is invoked later by the receiver thread's event loop.
When objects live in different threads, you're not allowed to send events, only to post them. This points to the underlying cause of your issue/
Any method you access on a QWidget or a derived class must be accessed on its thread(), i.e. the main thread. Everything inside of QWidget can use sendEvent freely as the sending thread and receiving object's thread are identical by contract. By calling QWidget methods from the wrong thread, you break that contract by indirectly using sendEvent and thus fail.
Only methods that you yourself have implemented and are thread-safe can be called from other threads - and they can't use sendEvent.

How can I write a C++ COM object with asynchronous event firing (like VB6's Timer object)?

I'm writing a C++ COM object for directory change notifications via ReadDirectoryChangesW. A thread in my object will wait for changes, then notify the VB6 client.
I know how to trigger events from the main thread of my program, similar to callback functions, but I don't want to force the user to poll my object for changes every small interval.
As far as I'm aware, what I want could be done by sending window messages, but this needs form subclassing on the VB6 side, which is quite complicated.
So I'm looking for a way to write an object like VB6's Timer which can fire an event in VB6 even when VB6 isn't currently calling into a method of Timer. Is this possible?
COM events.
The topic is rather laborious, it implies defining a 'sink' interface that the event consumer (VB) is passing to the event source, and then raising events by calling methods on the 'sunken' interface. See Architecture of Connectable Objects. You must implement IConnectionPointContainer. The good news is that IDEs are fully aware of this model and will expose your events in the VB designer. From the VB side will be as simple as a double-click on the COM object 'events' properties panel.
As for the 'async' part, this falls in the 'threading' model of your component and the VB host app. In Apartment threads (the default) you will have to raise the events in the main Apartment thread, and you may have to marshal the interface between threads. See What are the rules for CoMarshalInterface and CoUnmarshalInterface?.
The details about asynchronous COM event firing from C++ server to VB6 client can be found in this article.

Delegates and thread: CallbackContext parameter

I'm implementing threading in Metro mode, I got this example while Googling, but I don't understand CallbackContext . What's the use of this? This explains its use in MTA, but not clear to me. And I'm facing problem when I use CallbackContext as Any or Same. Something work with one but not with other! So first thing first I want to know what's the use of this?! PS: I'm new to WindowsRT programming and C++ too! Thanks!
auto workItemHandler = ref new WorkItemHandler([=](IAsyncAction^)
{
// Run the user callback.
try
{
func(data);
}
catch (...)
{
}
// Signal that the thread has completed.
SetEvent(completionEvent);
//CloseHandle(completionEvent);
}, CallbackContext::Same);
CallbackContext determines whether your delegate (in this case, a WorkItemHandler) aggregates the free-threaded marshaller. This will determine whether your delegate can be smuggled to another apartment (CallbackContext::Any), or if it must be called back to the originating apartment (CallbackContext::Same). Basically, it tells the person invoking your delegate whether it can be called directly regardless of apartment, or if they need to marshal back to the apartment it was created in.
For example, in a Windows Store Application, anything that modifies the UI needs to run on the UI thread (STA). Let's presume the method you're in is one that runs on the UI thread (such as an event callback, like a button click handler). Certain async calls like ThreadPool::RunAsync will run the passed-in delegate on a thread other than the UI thread (as the default for delegates is CallbackContext::Any). This is useful if you do not need to do anything on the UI thread, as it frees that thread up to continue pumping messages (and your app continues to feel performant).
However, if you do need to modify the UI or make a call back into the UI, and you attempt to do so from a non-UI thread, you will get an incorrect thread exception. By adding the parameter CallbackContext::Same you can force your delegate to run in the originating apartment (in this scenario, the STA) and thereby avoid the issue.
(You can also make a call back to the UI thread by using Dispatcher->RunAsync to invoke a further delegate to run on the STA. Whether it's better for your entire delegate to run on the STA or not depends on your scenario.)

C++ Embarcadero TTcpServer and TTcpClient

I want to know how to work with connected clients on TTcpServer class?
I got a client connected on method "ServerAccept" whats next? How can i work with them?
I need to start from ServerAccept a new thread to work with socket client?
The TTcpServer.OnAccept event is triggered when the TTcpServer.Accept() method is called and a client is accepted. ALL socket work with that client has to be done within the context of the TTcpServer.OnAccept event, using the methods of the TCustomIpClient object that is provided by the event. As soon as the event handler exits, TTcpServer closes the connection. If the TTcpServer.BlockMode property is set to bmThreadBlocking, the OnAccept event handler runs in a thread managed by TTcpServer so you do not need to create your own thread. Otherwise, you need to call the TTcpServer.Accept() method in your own code, in which case you can call it in your own thread if desired.