Home Random Page


CATEGORIES:

BiologyChemistryConstructionCultureEcologyEconomyElectronicsFinanceGeographyHistoryInformaticsLawMathematicsMechanicsMedicineOtherPedagogyPhilosophyPhysicsPolicyPsychologySociologySportTourism






Best Practices for Synchronization

Consider a DLL that creates worker threads as part of its initialization. Upon DLL cleanup, it is necessary to synchronize with all the worker threads to ensure that the data structures are in a consistent state and then terminate the worker threads. Today, there is no straightforward way to completely solve the problem of cleanly synchronizing and shutting down DLLs in a multithreaded environment. This section describes the current best practices for thread synchronizing during DLL shutdown.

Thread Synchronization in DllMain during Process Exit

· By the time DllMain is called at process exit, all the process’s threads have been forcibly cleaned up and there is a chance that the address space is inconsistent. Synchronization is not required in this case. In other words, the ideal DLL_PROCESS_DETACH handler is empty.

· Windows Vista ensures that core data structures (environment variables, current directory, process heap, and so on) are in a consistent state. However, other data structures can be corrupted, so cleaning memory is not safe.

· Persistent state that needs to be saved must be flushed to permanent storage.

 

Thread Synchronization in DllMain for DLL_THREAD_DETACH during DLL Unload

· When the DLL is unloaded, the address space is not thrown away. Therefore, the DLL is expected to perform a clean shutdown. This includes thread synchronization, open handles, persistent state, and allocated resources.

· Thread synchronization is tricky because waiting on threads to exit in DllMain can cause a deadlock. For example, DLL A holds the loader lock. It signals thread T to exit and waits for the thread to exit. Thread T exits and the loader tries to acquire the loader lock to call into DLL A’s DllMain with DLL_THREAD_DETACH. This causes a deadlock. To minimize the risk of a deadlock:

· DLL A gets a DLL_THREAD_DETACH message in its DllMain and sets an event for thread T, signaling it to exit.

· Thread T finishes its current task, brings itself to a consistent state, signals DLL A, and waits infinitely. Note that the consistency-checking routines should follow the same restrictions as DllMain to avoid deadlocking.

· DLL A terminates T, knowing that it is in a consistent state.

 

If a DLL is unloaded after all its threads have been created, but before they begin executing, the threads may crash. If the DLL created threads in its DllMain as part of its initialization, some threads may not have finished initialization and their DLL_THREAD_ATTACH message is still waiting to be delivered to the DLL. In this situation, if the DLL is unloaded, it will begin terminating threads. However, some threads may be blocked behind the loader lock. Their DLL_THREAD_ATTACH messages are processed after the DLL has been unmapped, causing the process to crash.

Recommendations

The following are recommended guidelines:

· Use Application Verifier to catch the most common errors in DllMain.

· If using a private lock inside DllMain, define a locking hierarchy and use it consistently. The loader lock must be at the bottom of this hierarchy.



· Verify that no calls depend on another DLL that may not have been fully loaded yet.

· Perform simple initializations statically at compile time, rather than in DllMain.

· Defer any calls in DllMain that can wait until later.

· Defer initialization tasks that can wait until later. Certain error conditions must be detected early so that the application can handle errors gracefully. However, there are tradeoffs between this early detection and the loss of robustness that can result from it. Deferring initialization is often best.

References


Date: 2016-03-03; view: 750


<== previous page | next page ==>
Deadlocks Caused by Lock Order Inversion | THE PROPERTIES OF CONCRETE
doclecture.net - lectures - 2014-2024 year. Copyright infringement or personal data (0.007 sec.)