How to Avoid Deadlock Between Modules
In some situations, it may be necessary for you to control
the synchronization of modules using facilities other than a thread-serialized
module or a serialized procedure. For example, consider the situation shown
in Figure 1, where two threads are each running a procedure
in different thread-serialized modules: procedure PROC1 in module MOD1 and
procedure PROC3 in module MOD2. MOD1 also has procedure PROC2 and MOD2 also
has procedure PROC4. Even though there is no actual recursive calling; if
PROC1 calls PROC4, it will wait for MOD2 to unlock; and if PROC3 calls PROC2,
it will wait for MOD1 to unlock. The procedures will not be able to complete
their calls, since each module will be locked by the thread in the other module.
This type of problem can occur even with serialization of calls to a module,
and is referred to as deadlock.
Figure 1. Deadlock Example in a THREAD(*SERIALIZE) module

This example shows how deadlock can occur if you try to access more than one procedure in the same thread-serialized module at the same time.
To avoid the problem in the above example and ensure thread
safe applications, you can control the synchronization of modules using the
techniques described in Using thread-related APIs. Any callers of PROC1
or PROC3 for each thread should do the following:
- Restrict access to the modules for all threads except the current thread, always in the same order (MOD1 then MOD2)
- In the current thread, call the required procedure (PROC1 or PROC3)
- Relinquish access to the modules for all threads in the reverse order of step 1 (MOD2 then MOD1).
One thread would be successful in restricting access to MOD1. Since all users of MOD1 and MOD2 use the protocol of restricting access to MOD1 and MOD2 in that order, no other thread can call procedures in MOD1 or MOD2 while the first thread has restricted access to the modules. In this situation you have access to more than one procedure in the same module at the same time, but since it is only available to the current thread, it is thread safe.
This method should also be used to synchronize access to shared storage.