ID Number: Q61285
3.00 3.10
WINDOWS
Summary:
The global lock count mechanism has been changed in the Windows
version 3.x protected modes (that is, standard mode and enhanced
mode). The GlobalLock function only affects the lock count of
discardable objects and the default data segment (DGROUP); movable
objects are not affected. Thus, repeated calling of the
GlobalLock and GlobalFlags functions on a GMEM_MOVEABLE object
does not show any changes to its lock count.
More Information:
The following are reasons and explanations concerning this design
change:
1. In real mode, the GlobalLock function fixes the segment:offset
of a global memory object. It also increases the lock count, as
reported by the GlobalFlags function.
2. In protected mode, the far pointer returned by the GlobalLock
function is a selector:offset, not a segment:offset. Because the
selector value does not change, the GlobalLock function does
not actually fix the memory object in the physical address space.
Thus, the GlobalLock function in protected mode does not change
the lock count, unless the object is discardable or is a default
data segment.
In the case of a discardable object, the lock count is meaningful,
because Windows needs to know when the object can be discarded
(which is when its lock count is zero).
3. However, some applications have used the GlobalLock lock count
as a "reference count" [that is, as an indication of how many times
the GlobalLock function was called]. If the lock count for an
object goes to zero, these applications might consider the object a
candidate for being manually discarded, perhaps after copying the
data to disk.
Unfortunately, this use of the GlobalLock function as a reference
count keeper does not work in protected mode. Applications that
symmetrically pair calls to the GlobalLock function with calls to
the GlobalUnlock function do not need to know the lock count, and
therefore, are unaffected by this change in behavior.
4. How does an application keep track of reference counts now, given
that the GlobalLock approach does not work for nondiscardable
objects in protected mode? The application should really keep track
of reference counts itself, which should not be hard to do because
the application in need of this functionality will have a table of
global handles anyway.
However, if the application cannot be modified to maintain its own
reference counts, then there is a new Windows function, called
GlobalFixthat will accomplish this functionality. The
GlobalFix function performs the following functionality:
a. It fixes the object in the protected mode linear space.
b. It increments the "lock count", as returned by the
GlobalFlags function.
5. The following includes more information about the GlobalFlags
function. In real mode, it returns the GlobalLock lock count.
In protected mode, if the object is discardable, the GlobalFlags
function also returns the GlobalLock lock count. In protected
mode, if the object is nondiscardable, the GlobalFlags function
returns the GlobalFix reference count. In other words, the
GlobalFlags function always returns the lock/fix count. However,
in protected mode, the GlobalLock and GlobalUnLock functions
do not affect the count, only the GlobalFix and GlobalUnFix
functions do.
Note: In real mode, the GlobalFlags lock count actually indicates
the sum of GlobalLock's and GlobalFix'es. Therefore, if the
programmer is calling GlobalLock's and GlobalFix'es in pairs,
then the GlobalFlags lock count actually is twice the logical
reference count, if in real mode.
6. If the application needs to keep track of reference counts, and the
programmer wants Windows to do the work for them, then the
programmer must accompany every call to the GlobalLock function
with a call to the GlobalFix function. This way the programmer
will be able to depend on the validity of the GlobalFlags'
lock/reference count. However, using the GlobalFix function just
to keep track of the reference count is overkill, if that is all
the programmer wants it to do. Remember, the GlobalFix function
also fixes the object in the protected mode linear address space.
The price the programmer pays for having Windows keep track of the
reference count (by using the GlobalFix function) is the following:
a. Every time the GlobalLock or GlobalUnLock function is called,
the programmer must also call either the GlobalFix or
GlobalUnFix function.
And, much worse:
b. The programmer establishes sandbars in the linear address space.
An application should either keep track of reference counts on its
own or always pair GlobalLock calls with matching
GlobalUnlock calls; the use of the GlobalFix function should
be avoided.
Very few applications should need to fix global objects in linear
space; therefore, few applications should need to use the
GlobalFix function.
7. If the programmer needs to unconditionally unlock and free a global
memory object of any type, then code similar to the following can
be used:
/* 1. Make it discardable if necessary. */
if (GlobalFlags shows that it is nondiscardable)
GlobalRealloc (GMEM_MODIFY it to be discardable);
/* 2. Remove any lock counts that might be on it. */
while (GlobalUnlock != 0) /* keep unlocking it */
;
/* 3. Free it. */
GlobalFree()
Additional reference words: 3.00 3.10 3.x