I want to switch from CreatMutex to boost::interprocess::named_mutex to limit my application to a single instance. Both methods works when the application runs and ends just fine. However, the lock is not released when the application crashes and using boost::interprocess::named_mutex. I could resolve that issue by using two name_mutex but I don't really understand the issue.
Why is the lock for boost::interprocess::named_mutex not released when the application crashes but it is release with CreatMutex? What's the difference?
boost::interprocess::named_mutex mutex(boost::interprocess::open_or_create, "my_mutex");
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> lock(mutex, boost::interprocess::try_to_lock);
if(!lock) {
return 1; //exit
}
//application may crash here.
boost::interprocess::named_mutex::remove("my_mutex");
return 1; //exit
Caveat: I've not spent much time with boost::interprocess, so this information is just from a quick inspection of the source. That said, I've used the Windows synchronisation API's a lot, so here goes...
The main difference between the two methods of interprocess synchronisation is how the object exists within the system.
With boost::interprocess::named_mutex, as well as a system-specific mutex, it looks like a synchronisation object is created as a file on the system. The location of the file is based on Registry entries (see note 1) (at least in Boost 1.54.0)... it's most likely located under the Common Application Data folder (see note 2). When the aplication crashes, this file is, in your case, not removed. I'm not sure if this is by design... however in the case of an application crash, it's perhaps best not to mess with the file system, just in case.
Conversely, when you use CreateMutex, an object is created at the kernel mode, which for named mutexes can be accessed by several applications. You get a handle to the Mutex by specifying the name when you create it, and you lose the handle when you call CloseHandle on it. The mutex object is destroyed when there are no more handles referencing it.
The important part of this is in the documentation:
The system closes the handle automatically when the process terminates. The mutex object is destroyed when its last handle has been closed.
This basically means that Windows will clean up after your application.
Note that if you don't perform a ReleaseMutex, and your application owns the mutex when it dies, then it's possible/likely that a waiting thread or process would see that the mutex had been abandoned (WaitForSingleObject returns WAIT_ABANDONED), and would gain ownership.
I apologise for not providing a solution, but I hope it answers your question about why the two systems act differently.
Just as an aside, using registry entries to get this information is horrible - it would be safer, and more future-proof, to use SHGetKnownFolderPath. But I digress.
Depending on your OS version, this could be %ALLUSERSPROFILE%\Application Data\boost.interprocess or ProgramData\boost.interprocess, or somewhere else entirely.
What you want is not trivial and the interprocess_mutex definitively the wrong way to do.
What you may could do is remove the mutex on termination, by providing a remover destructor and/or in a catch(...). But this is not guaranteed to work, since it won't be done if you terminate the process directly (from the OS). Also it could accidently remove the mutex while your application starts twice.
One approach is to safe the process-id (for example in a shared memory) on the first time your program starts and remove it when it stops. Everytime you start the application read and check if the id still in process, if not, start the program.
Related
There is this multiplatform (Windows, Linux, Cygwin) dynamic library which is loaded at run time by a Cygwin executable. At some point of time, during the normal workflow, the DLL allocates a pool of threads for use. These threads are managed as global variables (reference counted). So when the client process goes to shutdown, it starts releasing global objects, threads should be released too.
Issue is, as I understand, that during the process shutdown, the Loader lock is acquired and further down the street, threads want to acuiqre the same lock and, we have now a deadlock.
Now my ask for advise is, how we can make a nice shutdown?
The DLL has no init() or uninit() methods to be called. The client at best can be enhanced with some code before the end of main () (so this is before the process shutdown).
If I detach the threads, instead of joining them, during the global var clean up, memory goes corrupted. If I terminate them, we have ugly process dumps.
Btw, under Linux I see no such problems.
DLL is only C++14, client is C99 (Cygwin).
I tried to make the situation clear, but let me know if you have further questions. Thanks in advance for any ideas.
The fix is to add an uninit method to the DLL. It may not have one yet, but it needs one. You found out why: while the OS will call DllMain on DLL unload, it does so under loader lock. You need to do things that aren't possible under loader lock, so you need an extra call before DllMain. Naming that method uninit() is reasonable enough.
C++14 is not an issue here; this is an OS mechanism. Loader Lock has been around since ancient times.
At a previous job I struggled with this issue for a pretty lengthy period. Ultimately it came down to only 2 possible solutions:
Clean up every single resource the thread has claim to, then TerminateThread. It's violent and ugly but it works around the THREAD_DETACH issue and I actually found it advised on the Internet.
If you have the luxury of being able to get advance notice prior to PROCESS_DETACH - clean up everything at that early point, including orderly shutdown of your threads. Then by all means do absolutely nothing during PROCESS_DETACH - yes, don't even free any lingering heap objects, as you may be exposing yourself to deadlock or crash risks and the process is going down and freeing up all its resources anyway.
As an added note, I also learned to avoid at all costs having any global variables linked to the DLL lifetime. These will have their constructors and destructors executed in the DllMain context, needless to say more... If you need global singletons in a DLL, make sure to have manual control on their lifetimes (on both ends, so no auto-destruct smart pointers either).
I know how mutexes on windows normally work. And yes, sure, I could create a test program to find out the results, I'm just wondering if anybody knows before I write this up.
I saw a IDXGIKeyedMutex in the documentation today. It has a weird method of calling it where you can call two methods: Acquire(Key) & Release(Key). Acquire waits to obtain the "mutex" (shared resource) associated with the key, no matter what thread it is on. Release releases the shared resource, no matter what thread it is on. It is expected that NO thread calls to Acquire result in Acquire being called more than once before a corresponding Release is called (for the same key).
In this fashion, a lock-step producer/consumer can be done, like this:
Producer: Acquire(0), write shared resource, Release(1)
Consumer: Acquire(1), read shared resource, Release(0)
That got me to thinking: Can Windows Mutexes be used this way, though it is not documented? What if I create a mutex for two processes and share it out to both of them, and call WaitForSingleObject(m_hMutex,INFINITE) on the one process, and call ReleaseMutex(m_hMutex) in the other process? I'm assuming this doesn't work? Or does it, but nobody uses it this way?
No, this cannot be done for simple reason: to preserve mutual exclusion
I think you have misunderstood the IDXGIKeyedMutex.
The documentation of Release method simply says:
Return Value
Returns S_OK if successful.
If the device attempted to release a keyed mutex that is not valid or
owned by the device, ReleaseSync returns E_FAIL.
It fails when trying to release a mutex owned by another device and please note here that the mutual exclusion is for the devices that share a resource.
I have a boost threadpool which I use to do certain tasks. I also have a Sensor class that has the pure virtual function doWork(int total) = 0;. Whenever it is requested, my main process gets the necessary Sensor pointer and tells the threadpool to run Sensor::doWork(int total).
threadpool->schedule(boost::bind(&Sensor::doWork,this,123456));
I am dynamically loading libraries of type Sensor, thus it is out of my control if someone else has faulty coding which results in SEGFAULTS and such. So is there a way for me to (in my main process) handle any errors thrown by Sensor::doWork(int total), clean up the thread, delete that sensor object and notify the console what and where the error has occurred?
Really the only way to handle a segmentation fault here is to run Sensor::doWork in a completely separate process.
In UNIX, this involves using fork (or some other similar means), running Sensor::doWork in the child process, and then somehow shuttling the results back to the parent process.
I assume similar means are available in Windows.
EDIT: I thought I'd flesh out a bit some of the things you can do.
Solution #1: you can work with processes in the same fashion as you would threads. For example, you could create process pool that sit there in a loop of
Wait for a task to be passed in over a pipe or queue or some similar object
Perform the task
Return the results over a pipe or queue or some similar object
And since you're executing the tasks in the other processes, you're protected against them crashing. The main difficulty with this solution is actually communicating between processes; maybe boost's interprocess library will help with that. I've mainly done this sort of thing in python, which has a standard multiprocessing module that handles this stuff for you.
Solution #2: You could divide your application into "safe" and "risky" portions that run in different processes. The "risky" portion executes the Sensor::doWork methods and anything else you might want to do in that process -- but only work that is acceptable to be spontaneously lost if it crashes. The "safe" portion deals with any precious information that you cannot afford to lose, and monitors the "risky" portion, performing some recovery operations when the child crashes. And, of course, whatever other work you decide you want to do in the safe part.
If you got a SIGSEGV, even if you caught it you have no guarantee about your program state so there's pretty much no way to recover.
If you're working with 3rd party libraries, and they're buggy, and the library maintainer won't fix it (and you don't have the source) then your only recourse is to run the third party library from within a totally separate binary that talks to the main binary by some means. See for example firefox and plugin-container.
You might want to register a function callback to catch SIGSEV. In C this can be done using signal. Be aware, however, there is not much you can do, when the OS sends you a SIGSEV (note that it isn't required to). You don't really know in what state your program is in, I'd guess. If for example the heap got corrupt, new and delete operations may fail, so even a plain simple
std::cout << std::string("hello world") << std::endl;
statement, might not work since memory from the heap needs to be allocated.
Best, Christoph
I am developing a DLL in MS VC express c++ that will be loaded in multiple client applications at the same time, the DLL has a shared memory space created using data_seg(".SHARED_SPACE_NAME"). In this shared memory space there are some vectors that can be modified.
Lets assume we have a function in the DLL body called doCalc():
_DLLAPI void __stdcall doCalc(int argument)
{
//Add to vector
//Loop through vector
//Erase from vector
//etc.
}
If doCalc is called at the same time from two or more client applications the system will crash.
I want the doCalc calls to "wait in line" for the previous call to finish - like it was a single-threaded application.
So that if client 1 calls and then immediately after client 2 calls, then client 1 should finish the function, and then client 2 should run the function.
The best solution would be to run the DLL as a single thread but I have searched the internet a I do not think it is possible.
I have tried searching the internet for this issue, and I have come up with something about making the function static would make it thread safe.
I have also read that C++0x somehow will make this thread-safe. But that it is not supported in MS VC express.
I have no experience in multithreading, so I hope you can help. Thanks in advance.
The Windows API to use here would be CreateMutex. Create a named mutex object. As you need to manipulate the shared data, call WaitForSingleObject with the mutex handle, and when you are done, call ReleaseMutex. Each thread that calls WaitForSingleObject takes ownership of the mutex and any other thread that calls WaitForSingleObject will stall, until the owning thread calls ReleaseMutex.
Of course, I don't belive you can do what you want to do:
Dlls may be mapped in at different addresses in each process space. If so, all pointers will be incorrect.
C++ does not allow fine grained control over allocations and has many implicit allocations, especially when dealing with STL objects. I don't belive that you can get the vector to store all the relevant data in the shared area.
You are going to have to do this with C style raw arrays.
Looks like you need a system-wide mutex that will protect your critical section of code (the code that mustn't run simultaneously). Making the function static has nothing to do with it, because it doesn't prevent different applications from running it at the same time.
I think that Boost.Interprocess is exactly what you need. It will solve both, the synchronization problem, and the one that Jim Brissom said in his comment that you even haven't thought about yet.
I'm looking for a way to restart a thread, either from inside that thread's context or from outside the thread, possibly from within another process. (Any of these options will work.) I am aware of the difficulty of hibernating entire processes, and I'm pretty sure that those same difficulties attend to threads. However, I'm asking anyway in the hopes that someone has some insight.
My goal is to pause, save to file, and restart a running thread from its exact context with no modification to that thread's code, or rather, modification in only a small area - i.e., I can't go writing serialization functions throughout the code. The main block of code must be unmodified, and will not have any global/system handles (file handles, sockets, mutexes, etc.) Really down-and-dirty details like CPU registers do not need to be saved; but basically the heap, stack, and program counter should be saved, and anything else required to get the thread running again logically correctly from its save point. The resulting state of the program should be no different, if it was saved or not.
This is for a debugging program for high-reliability software; the goal is to run simulations of the software with various scripts for input, and be able to pause a running simulation and then restart it again later - or get the sim to a branch point, save it, make lots of copies and then run further simulations from the common starting point. This is why the main program cannot be modified.
The main thread language is in C++, and should run on Windows and Linux, however if there is a way to only do this on one system, then that's acceptable too.
Thanks in advance.
I think what you're asking is much more complicated than you think. I am not too familiar with Windows programming but here are some of the difficulties you'll face in Linux.
A saved thread can only be restored from the root process that originally spawned the thread, otherwise the dynamic libraries would be broken. Because of this saving to disk is essentially meaningless. The reason is dynamic libraries are loaded at different address each time they're loaded. The only way around this would be to take complete control of dynamically linking, no small feat. It's possible, but pretty scary.
The suspended thread will have variables in the the heap. You'd need to be able to find all globals 'owned' by the thread. The 'owned' state of any piece of the heap cannot be determined. In the future it may be possible with the C++0x's garbage collection ABI. You can't just assume the whole stack belongs to the thread to be paused. The main thread uses the heap when creating threads. So blowing away the heap when deserializing the paused thread would break the main thread.
You need to address the issues with globals. And not just the globals from created in the threads. Globals (or statics) can and often are created in dynamic libraries.
There are more resources to a program than just memory. You have file handles, network sockets, database connections, etc. A file handle is just a number. serializing its memory is completely meaningless without the context of the process the file was opened in.
All that said. I don't think the core problem is impossible, just that you should consider a different approach.
Anyway to try to implement this the thread to paused needs to be in a known state. I imagine the thread to be stoped would call a library function meant the halt the process so it could be resumed.
I think the linux system call fork is your friend. Fork perfectly duplicates a process. Have the system run to the desired point and fork. One fork wait to fork others. The second fork runs one set of input.
once it completes the first fork can for again. Again the second fork can run another set of input.
continue ad infinitum.
Threads run in the context of a process. So if you want to do anything like persist a thread state to disk, you need to "hibernate" the entire process.
You will need to serialise the entire set of the processes data. And you'll need to store the current thread execution point. I think serialising the process is do-able (check out boost::serialize) but the thread stop point is a lot more difficult. I would put places where it can be stopped through the code, but as you say, you cannot modify the code.
Given that problem, you're looking at virtualising the platform the app is running on, and using its suspend functionality to pause the entire thing. You might find more information about how to do this in the virtualisation vendor's features, eg Xen.
As the whole logical address space of the program is part of the thread's context, you would have to hibernate the whole process.
If you can guarantee that the thread only uses local variables, you could save its stack. It is easy to suspend a thread with pthreads, but I don't see how you could access its stack from outside then.
The way you would have to do this is via VM Snapshots; get a copy of VMWare Workstation, then you can write code to automate starting/stopping/snapshotting the machine at different points. Any other approach is pretty untenable, as while you might be able to freeze and dethaw a process, you can't reconstruct the system state it expects (all the stuff that Caspin mentions like file handles et al.)