Can a managed thread call a C++ method that calls boost asio async_write - visual-c++

I am writing a client in C# that is communicating with a Windows C++ DLL that uses boost asio asynchronous calls. I have read before that ASIO does not work too well in a managed environment. The VC++ DLL is an unmanaged project that creates an unmanaged thread for the I/O handlers. The C# code creates a background thread to handle sending messages to the C++ DLL via pinvoke. My question is - can the call to the boost::asio::async_write method be on a managed thread? Or, does it have to be on an unmanaged thread?
It will help simplify the logic and processing if I can make the call to async_write on the managed thread. But, I'm worried about what might happen when the .NET garbage collector runs and stops the threads. I don't know if ASIO will be able to handle that or not. I'm not passing any pointers to data defined in the C# code, so that should not be a problem.

The notion of a "managed thread" is a weak one, the operating system only supports one kind of thread. A thread that runs managed code isn't special, managed code gets translated to the exact same kind of machine code that a C compiler generates. The only difference is that the CLR knows about the thread and will have a reason to have a look at its stack when a garbage collection occurs. Necessary to find stack frames of managed code that may contain object references.
It will not be interested in any stack frames that belong to native code, it simply ignores them. And yes, the thread may be paused while the GC performs the search but only if it is currently executing managed code. Native code keeps running, it will only block when it returns back to a managed method if a GC is in progress. This pause isn't otherwise different from any other kind of reason a thread may pause, including losing the processor for a while when the operating system scheduler runs something else.
So using boost::asio is fine, nothing goes wrong. Just as the many other ways that a managed program can execute native code, including operating system calls. The only detail you'll want to take care of is making sure that your code gets compiled without /clr in effect. Compiling boost code to IL works fine, it just isn't very efficient.

Related

Application crashes once after I call MAPIUninitialize api

So, I have been working with MAPI API's. In that Whenever I call the MAPIUninitialize api, my application crashes. on further debugging, I found that, IMAPISession::OpenMsgStore is the reason behind the crash, whenever the OpenMsgStore function is executed during the program runtime, my app crashes exactly after the MAPIUninitialize is triggered. which is similar to the discussion in this thread mentioned below, in which soln is not available.
https://peach.ease.lsoft.com/scripts/wa-PEACH.exe?A2=MAPI-L;e6f3847a.0801&S=
I have checked my program for memory leaks, and I'm sure there is none and also, if i comment that particular api, my program doesnt crash, i dont understand the reason for the crash. I have tried all possible alternatives. Can anyone help on this ?
It mostly likely means you still have live MAPI objects. It is also possible that the sequence of MAPIInitialize / MAPIUninitialize is too quick and the common Office run-time is still (asynchronously) initializing when you attempt to shut it down.
Also, not all stores are created equal - IMAP4 is probably the worst.
It is not clear where and when these methods are used. Is it a secondary thread?
Anyway, here is what MSDN states:
A client must also invoke MAPIInitialize on every thread before using any MAPI objects and MAPIUninitialize when that use is complete. These calls should be made even if the objects to be used are passed to the thread from an external source. MAPIInitialize and MAPIUninitialize can be called from anywhere except from within a Win32 DllMain function, a function that is invoked by the system when processes and threads are initialized and terminated, or upon calls to the LoadLibrary and FreeLibrary functions.
I'd suggest playing with the MFCMAPI source code - you can run it under the debugger and see whether an issue is still reproducible or not.
Thanks for your wonderful suggestions. I have fixed the issue, my application actually calls the mapi api's defined in a c++ dll from golang. Because of that, every mapi api defined as a DLL function had different thread ID, When I tied the DLL function calls to same thread using runtime.LockOSThread() / runtime.UnlockOSThread() , it started working, no more crashes.
Ref: https://golang.org/pkg/runtime/#LockOSThread

Access a specific thread from Grand Central Dispatch

For a Mac application I'm using an external (C++) library that has build in memory management. A drawback of that memory manager is that memory needs to be deleted on the same thread as the new call.
Currently I'm using GCD to run code concurrently, but I run into the problem that objects of that library get allocated on various threads and I can't correctly delete them.
Is there a way to call the delete operator on the original thread that called new? I realise that GCD wants to abstract the underlying threads away from me, but otherwise I've to write a custom GCD-like implementation where I have full control over the threads.

Does Firebase set and get run on the main thread?

Do they run on the same thread as the node process or do they run on a different thread? The CPU usage for my node process goes above 100% when I do a lot of sets and gets (and add several event listeners) on firebase. Any ideas why?
There is only 1 main thread in your Node application, all of your code and all library javascript code will run in this thread. When a library attempts to use IO, it may call upon libuv which runs in its own thread. Libraries may also have their own C++ bindings. Without knowing what you're doing and how the 3rd party library is implemented, it's impossible to tell.

QSerialPort - Is it possible to read() and write() on separate threads?

We have a DLL that provides an API for a USB device we make that can appear as a USB CDC com port. We actually use a custom driver on windows for best performance along with async i/o, but we have also used serial port async file i/o in the past with reasonable success as well.
Latency is very important in this API when it is communicating with our device, so we have structured our library so that when applications make API calls to execute commands on the device, those commands turn directly into writes on the API caller's thread so that there is no waiting for a context switch. The library also maintains a listening thread which is always waiting using wait objects on an async read for new responses. These responses get parsed and inserted into thread-safe queues for the API user to read at their convenience.
So basically, we do most of our writing in the API caller's thread, and all of our reading in a listening thread. I have tried porting a version of our code over to using QSerialPort instead of native serial file i/o for Windows and OSX, but I am running into an error whenever I try to write() from the caller's thread (the QSerialPort is created in the listening thread):
QObject: Cannot create children for a parent that is in a different thread.
which seems to be due to the creation of another QObject-based WriteOverlappedCompletionNotifier for the notifiers pool used by QSerialPortPrivate::startAsyncWrite().
Is the current 5.2 version of QSerialPort limited to only doing reads and writes on the same thread? This seems very unfortunate as the underlying operating systems do not have any such thread limitations for serial port file i/o. As far as I can tell, the issue mainly has to do with the fact that all of QSerialPort's notifier classes are based on QObject.
Does anyone have a good work around to this? I might try building my own QSerialPort that uses notifiers not based on QObject to see how far that gets me. The only real advantage QObject seems to be giving here is in the destruction of the notifiers when the port closes.
Minimal Impact Solution
You're free to inspect the QSerialPort and QIODevice code and see what would need to change to make the write method(s) thread-safe for access from one thread only. The notifiers don't need to be children of the QSerialPort at all, they could be added to a list of pointers that's cleaned up upon destruction.
My guess is that perhaps no other changes are necessary to the mainline code, and only mutex protection is needed for access to error state, but you'd need to confirm that. This would have lowest impact on your code.
If you care about release integrity, you should be compiling Qt yourself anyway, and you should be having it as a part of your own source code repository, too. So none of this should be any problem at all.
On the Performance
"those commands turn directly into writes on the API caller's thread so that there is no waiting for a context switch" Modern machines are multicore and multiple threads can certainly run in parallel without any context switching. The underlying issue is, though: why bother? If you need hard-realtime guarantees, you need a hard-realtime system. Otherwise, nothing in your system should care about such minuscule latency. If you're doing this only to make the GUI feel responsive, there's really no point to such overcomplication.
A Comms Thread Approach
What I do, with plenty of success, and excellent performance, is to have the communications protocol and the communications port in the same, dedicated thread, and the users in either the GUI thread, or yet other thread(s). The communications port is generally a QIODevice, like QTcpSocket, QSerialPort, QLocalSocket, etc. Since the communications protocol object is "just" a QObject, it can also live, with the port, in the GUI thread for demostration purposes - it's designed fully asynchronously anyway, and doesn't block for anything but most trivial of computations.
The communications protocol is queuing multiple requests for execution. Even on a single-core machine, once the GUI thread is done submitting all of the requests, the further execution is all in the communications thread.
The QSerialPort implementation uses asynchronous OS APIs. There's little to no benefit to further processing those async replies on separate threads. Those operations have very low overhead and you will not gain anything measurable in your latency by trying to do so. Remember: this is not your code, but merely code that pushes bytes between buffers. Yes, the context switch overhead may be there on heavily loaded or single-core systems, but unless you can measure the difference between its presence and absence, you're fighting imaginary problems.
It is possible to use any QObject from multiple threads, of course, as long as you serialize the access to it via the event queue mutex. This is done for you whenever you use the QMetaObject::invokeMethod or signal-slot connections.
So, add a trivial wrapper around QSerialPort that exposes the write as a thread-safe method. Internally, it should use a signal-slot connection. You can call this thread-safe write from any thread. The overhead in such a call is a mutex lock and 2+n malloc/free calls, where n is the non-zero number of arguments.
In your wrapper, you can also process the readyRead signal, and emit a signal with received data. That signal can be processed by a QObject living in another thread.
Overall, if you do the measurements correctly, and if your port thread's implementation is correct, you should find no benefit whatsoever to all this complication.
If your communications protocol does heavy data processing, this should be factored out. It could go into a separate QObject that can then run on its own thread. Or, it can be simply done using dedicated functors that are executed by QtConcurrent::run.
What if you use QSerialPort to open and configure the serial port, and QSocketNotifier to monitor for read activity (and other QSocketNotifier instances for write completion and error handling, if necessary)?
QSerialPort::handle should give you the file descriptor you need. On Windows, if that function returns a Windows HANDLE, you can use _open_osfhandle to get a file descriptor.
As a follow up, shortly after this discussion I did implement my own thread-safe serial port code for POSIX systems using select() and the like and it is working well on multiple threads in conjunction with Qt and non-Qt applications alike. Basically, I have abandoned using QtSerialPort at all.

Delphi - Creating a control that runs in its own process

HI
I have a control that accesses a database using proprietary datasets. The database is an old ISAM bases database.
The control uses a background thread to query the database using the proprietary datasets.
A form will have several of these controls on it, each using their own thread to access the data as they all need to load simultaneously.
The proprietary datasets handle concurrency by displaying a VCL TForm notifying the user that the table being opened is locked by another user and that the dataset is waiting for the lock to be released.
The form has a cancel button on it which lets the user cancel the lock wait.
The problem:
When using the proprietary datasets from within a thread, the application will crash, hang or give some error if the lock wait form it displayed. I suspect this is to do with the VCL not being thread safe.
I have solved the issue by synchronizing Dataset.Open however this holds up the main thread until the dataset.open returns, which can take a considerable amount of time depending on the complexity of the query.
I have displayed a modal progress bar which lets to user know that something it happening but I don't like this idea as the user will be sitting waiting for the progress bar to complete.
The proprietary dataset code is compiled into the main application, i.e. its not stored in a separate DLL. We are not allowed to change how the locking works or whether a form is displayed or not at this stage of the development process as we are too close to release.
Ideally I would like to have Dataset.open run in the controls thread as well instead of having the use the main thread, however this doesn't seem likely to work.
Can anyone else suggest a work around? please.
Fibers won't help you one bit, because they are in the Windows API solely to help ease porting old code that was written with cooperative multitasking in mind. Fibers are basically a form of co-routines, they all execute in the same process, have their own stack space, and the switching between them is controlled by the user code, not by the OS. That means that the switching between them can be made to occur only at times that are safe, so no synchronization issues. OTOH that means that only one fiber can be running within one thread at the same time, so using fibers with blocking code has the same characteristics as calling blocking code from within one thread - the application becomes unresponsive.
You could use fibers together with multiple threads, but that can be dangerous and doesn't bring any benefit over using threads alone.
I have used fibers successfully within VCL applications, but only for specific purposes. Forget about them if you want to deal with potentially blocking code.
As for your problem - you should make a control that is used for display purposes only, and which uses the standard inter-process communication mechanisms to exchange data with another process that accesses your database.
COM objects can run in out-of-process mode. May be in delphi it will be a bit easier to use them, then another IPC mechanisms.

Resources