Hidden masters

Unlike other surrogates, a hidden master surrogate doesn't modify the master object. Instead, it creates and modifies a new copy of the master (copy on write semantics); the master's existence is transparent to the client. A Taligent example of a hidden master surrogate is TGArea, which has the hidden master TAreaGeometryHandle.

A hidden master surrogate's semantics are not shared, although sharing is used behind the scenes to avoid overhead.

Use hidden masters to lazy evaluate expensive operations. Clients often copy an area and then modify the copy (rather than the original). However, area-modifying operations frequently need to make a copy of that copy while performing their operations. By using surrogates, you can avoid copying the copy. Instead, the modifying operation creates and modifies another surrogate. It then processes the master objects of both surrogates, and installs the operation result as the master object of the target surrogate.

NOTE This technique results in a significant reduction of work and you should use it where expensive operations can be delayed or eliminated. Several of the books in the Bibliography discuss this technique.

Be careful using this kind of surrogate in a multithread situation. A caller might make a copy of a surrogate for another thread (not knowing there is a hidden master), and expect that thread to alter its (supposedly) private copy without synchronizing. Because the original surrogate and the copy both point at the same data, there is a potential for a race condition. This problem can be avoided by following these two rules:

Use MReferenceCounted to keep the reference count; it's multithread safe.

Once you create a master object, it must be immutable (you never change it once it is created). There is one exception: for operations that modify the object, you can modify the master directly when the reference count is one. This is because only one caller has the surrogate, and the reference count cannot change during the call because the sole surrogate is busy with the modifying call. This is not true, however, if another thread has an alias to the surrogate (pointer or reference); but this would be an unsafe situation anyway because if a second thread tries to read a surrogate while the first thread modifies it, you have a race condition. Do not share the surrogate; this technique is safe only when you give each thread its own surrogate.

[Contents] [Previous] [Next]
Click the icon to mail questions or corrections about this material to Taligent personnel.
Copyright©1995 Taligent,Inc. All rights reserved.

Generated with WebMaker