WTL multithreading, multiple interfaces & libraries - winapi

I have a Main Thread that displays an interface, within another thread created from the main thread before the Main interface is shown, I create tow other windows sequentially:
I create the first window:
CWarningDlg warnDlg;
warnDlg.Create(NULL);
warnDlg.ShowWindow(SW_SHOW);
warnDlg.BringWindowToTop();
CMessageLoop _Loop ;
if(_MyAppModule.AddMessageLoop(&_Loop))
{
nRet = _Loop.Run();
_MyAppModule.RemoveMessageLoop();
}
warnDlg.DestroyWindow();
if (nRet == SOME_VALUE)
{
doSomethingElse();
}
Do something else has:
CActionDlg actDlg;
actDlg.Create(NULL);
actDlg.ShowWindow(SW_SHOW);
actDlg.BringWindowToTop();
CMessageLoop _Loop ;
if(_MyAppModule.AddMessageLoop(&_Loop))
{
CreateAnObject(); //this also launches an object Specific Worker Thread
nRet = _Loop.Run();
_MyAppModule.RemoveMessageLoop();
}
The function CreateAnObject calls some functions from a 'ComplexObject.DLL' that create an complex object which holds the THREAD ID of the thread that called the CREATION function, it gets it with ::GetCurrentThreadId(); , while creating this complex object the GetCurrentThreadId() returns the ID of the SECOND THREAD, which is GOOD.
Now, in my CActionDialog I receive notifications from this object usind ::SendMessage(), the SendMessage function is called from within a Worker thread that is specific to the Complex Object just created.
When I receive those notifications I need to access some of that complex object values, for that I call some other functions from 'ComplexObject.DLL' which verify using the ::GetCurrentThreadId() function that the ID of the calling thread is the same as the ID of thread that created that complex object. That verification fails for me, because the functions get called using the thread ID of the MAIN THREAD, that has the Main interface GUI.
Why is that? I cannot understand! (I hope I successfully explained myself).

The problem you seem to have, from your description at least, is that whatever external API you are using via CreateAnObject, it restricts its further use to creation thread. Taking it as is, you are limited to making calls from the creation thread only. Whenever your code running on other theads, including thread hosting CWarningDlg, needs to talk to this API, you need to transfer the call to the CActionDlg thread and proceed from there.
Synchronization can be SendMessage you already do, or something safer like PostMessage with event/message completion notification.

Related

NIFI Processor won't call the #OnStopped or #OnDisabled functions

I have a NIFI-Processor that subscribes to a few tags on a OPC UA server.
I'm struggling to find a way to terminate the subscription. My plan was to just keep it running until I decide to stop the processor.
I tried defining functions for #OnStopped, #OnUnscheduled and #OnDisabled, but they never get called when I stop or disable the processor.
I'm on NIFI 1.7 so I can terminate the processor's thread, but my #OnStopped, #OnUnscheduled and #OnDisabled functions still don't get called.
Does terminating the thread mean that the thread won't return from onTrigger in a fashion that allows calling the above mentioned lifecycle methods?
EDIT: As requested, my method with annotation:
#OnStopped
private void OnStopped() {
getLogger().info("Subscriptions cleared - stopped");
miloOpcUAService.clearSubscriptions();
}
Your method has to have public visibility, otherwise the scheduler (which uses reflection) can't find it to invoke it.

Running Plone subscriber events asynchronously

In using Plone 4, I have successfully created a subscriber event to do extra processing when a custom content type is saved. This I accomplished by using the Products.Archetypes.interfaces.IObjectInitializedEvent interface.
configure.zcml
<subscriber
for="mycustom.product.interfaces.IRepositoryItem
Products.Archetypes.interfaces.IObjectInitializedEvent"
handler=".subscribers.notifyCreatedRepositoryItem"
/>
subscribers.py
def notifyCreatedRepositoryItem(repositoryitem, event):
"""
This gets called on IObjectInitializedEvent - which occurs when a new object is created.
"""
my custom processing goes here. Should be asynchronous
However, the extra processing can sometimes take too long, and I was wondering if there is a way to run it in the background i.e. asynchronously.
Is it possible to run subscriber events asynchronously for example when one is saving an object?
Not out of the box. You'd need to add asynch support to your environment.
Take a look at plone.app.async; you'll need a ZEO environment and at least one extra instance. The latter will run async jobs you push into the queue from your site.
You can then define methods to be executed asynchronously and push tasks into the queue to execute such a method asynchronously.
Example code, push a task into the queue:
from plone.app.async.interfaces import IAsyncService
async = getUtility(IAsyncService)
async.queueJob(an_async_task, someobject, arg1_value, arg2_value)
and the task itself:
def an_async_task(someobject, arg1, arg2):
# do something with someobject
where someobject is a persistent object in your ZODB. The IAsyncService.queueJob takes at least a function and a context object, but you can add as many further arguments as you need to execute your task. The arguments must be pickleable.
The task will then be executed by an async worker instance when it can, outside of the context of the current request.
Just to give more options, you could try collective.taskqueue for that, really simple and really powerful (and avoid some of the drawbacks of plone.app.async).
The description on PyPI already has enough to get you up to speed in no time, and you can use redis for the queue management which is a big plus.

Boost Asio, asynchronous server and video tracking

I need to trasmit with a (Boost) tcp server information collected in real time by the ARToolKit video tracking library.
Which is the right way of doing it?
I'm actually doing it with Boost threads and asio, but I think that what I do is done in a bad way (even if it works)
Here is what I do to run the server (the source of the Server class is from Boost tutorial):
boost::asio::io_service io_service;
Server s(io_service, 2345);
boost::thread bt(boost::bind(&boost::asio::io_service::run, &io_service)); //server in background in a second thread
Then I start the video tracking
startTracking(); //blocking call in the main thread
defined in this way
void startTracking(){
glutInit(&argc, argv); //global and reachable
if ((gArglSettings = arglSetupForCurrentContext()) == NULL) {
fprintf(stderr, "main(): arglSetupForCurrentContext() returned error.\n");
exit(-1);}
... //init a lot of artoolkit parameters
arVideoCapStart();
argMainLoop( NULL, keyEvent, mainLoop );
}
In this (horrible) way everything works. But I would like to avoid spawning a second thread for the asio server (it is not supposed to be thrown there, as I read from the Boost doc).
Otherwise trying to put the video traking out of the main thread crashes the ARToolKit library ie:
boost::thread workerThread(startTracking);
workerThread.join();
When the join() is run the program segfaults at glutInit call
What do you think the workerThread.join() method does? Take a look at the answer to this question. So, calling the join method will cause the thread it is called from (main thread) to block and wait until the worker thread has completed. Is that what you want? If you have set up ASIO to run on that main thread, then none of the ASIO I/O socket handlers will be able to execute and thus it will appear to hang because the thread it is on is frozen from the join method. Likewise for the ARToolKit library, if the calls to it have been initiated on this main thread, then it too will appear to freeze because that thread is frozen when the join method is called.
If this is not your problem, then please provide more code.

Windows Forms: thread safe access to GUI?

in the last hours I've struggled with delegates and accessing Windows Forms controls (C++) where I've used this tutorial (the first thread safe method): http://msdn.microsoft.com/en-us/library/ms171728.aspx#Y190
Changing TextBoxes and Labels works perfectly but when I want to show or hide the whole GUI from another thread this fails.
I use the following methode (which is part of the GUI class):
System::Void UI::showUI(boolean value) {
if (this->InvokeRequired) {
SetTextDelegate^ d = gcnew SetTextDelegate(this, &UI::showUI);
this->Invoke(d, gcnew array<Object^> { value });
} else {
if (value == true)
this->Show();
else
this->Hide();
}
}
In the first call the if-clause is true so Invoke is called. But usually the showUI method should be called a second time automatically where the if-clause returns false, but this is not happening. So the GUI is neither shown nor hiden.
Is it necessary to show/hide the GUI with a delegate or can I do it from every possible thread? If a delegate is necessary, why is showUI not executed a second time?
Thanks,
Martin
edit: okay the name SetTextDelegate is not appropriate but this is not the point...
This is a pretty standard case of deadlock, not uncommon with Control::Invoke(). It can only proceed if the UI thread is not busy. Use Debug + Windows + Threads and double-click the Main thread. Look at the call stack to see what it is doing. The typical case is that it is blocking, waiting for the thread to finish the job. That will never happen since the thread can't complete until the Invoke() call returns.
Don't block the UI thread.
Consider using BackgroundWorker, its RunworkerCompleted event is nice to do stuff after the thread completes, removing the need to block.

Using event object in inter-process

I'm trying to use event object in win32 environment to synchronize two processes. Below are the simplified code of two programs.
// process1
int main()
{
HANDLE h = CreateEvent(NULL, FALSE, FALSE, TEXT("Hello"));
WaitForSingleObject(h, INFINITE);
// RunProcess(L"process2.exe", L"");
}
// process2
int main()
{
HANDLE h = OpenEvent(EVENT_MODIFY_STATE, FALSE, TEXT("Hello"));
SetEvent(h);
}
It's quite simple, and works well when two processes are launched independently. However it does not work when the process 1 launches process 2 as a child process (which is commented in the above code) - the SetEvent call fails. What is the reason and solution of this problem?
Your code needs to check and handle errors. Both CreateEvent and OpenEvent will return NULL if they fail, in that case you need to check the error using GetLastError.
Your calls to WaitForSingleObject and SetEvent should be checked per the MSDN docs as well.
The order in which you need to do things in the parent process is:
CreateEvent
Start child process
WaitForSingleObject.
Otherwise you will hit the problem called out by #Mark Tolonen.
It would also be best to have a timeout on your wait, to handle the case where the child process fails to start, exits unexpectedly, or hangs.
An alternative approach if you intend to use this parent/child relationship would be to allow inheritance of the event handle. Then the event does not need to be named, and nobody else can 'squat' on it in a DoS attack on your apps. You can pass the handle value to the child as a command-line parameter. You do this using the bInheritHandle field on the eventAttributes parameter to CreateEvent.
A Boolean value that specifies whether
the returned handle is inherited when
a new process is created. If this
member is TRUE, the new process
inherits the handle.
Are you sure? As written, if process1 creates process2 in the current location, it will never create process2 because it will wait forever for the event to be fired. Create process2 first, then wait for the event to be set.
You have a NULL security descriptor, which the documentation says cannot allow the handle to be inherited by children processes, specifically:
If this parameter is NULL, the handle cannot be inherited by child processes
Maybe you need to create a proper security descriptor?

Resources