Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
MoreOpenTransport/OTMP.h
/* |
File: OTMP.h |
Contains: MP task friendly OT library. |
Written by: Quinn |
Copyright: Copyright © 2000 by Apple Computer, Inc., All Rights Reserved. |
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. |
("Apple") in consideration of your agreement to the following terms, and your |
use, installation, modification or redistribution of this Apple software |
constitutes acceptance of these terms. If you do not agree with these terms, |
please do not use, install, modify or redistribute this Apple software. |
In consideration of your agreement to abide by the following terms, and subject |
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs |
copyrights in this original Apple software (the "Apple Software"), to use, |
reproduce, modify and redistribute the Apple Software, with or without |
modifications, in source and/or binary forms; provided that if you redistribute |
the Apple Software in its entirety and without modifications, you must retain |
this notice and the following text and disclaimers in all such redistributions of |
the Apple Software. Neither the name, trademarks, service marks or logos of |
Apple Computer, Inc. may be used to endorse or promote products derived from the |
Apple Software without specific prior written permission from Apple. Except as |
expressly stated in this notice, no other rights or licenses, express or implied, |
are granted by Apple herein, including but not limited to any patent rights that |
may be infringed by your derivative works or by other works in which the Apple |
Software may be incorporated. |
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO |
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED |
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN |
COMBINATION WITH YOUR PRODUCTS. |
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR |
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION |
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT |
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN |
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
Change History (most recent first): |
<7> 21/9/01 Quinn Changes for CWPro7 Mach-O build. |
<6> 8/2/01 Quinn [2619462] The fix for the MP bug is in CarbonLib 1.2.5. |
<5> 8/2/01 Quinn Add missing word to comment. |
<4> 8/2/01 Quinn Add OTMPGetMessage and OTMPPutMessage. |
<3> 5/12/00 Quinn Looks like the bug fix won't make it into CarbonLib 1.2. |
<2> 10/11/00 Quinn Added OTMPGetCanRunStatus. |
<1> 7/11/00 Quinn First checked in. |
*/ |
#pragma once |
///////////////////////////////////////////////////////////////// |
// MoreIsBetter Setup |
#include "MoreSetup.h" |
// Mac OS Interfaces |
#if ! MORE_FRAMEWORK_INCLUDES |
#include <OpenTransport.h> |
#endif |
///////////////////////////////////////////////////////////////// |
#ifdef __cplusplus |
extern "C" { |
#endif |
typedef UInt32 OTMPCanRunStatus; |
enum { |
kOTMPCanRun = 0, |
kOTMPSystemTooOld = 1, |
kOTMPBadCarbon = 2 |
}; |
extern pascal OTMPCanRunStatus OTMPGetCanRunStatus(void); |
// This routine returns a value of type OTMPCanRunStatus |
// that indicates whether OTMP can run and, if not, why |
// it can't. Note that OTMP refuses to run if a CarbonLib |
// older than version 1.2.5 is installed. This is because a |
// bug in older versions of CarbonLib [2563553] prevents |
// MP tasks from using DTInstall (even those linked against |
// InterfaceLib). |
// This module logs its activities to MoreMPLog. You can control which |
// bit in the log mask it uses (see "MoreMPLog.h" for a discussion of the |
// log mask) by changing this constant. |
enum { |
kOTMPWaitRecordLogID = 1, |
kOTMPNotificationLogID = 2, |
kOTMPStdActionLogID = 3, |
kOTMPAPILogID = 4, |
kOTMPRetriesLogID = 5 |
}; |
// OTMPProviderRef is reference to a private structure defined inside this module. |
typedef struct OTMPProvider OTMPProvider; |
typedef OTMPProvider *OTMPProviderRef; |
// Like OT itself, OTMP supports a limited degree of polymorphism. Specifically, |
// OTMPEndpointRef is a subclass of OTMPProviderRef. This structure is hard to |
// represent in C, so we just equate the two types. |
typedef OTMPProviderRef OTMPEndpointRef; |
extern pascal OSStatus InitOpenTransportMPInContext( |
OTInitializationFlags flags, |
OTClientContextPtr * clientContext); |
// You must call this routine at system task time. |
extern pascal void CloseOpenTransportMPInContext(OTClientContextPtr clientContext); |
// You must call this routine at system task time. |
extern pascal OSStatus OTMPPrepareThisTask(void); |
// You must call this from each MP task that is to call |
// this library. You must not call it for the main thread |
// (or any other cooperative thread). |
extern pascal void OTMPUnprepareThisTask(void); |
// You must call this from each MP task that you have |
// prepared using OTMPPrepareThisTask before the task quits. |
// This routine does not require that the preparation have |
// been successful (or even to have occured at all), so you |
// can safely call it at the end of any MP task that might |
// have called OTMPPrepareThisTask. |
extern pascal OTMPEndpointRef |
OTMPOpenEndpointQInContext (const char * cfig, |
OTOpenFlags oflag, |
TEndpointInfo * info, |
OSStatus * errPtr, |
OTClientContextPtr clientContext); |
// This "quick" version of OTOpenEndpoint uses a configuration |
// string rather than a OTConfigurationRef. I haven't |
// yet implemented the real routine because I'm still trying |
// to decide how to handle OTCreateConfiguration. The obvious |
// approach would require two round trips from MP to blue, which |
// is unnecessarily slow. The main advantage of using |
// a configuration is that you can create endpoints quickly by |
// creating a single configuration and cloning it each time you |
// create an endpoint. This speeds up endpoint creation a little. |
// However, if your application is creating lots of endpoints you |
// will get a much better speed increase by maintaining a cache of |
// created endpoints. |
// |
// Regardless, this routine is just fine for 99% of clients. |
extern pascal OSStatus |
OTMPCloseProvider (OTMPProviderRef ref); |
extern pascal SInt32 |
OTMPIoctl (OTMPProviderRef ref, |
UInt32 cmd, |
void * data); |
extern pascal OSStatus |
OTMPCancelSynchronousCalls (OTMPProviderRef ref, |
OSStatus errParam); |
extern pascal OSStatus |
OTMPGetEndpointInfo (OTMPEndpointRef ref, |
TEndpointInfo * info); |
extern pascal OTResult |
OTMPGetEndpointState (OTMPEndpointRef ref); |
extern pascal OTResult |
OTMPLook (OTMPEndpointRef ref); |
extern pascal OTResult |
OTMPCountDataBytes (OTMPEndpointRef ref, |
OTByteCount * countPtr); |
extern pascal OSStatus |
OTMPGetProtAddress (OTMPEndpointRef ref, |
TBind * boundAddr, /* can be NULL */ |
TBind * peerAddr) /* can be NULL */; |
extern pascal OSStatus |
OTMPResolveAddress (OTMPEndpointRef ref, |
TBind * reqAddr, |
TBind * retAddr, |
OTTimeout timeOut); |
extern pascal OSStatus |
OTMPBind (OTMPEndpointRef ref, |
TBind * reqAddr, /* can be NULL */ |
TBind * retAddr) /* can be NULL */; |
extern pascal OSStatus |
OTMPUnbind (OTMPEndpointRef ref); |
extern pascal OSStatus |
OTMPConnect (OTMPEndpointRef ref, |
TCall * sndCall, |
TCall * rcvCall) /* can be NULL */; |
extern pascal OSStatus |
OTMPListen (OTMPEndpointRef ref, |
TCall * call); |
extern pascal OSStatus |
OTMPAccept (OTMPEndpointRef listener, |
OTMPEndpointRef worker, |
TCall * call); |
// The implementation of this routine has a race condition which |
// might be exposed if the worker endpoint is active (ie there are |
// outstanding synchronous operations on the endpoint). Rather than |
// fix the problem (which would require a major rework of the |
// library's global concurrency model), I've decided to outlaw this |
// behaviour. You must call this routine only with worker endpoints |
// that are quiescent (ie have no outstanding synchronous operations). |
// |
// See the comments in the implementation for details. |
extern pascal OSStatus |
OTMPSndDisconnect (OTMPEndpointRef ref, |
TCall * call) /* can be NULL */; |
extern pascal OSStatus |
OTMPRcvDisconnect (OTMPEndpointRef ref, |
TDiscon * discon) /* can be NULL */; |
extern pascal OSStatus |
OTMPSndOrderlyDisconnect (OTMPEndpointRef ref); |
extern pascal OSStatus |
OTMPRcvOrderlyDisconnect (OTMPEndpointRef ref); |
extern pascal OSStatus |
OTMPOptionManagement (OTMPEndpointRef ref, |
TOptMgmt * req, |
TOptMgmt * ret); |
extern pascal OTResult |
OTMPRcv (OTMPEndpointRef ref, |
void * buf, |
OTByteCount nbytes, |
OTFlags * flags); |
extern pascal OTResult |
OTMPSnd (OTMPEndpointRef ref, |
void * buf, |
OTByteCount nbytes, |
OTFlags flags); |
extern pascal OSStatus |
OTMPSndUData (OTMPEndpointRef ref, |
TUnitData * udata); |
extern pascal OSStatus |
OTMPRcvUData (OTMPEndpointRef ref, |
TUnitData * udata, |
OTFlags * flags); |
extern pascal OSStatus |
OTMPRcvUDErr (OTMPEndpointRef ref, |
TUDErr * uderr); |
#if CALL_NOT_IN_CARBON |
// IMPORTANT: |
// These routines are a preliminary implementation and have |
// not yet been tested properly. Specifically, I have not |
// tested the flow control execution paths. |
extern pascal OTResult |
OTMPGetMessage (OTMPProviderRef ref, |
strbuf * ctlbuf, |
strbuf * databuf, |
OTFlags * flagsPtr); |
extern pascal OSStatus |
OTMPPutMessage (OTMPProviderRef ref, |
const strbuf * ctlbuf, |
const strbuf * databuf, |
OTFlags flags); |
#endif |
///////////////////////////////////////////////////////////////// |
// Cooperative Threading |
// During the bring up and debugging effort it's often useful to run |
// everything from the main thread (or from Thread Manager threads). |
// To limit OTMP's external dependencies, I allow you to install a |
// callback that OTMP calls while is waiting for async operations |
// to complete. You can use this callback to call WaitNextEvent, or |
// yield time in whatever way is appropriate for your application. |
// This is very similar to the kOTSyncIdleEvent idea, except that |
// there is only one callback for the entire library. |
// |
// IMPORTANT: You only need to install this callback if you call |
// OTMP from your application's main thread or a Thread Manager thread. |
// If you always call OTMP from preemptively scheduled MP tasks this |
// callback is unnecessary. |
typedef pascal OSStatus (*OTMPMainThreadYielder)(void); |
// OTMP calls this routine when it is waiting "sync waiting", |
// ie waiting for an asynchronous event to complete. The routine |
// should yield time in whatever way that's appropriate for your |
// application. |
// |
// If the routine returns an error, OTMP will break out of its |
// sync wait loop. You should only do this under the most dire |
// circumstances!!! It will leave the entire library in a very |
// base state. It's useful for breaking out of endless loops while |
// debugging, and not much else. For production code you should |
// cancel the synchronous call using OTMPCancelSynchronousCalls. |
extern pascal void InstallOTMPMainThreadYielder(OTMPMainThreadYielder yielder); |
// Installs, or removes if yielder is nil, the yielder callback. |
///////////////////////////////////////////////////////////////// |
// Debugging Stuff |
#if MORE_DEBUG |
// The following routines were useful for bringing up OTMP |
// and may also be useful when debugging your applications. |
extern void OTMPPrintSndRetryFreqDist(void); |
// Prints, to stdout, a frequency distribution of the |
// number of memory retries by OTMPSnd. See the |
// implementation for more details. |
extern pascal void RunOTMPAsSystemTasks(Boolean asSystemTasks); |
// If asSystemTasks is true, the module will run entirely at |
// system task time. This was very useful when debugging |
// OTMP but is of limited usefulness you OTMP clients. Call this |
// routine after initialising the library but before calling |
// any other library routines. This routine also forces all |
// Blue tasks to run at system task time (see "MoreBlueActions.h"). |
// Must be called at system task time. |
#endif |
///////////////////////////////////////////////////////////////// |
// OTMPX |
// ----- |
// These routines look at the current system version and do the right |
// thing on both traditional Mac OS (call OTMP) and Mac OS X |
// (call Mac OS X's built in OT compatibility directly). |
extern pascal OSStatus InitOpenTransportMPXInContext( |
OTInitializationFlags flags, |
OTClientContextPtr * clientContext); |
extern pascal void CloseOpenTransportMPXInContext(OTClientContextPtr clientContext); |
extern pascal OSStatus OTMPXPrepareThisTask(void); |
extern pascal void OTMPXUnprepareThisTask(void); |
extern pascal OTMPEndpointRef |
OTMPXOpenEndpointQInContext (const char * cfig, |
OTOpenFlags oflag, |
TEndpointInfo * info, |
OSStatus * errPtr, |
OTClientContextPtr clientContext); |
extern pascal OSStatus |
OTMPXCloseProvider (OTMPProviderRef ref); |
extern pascal SInt32 |
OTMPXIoctl (OTMPProviderRef ref, |
UInt32 cmd, |
void * data); |
extern pascal OSStatus |
OTMPXCancelSynchronousCalls (OTMPProviderRef ref, |
OSStatus errParam); |
extern pascal OSStatus |
OTMPXGetEndpointInfo (OTMPEndpointRef ref, |
TEndpointInfo * info); |
extern pascal OTResult |
OTMPXGetEndpointState (OTMPEndpointRef ref); |
extern pascal OTResult |
OTMPXLook (OTMPEndpointRef ref); |
extern pascal OTResult |
OTMPXCountDataBytes (OTMPEndpointRef ref, |
OTByteCount * countPtr); |
extern pascal OSStatus |
OTMPXGetProtAddress (OTMPEndpointRef ref, |
TBind * boundAddr, /* can be NULL */ |
TBind * peerAddr) /* can be NULL */; |
extern pascal OSStatus |
OTMPXResolveAddress (OTMPEndpointRef ref, |
TBind * reqAddr, |
TBind * retAddr, |
OTTimeout timeOut); |
extern pascal OSStatus |
OTMPXBind (OTMPEndpointRef ref, |
TBind * reqAddr, /* can be NULL */ |
TBind * retAddr) /* can be NULL */; |
extern pascal OSStatus |
OTMPXUnbind (OTMPEndpointRef ref); |
extern pascal OSStatus |
OTMPXConnect (OTMPEndpointRef ref, |
TCall * sndCall, |
TCall * rcvCall) /* can be NULL */; |
extern pascal OSStatus |
OTMPXListen (OTMPEndpointRef ref, |
TCall * call); |
extern pascal OSStatus |
OTMPXAccept (OTMPEndpointRef listener, |
OTMPEndpointRef worker, |
TCall * call); |
extern pascal OSStatus |
OTMPXSndDisconnect (OTMPEndpointRef ref, |
TCall * call) /* can be NULL */; |
extern pascal OSStatus |
OTMPXRcvDisconnect (OTMPEndpointRef ref, |
TDiscon * discon) /* can be NULL */; |
extern pascal OSStatus |
OTMPXSndOrderlyDisconnect (OTMPEndpointRef ref); |
extern pascal OSStatus |
OTMPXRcvOrderlyDisconnect (OTMPEndpointRef ref); |
extern pascal OSStatus |
OTMPXOptionManagement (OTMPEndpointRef ref, |
TOptMgmt * req, |
TOptMgmt * ret); |
extern pascal OTResult |
OTMPXRcv (OTMPEndpointRef ref, |
void * buf, |
OTByteCount nbytes, |
OTFlags * flags); |
extern pascal OTResult |
OTMPXSnd (OTMPEndpointRef ref, |
void * buf, |
OTByteCount nbytes, |
OTFlags flags); |
extern pascal OSStatus |
OTMPXSndUData (OTMPEndpointRef ref, |
TUnitData * udata); |
extern pascal OSStatus |
OTMPXRcvUData (OTMPEndpointRef ref, |
TUnitData * udata, |
OTFlags * flags); |
extern pascal OSStatus |
OTMPXRcvUDErr (OTMPEndpointRef ref, |
TUDErr * uderr); |
#ifdef __cplusplus |
} |
#endif |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-07-22