HR>> Most (but not all) OS/2 APIs calls DosExitCritSec() under cover.
HR>> So you should not use any API (system, runtime, library) unless
HR>> you know that this function would never call a system API.
JdBP> Actually, that's not quite the right explanation.
JdBP> The reason not to call APIs is as explained in the CP Guide and
JdBP> Reference. (The CPREF talks about "dynamic link library
JdBP> calls", but it is really talking about APIs in any arbitrary
JdBP> libraries. Even statically linked libraries can be a problem
JdBP> if they use semaphores internally.) If a second thread had
JdBP> been already in that API when it was blocked by the first
JdBP> thread entering the criticical section, then that second thread
JdBP> will possibly be holding a mutex semaphore that restricts
JdBP> access to the internals of that API. If the first thread then
JdBP> attempts to use that API, it will block on the mutex whilst
JdBP> holding the critical section, and the two threads will be
JdBP> deadlocked.
In redbooks is declared that most (but not all) OS/2 API will enter
DosExitCritSec() before entering ring 0. So any API to a runtime library my
call it.
This is since OS/2 1.3. In OS/2 1.2 and earlier there was NO unlck and a
restriction not to use more than 10 assembler statements.
I'd had in OS/2 2.0 exactly that problem: In production environment a
multithreaded process crashed mostly (not always) in case of exit. The
DosWaitThread() API doesn't exist. Depending on memory amount the program
crashed or even crashed NOT.
To fix that bug I had to terminate other threads clean and before thread 1
itself terminates. For that I foun DosEnterCritSec() as friend of me. On
thread exit:
DosEnterCritSec();
death = 1; /* signal to thread 1 thread is deed */
_endthread(); /* clean up C environment and die */
/* thred was started with _beginthread */
in thread 1
while (!death) DosSleep(0); /* give up timeslice */
With DosWaitThread() this would be much simpler. A simple DosWaitThread() for
all threads in thread 1 would do the whole work.
DosEnterCritSec()/DosExitCritSec() pair is also a probate way to block other
threads for shorthand manipulation of process internal but thread shared
variables. It would save the overhead of semaphore handling. But it's always
unsuitable for longer code sequences (with/without any API).
--- Sqed/32 1.14/development
102
* Origin: Schont die Umwelt: Vermeidet DOSen (2:2476/493)
|