Mutex, Windows 10, c++, Obtain on one thread, release on another - c++

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.

Related

Do injected process' stay true to locks that are created via the injected DLL/code?

I've created a DLL that injects into a piece of software, the purpose of this DLL is to encrypt some data during run time that shouldn't be accessible by others.
Anyways, we've run into an issue where the encryption/decryption process messes up because another thread (I'm assuming) access' this process for it's own encryption/decryption (in the wrong order).
I don't have access to the software's native code.
My question is....
If I were to make an std::mutex to preform locking operations within a class that is created inside of the injected DLL, but called from the original softwares threads... Would these threads abide by the locking scheme of the DLL? I think the answer is yes, I just want to be sure...
If I were to make an std::mutex to preform locking operations within a class that is created inside of the injected DLL, but called from the original softwares threads...
No, because the other thread in the older code won't know about the mutex, much less abide to it. (mutexes don't magically lock the resource, they are just a way for two or many pieces of code to "signal" each other that some of their "group" needs exclusive access to a resource. If any of the pieces of code ignores the discipline, a mutex isn't going to stop it)

boost::interprocess::named_mutex vs CreateMutex

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.

Putting a mutex in a memory mapped file on windows in C/C++

Does Windows offer any kind of mutex that can be placed in a memory mapped file and used across multiple processes?
Ideally it must be completely self contained such that it can survive by itself in the file, even across a reboot.
Also, no resources should be leaked if I simply remove the file manually while no processes are running.
If possible the solution should also offer the accompanying 'condition' concept which should also be an object that can sit in a shared memory mapped file.
In short, I need something similar to a PTHREADS mutex with the SHARED attribute.
As far as I understand, simply using a PTHREADS mutex is not possible because the SHARED attribute is unsupported in the Windows port of PTHREADS.
To share a synchronization object, give it a name and use the same name in each process when you Create the object.
The following synchronization objects can be shared between process that way :
Mutex
Semaphore
Event
Critical sections cannot be shared, but are faster.
Testing or waiting on those objects is done with the wait family of functions, often WaitForMultipleObjects.
Use the file as its own mutex: Use the LockFileEx function and have everybody agree to lock byte 0 of the file when they want to claim the mutex.
That's not possible. The mutex object itself lives in kernel space to protect it from user code messing with its state. The handle you acquired to it is only valid for the process that acquired it. Technically you could use DuplicateHandle() and put the returned handle in the mmf, but only if you have a handle to the other process that accesses the memory section. That's fairly brittle.
This is why you can specify a name for the mutex in the CreateMutex() function. The other process gets to it by using the same name in the OpenMutex call.

Which process has acquired semaphore

I have created two processes which are accessing same global shared memory. For synchronization purpose, I have used global semaphore.
Can we find out without debugging(using any windows tool) which process had acquired semaphore?
Print a message in your program each time the semaphore is acquired. Why don't you want you/can't you debug?
Really, without more information about what you're trying to do, this is all that can be said.

Why would I want to start a thread "suspended"?

The Windows and Solaris thread APIs both allow a thread to be created in a "suspended" state. The thread only actually starts when it is later "resumed". I'm used to POSIX threads which don't have this concept, and I'm struggling to understand the motivation for it. Can anyone suggest why it would be useful to create a "suspended" thread?
Here's a simple illustrative example. WinAPI allows me to do this:
t = CreateThread(NULL,0,func,NULL,CREATE_SUSPENDED,NULL);
// A. Thread not running, so do... something here?
ResumeThread(t);
// B. Thread running, so do something else.
The (simpler) POSIX equivalent appears to be:
// A. Thread not running, so do... something here?
pthread_create(&t,NULL,func,NULL);
// B. Thread running, so do something else.
Does anyone have any real-world examples where they've been able to do something at point A (between CreateThread & ResumeThread) which would have been difficult on POSIX?
To preallocate resources and later start the thread almost immediately.
You have a mechanism that reuses a thread (resumes it), but you don't have actually a thread to reuse and you must create one.
It can be useful to create a thread in a suspended state in many instances (I find) - you may wish to get the handle to the thread and set some of it's properties before allowing it to start using the resources you're setting up for it.
Starting is suspended is much safer than starting it and then suspending it - you have no idea how far it's got or what it's doing.
Another example might be for when you want to use a thread pool - you create the necessary threads up front, suspended, and then when a request comes in, pick one of the threads, set the thread information for the task, and then set it as schedulable.
I dare say there are ways around not having CREATE_SUSPENDED, but it certainly has its uses.
There are some example of uses in 'Windows via C/C++' (Richter/Nasarre) if you want lots of detail!
There is an implicit race condition in CreateThread: you cannot obtain the thread ID until after the thread started running. It is entirely unpredictable when the call returns, for all you know the thread might have already completed. If the thread causes any interaction in the rest of that process that requires the TID then you've got a problem.
It is not an unsolvable problem if the API doesn't support starting the thread suspended, simply have the thread block on a mutex right away and release that mutex after the CreateThread call returns.
However, there's another use for CREATE_SUSPENDED in the Windows API that is very difficult to deal with if API support is lacking. The CreateProcess() call also accepts this flag, it suspends the startup thread of the process. The mechanism is identical, the process gets loaded and you'll get a PID but no code runs until you release the startup thread. That's very useful, I've used this feature to setup a process guard that detects process failure and creates a minidump. The CREATE_SUSPEND flag allowed me to detect and deal with initialization failures, normally very hard to troubleshoot.
You might want to start a thread with some other (usually lower) priority or with a specific affinity mask. If you spawn it as usual it can run with undesired priority/affinity for some time. So you start it suspended, change the parameters you want, then resume the thread.
The threads we use are able to exchange messages, and we have arbitrarily configurable priority-inherited message queues (described in the config file) that connect those threads. Until every queue has been constructed and connected to every thread, we cannot allow the threads to execute, since they will start sending messages off to nowhere and expect responses. Until every thread was constructed, we cannot construct the queues since they need to attach to something. So, no thread can be allowed to do work until the very last one was configured. We use boost.threads, and the first thing they do is wait on a boost::barrier.
I stumbled with a similar problem once upon I time. The reasons for suspended initial state are treated in other answer.
My solution with pthread was to use a mutex and cond_wait, but I don't know if it is a good solution and if can cover all the possible needs. I don't know, moreover, if the thread can be considered suspended (at the time, I considered "blocked" in the manual as a synonim, but likely it is not so)