|
Mac OS 9
|
#include <Multiprocessing.h>
You must properly check the availability of MP services before calling them!
Checking for the availability of the MP API is rather ugly. This is a historical problem, caused by the original implementation letting itself get prepared when it really wasn't usable and complicated by some important clients then depending on weak linking to "work". (And further complicated by CFM not supporting "deferred" imports, which is how many programmers think weak imports work.)
The end result is that the MP API library may get prepared by CFM but be totally unusable. This means that if you import from the MP API library, you cannot simply check for a resolved import to decide if MP services are available. Worse, if you explicitly prepare the MP API library you cannot assume that a noErr result from GetSharedLibrary means that MP services are available.
If you import from the MP API library you MUST use the MPLibraryIsLoaded macro (or equivalent code in languages other than C) to tell if the MP API services are available. It is not sufficient to simply check that an imported symbol is resolved as is commonly done for other libraries. The macro expands to the expression: (((UInt32)_MPIsFullyInitialized != (UInt32)kUnresolvedCFragSymbolAddress ) && (_MPIsFullyInitialized ()))
This checks if the imported symbol _MPIsFullyInitialized is resolved and if resolved calls it. Both parts must succeed for the MP API services to be available.
If you explicitly prepare the MP API library you MUST use code similar to the following example to tell if the MP API services are available. It is not sufficient to depend on just a noErr result from GetSharedLibrary.
OSErr err;
Boolean mpIsAvailable = false;
CFragConnectionID connID = kInvalidID;
MPIsFullyInitializedProc mpIsFullyInitialized = NULL;
err = GetSharedLibrary("\pMPLibrary", kCompiledCFragArch, kReferenceCFrag, &connID, NULL, NULL);
if (err == noErr) {
err = FindSymbol(connID, "\p_MPIsFullyInitialized", (Ptr *) &mpIsFullyInitialized, NULL);
}
if (err == noErr) {
mpIsAvailable = (*mpIsFullyInitialized)();
}