1

I'm not sure how clear the title of the question is. Here's what I'm trying to do:

I have a process, which uses DLL libraries as plugins. Those libraries use functions, synchronized with a critical section object . I want all DLL functions to be synchronized with the same critical section object. I thought about the following: the first DLL will initialize a critical section object, and other DLLs will use it too, instead of initializing a new one. But how can I get the pointer to the critical section object of the first DLL?

One solution I thought of is using a Named Shared Memory, and placing the pointer to the critical section object there. It will work, but it feels like shooting a fly with a bazooka. Is there a simpler and more idiomatic way to create a named object with a retrievable pointer?

5
  • Export a function from the DLL that owns the lock that return a pointer to that lock. Or export functions from the DLL that acquire and release the lock. Commented Oct 17, 2014 at 11:12
  • 1
    Isn't this just what Named Mutexes (msdn.microsoft.com/en-gb/library/windows/desktop/…) are for? Commented Oct 17, 2014 at 13:35
  • @AAT a named Mutex cannot hold a pointer-sized variable, can it? Apart from that, it's pretty close, yes. Commented Oct 17, 2014 at 13:47
  • I wasn't trying to give you a way to pass a pointer... I thought your problem is synchronisation between DLLs, and mutexes are a good way to do that. Not quite as fast as a CriticalSection, I grant you. Commented Oct 17, 2014 at 14:14
  • The advantange of using a named mutex is that you do not have to pass the mutex handle across DLL boundaries. Each DLL can individually call (Create/Open)Mutex() specifying the same name, and they will each get their own local handle to the same mutex object in the kernel, and thus can sync with each other. You can't do that with a critical section, you have to pass a pointer around instead. Commented Oct 17, 2014 at 16:33

2 Answers 2

3

One Dll should be responsible for the Management of the critical section object. This dll may also export functions to work with it. This dll should create the object during its load and provide (exports) a function that returns the objects pointer.

Sign up to request clarification or add additional context in comments.

4 Comments

This is the correct approach. Solve the problem with proper program design and encapsulation, not with some ad hoc global resource sharing. The need to share a critical section between different DLL:s already suggests that the program design is quite muddy.
I'm afraid that it's not going to work for me. I don't want to get into details, but the situation is that I have no control over the exe, and the DLLs are being injected. Exporting from the DLLs might work, but how will they find one another? I can e.g. keep the instance of the first DLL somewhere, but where? I'm back to the original problem - having a global named variable.
Your personal design problems are just that. Personal. Not detailed in the question you asked. And in any case, if you can agree on a common name for a mutex, you can solve your problem properly. Very easily in fact.
Each DLL can call LoadLibrary to get a handle to the particular DLL responsible for the critical section object. The first one to do so will actually load the library (or you can preload it by injection) and the others will just get a handle to it. You can then call GetProcAddress to get the address of a function that returns a pointer to the critical section. (NB: you mustn't call LoadLibrary inside DllMain, so you'll need to wait until your main library function(s) have control.)
2

Use a named Mutex. You do not have to pass it around across DLL boundaries. Each DLL can individually call CreateMutex(), specifying the same name, and they will each get their own local HANDLE to the same mutex object in the kernel, thus allowing syncing with each other. Just make sure each DLL calls CloseHandle() when it is done using the mutex. The best place to do both is in each DLL's entry point function, eg:

HANDLE hMutex = NULL;

BOOL WINAPI DllEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
    switch( fdwReason ) 
    { 
        case DLL_PROCESS_ATTACH:
            hMutex = CreateMutex(NULL, FALSE, TEXT("MySharedMutex"));
            if (hMutex == NULL) return FALSE;
            break;

        case DLL_PROCESS_DETACH:
            if (hMutex != NULL)
            {
                CloseHandle(hMutex);
                hMutex = NULL;
            } 
            break;
    }

    return TRUE;
}

8 Comments

This will work, but I hoped to avoid the performance penalty of a Mutex, as I don't need interprocess synchronization. I'll accept this answer if no other alternatives will show up.
Unless the DLLs talk to each other directly, the only option is to use a named kernel object that they can share. Whether that is a named mutex or a named shared memory block, the choice is yours.
Well, by using a named shared memory block, I could keep a pointer to a shared critical section object. This will have better performance, but more complicated implementation, especially WRT (un)initialization and thread safety. For now, I decided to stick to a Mutex object, as you've suggested.
Rather than allocating a CS and putting a pointer to it inside the shared memory, the shared memory can be the CS itself. Just allocate the shared memory to the full size of a CRITICAL_SECTION and initialize it the first time it is allocated. But yes, there is an issue about when the CS can be uninitialized, or making sure nobody uses it before it is initialized. I would stick with a mutex. It is simpler to use, and the performance difference is comparable.
I'm not sure, but I thought that shared memory could be slower, as it's synchronized between processes. As for performance of a Mutex vs CS, apparently a Critical Section is 25 times faster.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.