Must a DLL be multithread when called by a Delphi object? - multithreading

I derived a TMyThread object from TThread in Delphi, and in TMyThread.Execute, it will invoke a DLL written by Visual C++. In that case, must the DLL also compiled with the Multi-thread library and support multi-thread as well?

Older versions of the MSVC runtime come in both multi-threaded and single-threaded variants. The difference is that the single-threaded variant does not protect against potential race conditions. So, if the code that calls into the MSVC runtime does so from more than one thread, the single-threaded runtime cannot be safely used.
The scenario that you describe has only a single thread executing code inside your MSVC DLL. In which case the single-threaded MSVC runtime is safe to use. It does not matter that the host executable is multi-threaded. All that counts is whether multiple threads call into the MSVC runtime attached to your MSVC DLL.
MSVC stopped shipping separate single-threaded and multi-threaded runtimes many releases ago. One wonders whether or not it makes a difference to your application. Can you detect any performance difference between the two runtime options. If not then it would make sense to me to use the multi-threaded runtime. Choosing the single-threaded runtime is just storing up a potential debugging headache when you forget about this in a future change to the code and introduce extra threads to your MSVC DLL.

The C++ DLL should be MT, if you intend to use it MT. If you intend to use it from only one single thread of your application, then you don't have to do that. But you should clearly document this as soon as you have the slightest doubt that there could be a thread conflict, e.g. with data structures internally managed within the DLL. Or use MT anyway, take care of proper locking and forget about it. (My previous Delphi statement still stands true).

Related

C++11: Is std::thread on linux depending on pthread library?

I read that pthread is C library and is not compatible with C++ object model, especially when talking about exception handling.
So I wish to know on linux system, how gcc/clang implements std::thread, is it calling some linux native functions/kernel apis or something?
Also, how is std::thread_local implemented, related with __thread?
I read that pthread is C library and is not compatible with C++ object model, especially when talking about exception handling.
This information is inaccurate.
how gcc/clang implements std::thread
They call a platform-specific thread creation function. On Linux it is pthread_create. You can call this function directly.
When a thread throws an exception and it is not caught std::terminate is called.
Note that your application must be compiled and linked with -pthread flag (using -lpthread is unnecessary and insufficient with both C and C++).
I read that pthread is C library and is not compatible with C++ object model, especially when talking about exception handling.
There's a statement in the neighborhood of this that is true, but this statement as written is not true.
There are two facts here.
If YOU call pthreads functions yourself, it is indeed just a C library, and you had better make sure you do everything correctly in regards to exception safety. If you pass function pointers to pthread_create_... and those functions will throw exceptions... your program can have big problems. That should be obvious, it will be true whenever you talk to a C library from C++.
That does not mean it is impossible to use such a library with a C++ program!
pthread does not actually need to know about any of your objects, or any of their ctors or dtors, or any of that, in order to make your program multithreaded. All it needs to spawn a thread, is a function pointer, and that function pointer will have a completely C-compatible signature.
When the C++ compiler calls pthreads functions in order to implement std::thread, the compiler is going to emit code that talks to pthread correctly. If it uses pthread in an illegal way to implement your C++ program, it's a bug in the compiler or standard library.
Use ldd myExecutable on compiler output to find out.
Both libstdc++ and libc++ apparently use pthreads, but they are not required to do that. Evidence of it can be found in native_handle methods documentation here and here. The documents say:
Accesses the native handle of *this.
The meaning and the type of the result of this function is implementation-defined. On a POSIX system, this may be a value of type pthread_cond_t*. On a Windows system, this may be a PCONDITION_VARIABLE.
and
Returns the implementation defined underlying thread handle.

Why can I not blocking main thread in WinRT(Windows Store App)?

This question is not about "should I block my main thread" as it is generally a bad idea to block a main/STA/UI thread-for messaging and UI operations, but why WinRT C++/cx doesn't allow any blocking of the main thread compared to iOS, Android, and even C#(await doesn't actually block though).
Is there a fundamental difference in the way Android or iOS block the main thread? Why is WinRT the only platform that doesn't allow any form of blocking synchronization?
EDIT: I'm aware of co-await in VS2015, but due to backward compatibility my company still uses VS2013.
Big topic, at break-neck speed. This continues a tradition that started a long time ago in COM. WinRT inherits about all of the same concepts, it did get cleaned-up considerably. The fundamental design consideration is that thread-safety is one of the most difficult aspects of library design. And that any library has classes that are fundamentally thread-unsafe and if the consumer of the library is not aware of it then he'll easily create a nasty bug that is excessively difficult to diagnose.
This is an ugly problem for a company that relies on a closed-source business model and a 1-800 support phone number. Such phone calls can be very unpleasant, threading bugs invariably require telling a programmer "you can't do that, you'll have to rewrite your code". Rarely an acceptable answer, not at SO either :)
So thread-safety is not treated as an afterthought that the programmer needs to get right by himself. A WinRT class explicitly specifies whether or not it is thread-safe (the ThreadingModel attribute) and, if it is used in an unsafe way anyway, what should happen to make it thread-safe (the MarshallingBehavior attribute). Mostly a runtime detail, do note how compiler warning C4451 can even make these attributes produce a compile-time diagnostic.
The "used in an unsafe way anyway" clause is what you are asking about. WinRT can make a class that is not thread-safe safe by itself but there is one detail that it can't figure out by itself. To make it safe, it needs to know whether the thread that creates an object of the class can support the operating system provided way to make the object safe. And if the thread doesn't then the OS has to create a thread by itself to give the object a safe home. Solves the problem but that is pretty inefficient since every method call has to be marshalled.
You have to make a promise, cross-your-heart-hope-to-die style. The operating system can avoid creating a thread if your thread solves the producer-consumer problem. Better known as "pumping the message loop" in Windows vernacular. Something the OS can't figure out by itself since you typically don't start to pump until after you created a thread-unsafe object.
And just one more promise you make, you also promise that the consumer doesn't block and stops accepting messages from the message queue. Blocking is bad, implicit is that worker threads can't continue while the consumer is blocking. And worse, much worse, blocking is pretty likely to cause deadlock. The threading problem that's always a significant risk when there are two synchronization objects involved. One that you block on, the other that's hidden inside the OS that is waiting for the call to complete. Diagnosing a deadlock when you can't see the state of one of the sync objects that caused the deadlock is generally unpleasant.
Emphasis on promise, there isn't anything the OS can do if you break the promise and block anyway. It will let you, and it doesn't necessarily have to be fatal. It often isn't and doesn't cause anything more than an unresponsive UI. Different in managed code that runs on the CLR, if it blocks then the CLR will pump. Mostly works, but can cause some pretty bewildering re-entrancy bugs. That mechanism doesn't exist in native C++. Deadlock isn't actually that hard to diagnose, but you do have to find the thread back that's waiting for the STA thread to get back to business. Its stack trace tells the tale.
Do beware of these attributes when you use C++/CX. Unless you explicitly provide them, you'll create a class that's always considered thread-safe (ThreadingModel = Both, MarshallingType = Standard). An aspect that is not often actually tested, it will be the client code that ruins that expectation. Well, you'll get a phone call and you have to give an unpleasant answer :) Also note that OSX and Android are hardly the only examples of runtime systems that don't provide the WinRT guarantees, the .NET Framework does not either.
In a nutshell: because the policy for WinRT apps was "thou shalt not block the UI thread" and the C++ PPL runtime enforces this policy whilst the .NET runtime does not -- look at ppltasks.h and search for prevent Windows Runtime STA threads from blocking the UI. (Note that although .NET doesn't enforce this policy, it lets you accidentally deadlock yourself instead).
If you have to block the thread, there are ways to do it using Win32 IPC mechanisms (like waiting on an event that will be signaled by your completion handler) but the general guidance is still "don't do that" because it has a poor UX.

Delphi DLL - thread safe

I have a Delphi DLL and I want to load it in my app inside a thread (more than one, to be exactly). The DLL just creates a object, then it uses it and destroys it. For that point of view, the DLL code is thread safe.
But what happens if I load that DLL in a thread? Is the DLL still going to be thread safe? What should I know about threads loading DLL? I have seen that the VCL has the IsMultThread property that is set when we create a thread, but will the dll get notified about that or should I do it manually?
The most common pitfall is use of global variables. So long as you don't use any global variables (or properly synchronise access to the ones you do use) you will be a long way towards thread safety.
IsMultiThread is used by, for example, the memory manager to make optimisations in the single threaded case. Personally I don't feel this is a worthwhile optimisation these days since practically all useful code has threads of some description. I'd just set IsMultiThread to True at the start of your DLL, e.g. in the begin/end block of your DLL .dpr file, or in one of your unit's initialization sections which amounts to the same thing.
To answer your question directly, the instance of IsMultiThread in your DLL will not be set true unless you create a thread in that DLL. Since you create the threads in your EXE you need to do it yourself in the DLL.
More generally, it's simply impossible to say much about thread safety of your code without knowing what it does and what you actually mean by thread safe. The latter point may sound odd, but what I'm referring to is the issue discussed in Eric Lippert's famous What is this thing you call "thread safe"? article.
Set IsMultiThread to True the first thing in the main block of your library project:
library MyLibrary;
begin
IsMultiThread := True;
...
end.
This will instruct the memory manager to use thread-safe allocation/deallocation routines.
If you are careful about what you do in the thread, you'll be ok. If you need to update the VCL of the main thread, use synchronize, or better yet, don't.
I have a big DLL where I do lots of database access, and it runs in a thread. Everything worked great in my unit tests, but blew up sky high when run within a thread in the main app. Turns out, I had to re-read the database docs on thread safety. In my case, it's DBISAM and I just had to be sure to create a new session for the threaded database instance, so it wouldn't collide with the main one.
Another place where I ran into trouble (again, worked great in unit tests, failed in threads) is with XML handling. I had to call CoInitialize/CoUnInitialize before/after using the XML DOM stuff. This holds true for any SOAP stuff, which uses the XML DOM under the hood.

Win32 alternative for the destructor in pthread_keycreate (when I cannot control dllmain)

In pthreads, you can associate a destructor function with each per-thread storage slot. When a thread dies, if the slot is non-0, the destructor is called.
In a Win32 DLL, the DLLMain function, called at thread exit, can do the same thing.
What can I do in code that lives in a purely static library?
This is a hard problem, and requires sticking callbacks in special locations. Luckily for you, it is solved in Boost.Thread. Use boost::this_thread::at_thread_exit, or boost::thread_specific_ptr
Windows support Thread Local Storage (TLS) in a DLL. It can be very practical if you want have some memory blocks per thread with the unique value (unique per thread). Inside of any other function from the DLL you can get the value which correspond to the current thread in very easy way. It is very useful in some scenarios. Look at here for more details.
I dun't use pthreads myself, but I suppose that per-thread storage slot introduced to make the work with TLS more comfortable.
UPDATED: From your comment I see that you misunderstand my answer. I'm not a POSIX developer, I develop in Win32 only and your question is about WIn32 API possibilities of per-thread allocation and deallocations. I try to explain the possibilities and you can decide yourself which one are better for your specific scenarios.
The equivalent of pthread_XXX functions in Win32 are following:
pthread_key_create TlsAlloc
pthread_setspecific TlsSetValue
pthread_getspecific TlsGetValue
pthread_key_delete TlsFree
I not recommended you to use the construct __declspec(thread), which is more compiler specific.
The example Using Thread Local Storage shows how to use thread local storage (TLS) without DLLs, but I personally like and use TLS only in DLL.
The destructor parameter of the pthread_key_create function has no analog in Win32, but I don't see here any problem. All C/C++ compilers support __try {/**/} __finally {/**/} construct of the Structured Exception Handling so you can use it in the body of your thread function and implement in the way any Cleaning up Resources exacly like you can do this in the main thread.
I find pity that you not included in your question an example which shows how you typically use destructor of the pthread_key_create function. I find that examples can clear much things without a lot of words. So if my answer do not help you we can better explain all in examples: you write an example and probably short comment what it should do and I could write the same code using Win32 API only in C or C++.

Is it safe to call a dll function from multiple threads in a single application?

I am writing a server application in Delphi 2009 that implements several types of authentication. Each authentication method is stored in a separate dll. The first time an authentication method is used the appropriate dll is loaded. The dll is only released when the application closes.
Is it safe to access the dlls without any form of synchronisation between the server threads (connections)?
Short answer:
Yes, it is generally possible to call a DLL function from multiple threads, since every thread has it's own stack and calling a DLL function is more or less the same as calling any other function of your own code.
Long answer:
If it is actually possible depends on the DLL functions using a shared mutable state or not.
For example if you do something like this:
DLL_SetUser(UserName, Password)
if DLL_IsAuthenticated then
begin
...
end;
Then it is most certainly not safe to be used from different threads. In this example you can't guarantee that between DLL_SetUser and DLL_IsAuthenticated no other thread makes a different call to DLL_SetUser.
But if the DLL functions do not depend on some kind of predefined state, i.e. all necessary parameters are available at once and all other configuration is the same for all threads, you can assume it'll work.
if DLL_IsAuthenticated(UserName, Password) then
begin
...
end;
But be careful: It might be possible that a DLL function looks atomic, but internally uses something, which isn't. If for example if the DLL creates a temporary file with always the same name or it accesses a database which can only handle one request at a time, it counts as a shared state. (Sorry, I couldn't think of better examples)
Summary:
If the DLL vendors say, that their DLLs are thread-safe I'd use them from multiple threads without locking. If they are not - or even if the vendors don't know - you should play it safe and use locking.
At least until you run into performance problems. In that case you could try creating multiple applications/processes which wrap your DLL calls and use them as proxies.
For your DLLs to be thread-safe you need to protect all shared data structures that multiple threads in one process could access concurrently - there is no difference here between writing code for a DLL vs. writing code for an executable.
For multiple processes there is no risk in concurrent access, as each process gets its own data segment for the DLL, so variables with the same name are actually different when seen from different processes. It is actually much more difficult to provide data in a DLL that is the same from different processes, you would basically need to implement the same things you would use for data exchange between processes.
Note that a DLL is special in that you get notifications when a process or a thread attaches to or detaches from a DLL. See the documentation for the DllMain Callback Function for an explanation, and this article for an example how to use this in a Delphi-written DLL. So if your threads are not completely independent from each other (and no shared data is write-accessed), then you will need some shared data structures with synchronized access. The various notifications may help you with properly setting up any data structures in your DLL.
If your DLLs allow for completely independent execution of the exported functions, also do check out the threadvar thread-specific variables. Note that for them initialization and finalization sections are not usable, but maybe the thread notifications can help you there as well.
Here's the thing - you cannot assume that the DLL's are thread safe if you don't have control over the source code (or documentation stating it is) so therefore you should assume it is not
If you talking about Win32 DLLs, they're meant to be safe if called by multiple threads, applications. I don't know what your DLL does, but if your DLL is using a lockable resource like a file or a port, then there could be trouble based on the implementation inside the DLL.
I am not familiar with the working of Delphi 2009 authentication DLLs. Maybe you should add that information to the headline (that you're talking specifically about the Delphi 2009 DLLs)

Resources