Borland C++ - Multithreaded TCPServer Issue - c++

[I might be wrong about these]
TIdTCPServer Server is multithreaded in Borland C++ builder. It handles all client's on seperate threads. This is written in help of Borland c++.
Now is my problem & question.
For example, ShowMessage(String ..) method should be called on main (gui) thread. But as I say above, TCPServer is multithreaded and handles OnExecute event on different threads. When I use ShowMessage method in OnExecute event (which is handled on a different thread than main thread), I get weird results. Sometimes ShowMessage() works as expected, sometimes it is shown without any text on it with different box sizes(infinite lengt, very long, normal, etc). The other user interface changes causes no problem(update TEdit, TMemo. Only ShowMessage() has problem for now)
I think this problem is the result of calling ShowMessage() method not on the main (gui) thread but on TCPServer's thread which is created for client connections internally by TIdTCPServer.
So how can I fix it?

ShowMessage() displays a VCL TForm, and as such is not thread-safe. You have to use TThread::Synchronize(), TThread::Queue(), TIdSync, TIdNotify, or any other inter-thread communication mechanism of your choosing to make ShowMessage() run on the main thread.
To display a popup message in a worker thread, use the Win32 API MessageBox() function instead. It is thread-safe, and can be called in any thread without synchronizing with the main thread.

All changes to the user interface should be done in the main thread. You can use the TThread::Queue function for executing a function in the main thread. It posts a message to the main message queue, and the TThreadMethod passed as a parameter gets executed when the main thread handles messages.
If you need to pass data to the main thread, e.g. the message to be shown, you'll have to do that separately, as function parameters cannot be passed via the Queue function.

Yes your issue has most probably nothing to do with TCP. Any VCL access must be done within the main thread. (do not forget that message dialogs are often called from VCL wrapers and not directly through winapi)
Yeas I know it sometimes works 'well' even when not, but then this issues appears:
always an exception an App close/exit
occasional App hang/exception (fatal or non fatal for App)
occasional corrupted VCL visual stuff (missing items in lists, missed events, etc)
occasional unpredictable behaviour (sometimes overwrite even App non VCL data)
Many occasional issues are repeatable dependent on:
UI complexity
source code complexity (bigger code more often issues)
number of windows/forms
Also beware of memory leaks. VCL is extremly unstable if memory manager is corrupted by invalid deletes etc... (do not know how about it in newer versions but in bds2006 is this very big issue)
PS. if you need just dialogs then use WINAPI interface it should work even in threads if your text data is not VCL related (for example AnsiString variable access is fine but DBGrid access is not)

Related

Cross thread call a.k.a run on main/UI thread from other thread without dependencies needed

I'm on some c++ mobile product, but I need my apps main thread is still running without any blocking when doing some heavy work on the background thread and run back on main thread. But I realized there is no runOnMainThread/runOnUIThread in c++ thread api. I trying to figure it out the issue and found that need to depend library, or create your own thread event queue. Although it is good, but i am thinking to have a behavior which can runOnUIThread.
How it does not work: the mentioned library creates a timer, installs a SIGALRM signal handler and dispatches queued tasks when signals are fired. This allows tasks being processed on the main thread even when it is busy. However POSIX permits only a small set of async-signal-safe functions to be invoked inside of signal handler. Running arbitrary с++ code inside of signal handler violates that restriction and leaves application in hopelessly doomed state.
After some research and development, I've created a library called NonBlockpp
it is a small c++ library to allow c++ mobile application able to process the heavy and time consuming task on background and back to Main thread again, It’s been tested and fired the main thread event.
It also allow to save the tasks and fire them later, all the task has no blocking each other and thread safety.
How it works:
If you found any query or suggestion, please don't hesitate to raise an issue and we can discuss it together.
The project has rectify from signal to pollEvent due to signal handler might not be safe to use.
Please take a look the new changed.
NonBlockpp
Usage

win32 SetTimer waitfor TIMERPROC [duplicate]

In this thread (posted about a year ago) there is a discussion of problems that can come with running Word in a non-interactive session. The (quite strong) advice given there is not to do so. In one post it is stated "The Office APIs all assume you are running Office in an interactive session on a desktop, with a monitor, keyboard and mouse and, most importantly, a message pump." I'm not sure what that is. (I've been programming in C# for only about a year; my other programming experience has primarily been with ColdFusion.)
Update:
My program runs through a large number of RTF files to extract two pieces of information used to construct a medical report number. Rather than try and figure out how the formatting instructions in RTF work, I decided to just open them in Word and pull the text out from there (without actually starting the GUI). Occasionally, the program hiccuped in the middle of processing one file, and left a Word thread open attached to that document (I still have to figure out how to shut that one down). When I re-ran the program, of course I got a notification that there was a thread using that file, and did I want to open a read-only copy? When I said Yes, the Word GUI suddenly popped up from nowhere and started processing the files. I was wondering why that happened; but it looks like maybe once the dialog box popped up the message pump started pushing the main GUI to Windows as well?
A message loop is a small piece of code that exists in any native Windows program. It roughly looks like this:
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
The GetMessage() Win32 API retrieves a message from Windows. Your program typically spends 99.9% of its time there, waiting for Windows to tell it something interesting happened. TranslateMessage() is a helper function that translates keyboard messages. DispatchMessage() ensures that the window procedure is called with the message.
Every GUI enabled .NET program has a message loop, it is started by Application.Run().
The relevance of a message loop to Office is related to COM. Office programs are COM-enabled programs, that's how the Microsoft.Office.Interop classes work. COM takes care of threading on behalf of a COM coclass, it ensures that calls made on a COM interface are always made from the correct thread. Most COM classes have a registry key in the registry that declares their ThreadingModel, by far the most common ones (including Office) use "Apartment". Which means that the only safe way to call an interface method is by making the call from the same thread that created the class object. Or to put it another way: by far most COM classes are not thread-safe.
Every COM enabled thread belongs to a COM apartment. There are two kinds, Single Threaded Apartments (STA) and a Multi Thread Apartment (MTA). An apartment threaded COM class must be created on an STA thread. You can see this back in .NET programs, the entry point of the UI thread of a Windows Forms or WPF program has the [STAThread] attribute. The apartment model for other threads is set by the Thread.SetApartmentState() method.
Large parts of Windows plumbing won't work correctly if the UI thread is not STA. Notably Drag+Drop, the clipboard, Windows dialogs like OpenFileDialog, controls like WebBrowser, UI Automation apps like screen readers. And many COM servers, like Office.
A hard requirement for an STA thread is that it should never block and must pump a message loop. The message loop is important because that's what COM uses to marshal an interface method call from one thread to another. Although .NET makes marshaling calls easy (Control.BeginInvoke or Dispatcher.BeginInvoke for example), it is actually a very tricky thing to do. The thread that executes the call must be in a well-known state. You can't just arbitrarily interrupt a thread and force it to make a method call, that would cause horrible re-entrancy problems. A thread should be "idle", not busy executing any code that is mutating the state of the program.
Perhaps you can see where that leads: yes, when a program is executing the message loop, it is idle. The actual marshaling takes place through a hidden window that COM creates, it uses PostMessage to have the window procedure of that window execute code. On the STA thread. The message loop ensures that this code runs.
The "message pump" is a core part of any Windows program that is responsible for dispatching windowing messages to the various parts of the application. This is the core of Win32 UI programming. Because of its ubiquity, many applications use the message pump to pass messages between different modules, which is why Office applications will break if they are run without any UI.
Wikipedia has a basic description.
John is talking about how the Windows system (and other window based systems - X Window, original Mac OS....) implement asynchronous user interfaces using events via a message system.
Behind the scenes for each application there is a messaging system where each window can send events to other windows or event listeners -- this is implemented by adding a message to the message queue. There is a main loop which always runs looking at this message queue and then dispatching the messages (or events) to the listeners.
The Wikipedia article Message loop in Microsoft Windows shows example code of a basic Windows program -- and as you can see at the most basic level a Windows program is just the "message pump".
So, to pull it all together. The reason a windows program designed to support a UI can't act as a service is because it needs the message loop running all the time to enable UI support. If you implement it as a service as described, it won't be able to process the internal asynchronous event handling.
In COM, a message pump serialises and de-serialises messages sent between apartments. An apartment is a mini process in which COM components can be run. Apartments come in single threaded and free threaded modes. Single threaded apartments are mainly a legacy system for applications of COM components that don't support multi-threading. They were typically used with Visual BASIC (as this did not support multi-threaded code) and legacy applications.
I guess that the message pump requirement for Word stems from either the COM API or parts of the application not being thread safe. Bear in mind that the .NET threading and garbage collection models don't play nicely with COM out of the box. COM has a very simplistic garbage collection mechanism and threading model that requires you to do things the COM way. Using the standard Office PIAs still requires you to explicitly shut down COM object references, so you need to keep track of every COM handle created. The PIAs will also create stuff behind the scenes if you're not careful.
.NET-COM integration is a whole topic all by itself, and there are even books written on the subject. Even using COM APIs for Office from an interactive desktop application requires you to jump through hoops and make sure that references are explicitly released.
Office can be assumed to be thread-unsafe, so you will need a separate instance of Word, Excel or other Office applications for each thread. You would have to incur the starting overhead or maintain a thread pool. A thread pool would have to be meticulously tested to make sure all COM references were correctly released. Even starting and shutting down instances requires you to make sure all references are released correctly. Failure to dot your i's and cross your t's here will result in large numbers of dead COM objects and even whole running instances of Word being leaked.
Wikipedia suggests it means the program's main Event Loop.
I think that this Channel 9 discussion has a nice succinct explanation:
This process of window communication is made possible by the so-called Windows Message Pump. Think of the Message Pump as an entity that enables cooperation between application windows and the desktop.

QProcess: Destroyed while process is still running

I am using Qt for developing a custom control interface to xmgrace, a 2D plotting library.
I have 3 components in my project:
A GUI made in Qt
A QThread which runs some shared object code from C in a background thread.
An xmgrace window connected to both the above using a pipe. (Using the grace_np library)
Communication from (1) --> (2) is done by changing status of some global variables declared in the shared object code.
Communication from (1) --> (3) & (2) --> (3) is using built in functions provided by the grace_np library.
Now, communication from (2) --> (1) is what is causing problems. I tried 2 possible ways I could think of:
a) Declaring a shared object in Qt code which emits a Qt Signal and is called within the C code.
b) Returning from the thread and using the return value to perform some operation and then restart the thread.
Both these methodologies have given unreliable results. My GUI gets stuck/causes segmentation fault and I get the message:
QProcess: Destroyed while process is still running
I am not using the QProcess class anywhere in my code. So this has become a mystery.
Please provide some info on what could be the possible causes for this.
PS: The pipe to (3) is one way and is required that way only.
Edit 1:
FYI I'm using Qt 4.2, So I can't use the QObject approach and then use a movetothread()
I'm sorry for not putting the code, as I can't due to company policies and also because I don't know what to put (Its too huge). The shared c code is 400k+ lines
I believe I have found the culprit to my problem. It seems that using the class QMessageBox is causing this problem. I was initially using static function of QMessageBox. Now I have tried declaring it over both the stack and the heap, but the problem still persists.
But I have found that removing all calls to QMessageBox from my code solves the problem.
But then the problem now is, how do I show messages?
I am just speculating here, but is it possible that the modal nature of QMessageBox is blocking the pipe existing between my program and xmgrace and subsequently causing it to quit? Then creating a custom QMessageBox (non modal) might solve this issue.
Edit 2:
I'm not calling the QMessageBox from the worker thread. Plus the way I'm using the worker thread, it never returns unless I close the program. To give an idea my QThread::run function is of the form:
QThread_Object::run()
{
c_init();
c_main();
}
where c_init & c_run are functions linked from shared c code. So it is impossible to call a QMessageBox from within these directly.
For now I'm planning on doing away with the QMessageBox and using the QMainWindow status bar instead. But then it doesn't give the entire functionality. I suppose this could be a bug in Qt 4.2
Edit 3:
I mentioned earlier that communication from (2) --> (1) was what was causing problems. Now I have done away with this communication completely and have discovered more precisely that the problem is caused by invoking QMessageBox anytime after starting the worker thread. Earlier the communication mentioned above was causing Qt to emit a signal indirectly and invoke a QMessageBox which I believe was the culprit.
Edit 4:
Ok, I forgot to mention the biggest mystery surrounding this problem since the beginning. I basically work(Place A) via ssh on a workstation(Place B) on which I code and run this program.
B is connected on 2 physical networks. A is connected to B through Network 1. Now this problem has never occured while working from my terminal at A (ie on ssh via Network 1). But it consistently occurs when I access B directly or through ssh over Network 2. Please note that every time the code is executed on B only. Both these networks are used by hundereds.
Edit 5
Finally, I have solved my problem by sub-classing QDialog and making a custom MessageBox as I don't really require the extended functionality of QMessageBox. I still don't know what precisely within QMessageBox was causing the problem. I suppose some bug within Qt which will always remain a mystery.
Since there's no code I'm shooting in the dark a little here, but it sounds like your QProcess was created on the stack, intentionally or not, or your QThread is getting destroyed prematurely. I'd put money on your QThread objects being launched incorrectly. It's hard to blame you since the documentation is (or was until recently) screwy. Consider reading this thread and this thread and don't sub-class QThread at all.
Edit:
If QMessageBox is your culprit, then I'm guessing that you're displaying it from the child thread. From the documentation:
In GUI applications, the main thread is also called the GUI thread
because it's the only thread that is allowed to perform GUI-related
operations.
There are several ways to display messages from a child thread. Personally, I use qt's error reporting scheme and redirect qCritical, qDebug, etc to stderr. Another easier way to do it would be for you to emit a QString signal from your worker thread that's caught by your GUI thread, which then displays/collects the error. I like to have my MainWindow collect the errors and then display them all at once when the worker thread finishes.
Edit 2:
Since the problem seems to be QMessageBox being modal (i.e., blocking your main thread while the worker thread moves forward), you can easily solve this by using QMessageBox in its non-modal modes. Simply pass 0 as the parent widget in the QMessageBox constructor/static function. Processing will continue without waiting for the user to exit the window--this might also result in multiple message boxes being open at the same time. If that helps you avoid the error, go over your code carefully to make sure the windows are properly destroyed after closing.

Callback from other thread

I have problem with callbacks from other application thread. Dll is some kind of wrapper between Addinational application and Application program and its working within Application program memory(with same PID). Addinational application(other thread and PID) is application which in main loop looking for "something" and when found it, it calls Callback function from Dll and then Dll calls Callback function from Application program. Maybe its little confusing look at image above.
And theres crash(when dll calls callback function from application program) with message:
Unhandled exception at 0x70786a46 in MainProgram.exe: 0xC0000005: Access violation reading location 0x00000164.
Call stack mshtml.dll
Propably application program using IE controls to update UI. How could I update UI when Addinational application callsback?
SendMessage is a general solution for posting results to a GUI thread. It does all thread synchronization for you and doesn’t return until the message has been processed by the receiver thread's window.
PostThreadMessage is less reliable since the message may/will be lost when the receiver is in a modal loop for e.g. MessageBox, unless you have added a hook that intercepts the thread message – so just use SendMessage.
More advanced techniques involve doing the thread synchronization yourself, e.g. with a buffer, but anyway that will probably also involve SendMessage for a GUI thread, so, I suggest you just start with that, and if that’s good enough, then don’t do more.
EDIT: dang, I see now that although the first sentence talks about threads, it's really about sending data from one process to another process. Well, for that there is WM_COPYDATA. Please consider that a (user level) pointer from one process, is not valid in the other process.
So you want to call a function that belongs to another process. I think you need to read about RPC:s http://msdn.microsoft.com/en-us/library/windows/desktop/aa378651%28v=vs.85%29.aspx

need help in UI threads in C++

I'm using UI threads and I built one thread with message map and it works fine, the problem is when I'm tring to create another thread from the first one.
When I'm getting to this line:
this->PostThreadMessage(WM_MYTHREADMESSAGE,0,0);
I'm getting the next message:
"No symbols are loaded for any call stack frame. The source code cannot be displayed"
I dont know if its could be the reason for the problem but I have built two message maps, one for each thread, I don't know if its ok to do so.
The question is difficult to understand. I'm assuming that you're stepping through your program in the debugger, and you get to that PostThreadMessage line.
If you choose Step Into, the debugger will try to step into the PostThreadMessage call (or the framework wrapper, depending on the type of this). Since PostThreadMessage is a system call, it's likely you don't have symbols for that code. The debugger will just show you disassembly. You can try to use the Microsoft symbol server, but I don't see much point in trying to trace into PostThreadMessage. If the parameters are right, it's going to post the message to the specified thread's queue. Not much to see there.
Posting message to other threads is tricky business. Most Windows programs, even multithreaded ones, typically keep all the UI work to a single thread. It can be done, but there are a lot of caveats and it's usually not worth the pain.
So there are couple of things:
if you want to notify the UI thread from the worker thread, then you should not use PostThreadMessage, here is why.
When this->PostThreadMessage(...) called in a member function of thread A, the message will be sent to thread A, because this points to CWinThread of A. You have to get a pointer to the other thread to post a message to it.
Finally if you want to notify your UI thread, use PostMessage to send a message to the window created by that thread. Add a corresponding handler to the window message map.
Hope this helps