|
|
1.1 ! root 1: % run this through LaTeX with the appropriate wrapper ! 2: ! 3: \chapter {Boilerplate for Responders}\label{cook:responder} ! 4: Let's consider how to build a responder which is also a performer. ! 5: In Chapter~\ref{cook:discipline}, ! 6: two forms for a responder were identified: ! 7: {\em dynamic}, ! 8: in which each incoming association caused the instantiation of a new responder, ! 9: and, ! 10: {\em static}, ! 11: in which each incoming association was given to a pre-existing single ! 12: instantiation of a responder. ! 13: The dynamic responder can be thought of as simply being a special case of a ! 14: static responder. ! 15: Hence, ! 16: we will describe how one builds a static responder in this chapter. ! 17: ! 18: If you have access to the source tree for this release, ! 19: the directory \file{others/lookup/} contains the boilerplate described herein. ! 20: ! 21: \section {Static Responder} ! 22: There are three areas for the boilerplate: ! 23: association management, operation response, and, error handling. ! 24: ! 25: Before proceeding however, ! 26: let's consider what an \verb"#include" file, say \verb"ryresponder.h", ! 27: might look like. ! 28: First, the standard \man librosy(3n) definitions are included, ! 29: along with the definitions for the daemon logging package. ! 30: Next, a \verb"dispatch" structure is defined ! 31: along with the boilerplate routines. ! 32: The \verb"dispatch" structure will be used by the boilerplate to invoke a ! 33: user-supplied routine that will respond to an invocation. ! 34: ! 35: \newpage ! 36: \tgrindfile{ryresponder-h} ! 37: ! 38: \subsection {Association Management} ! 39: Association management is performed precisely the way it is outlined in ! 40: Section~\ref{acs:server} of \volone/. ! 41: This is implemented by the routine \verb"ryresponder": ! 42: \begin{quote}\index{ryresponder}\small\begin{verbatim} ! 43: int ryresponder (argc, argv, myservice, dispatches, ops, ! 44: start, stop) ! 45: int argc; ! 46: char **argv, ! 47: *myservice; ! 48: struct dispatch *dispatches; ! 49: struct RyOperation *ops; ! 50: IFP start, ! 51: stop; ! 52: \end{verbatim}\end{quote} ! 53: The parameters to this procedure are: ! 54: \begin{describe} ! 55: \item[\verb"argc"/\verb"argv":] the argument vector (and its length) ! 56: that the program was invoked with; ! 57: ! 58: \item[\verb"myservice":] the non-host portion of the application-entity ! 59: information; ! 60: ! 61: \item[\verb"dispatches":] a pointer to a \verb"dispatch" table; ! 62: ! 63: \item[\verb"ops":] a pointer to a \verb"RyOperation" table; ! 64: ! 65: \item[\verb"start":] the address of a routine to decide if incoming ! 66: associations should be accepted ! 67: (use \verb"NULLIFP" if associations should always be accepted); ! 68: and, ! 69: ! 70: \item[\verb"stop":] the address of a routine to note that an association ! 71: requests termination or has been terminated ! 72: (use \verb"NULLIFP" if associations termination is unremarkable). ! 73: \end{describe} ! 74: The function of this routine is straight-forward though tedious. ! 75: First, \verb"myname" is initialized to the name that the program was invoked ! 76: with. ! 77: Next, a debug flag is possibly set and the daemon logging package is ! 78: initialized, ! 79: and the responder's application-entity information is computed. ! 80: Finally, ! 81: each operation is registered with the \verb"RyDispatch" routine, ! 82: and the \verb"start" and \verb"stop" routines are remembered. ! 83: ! 84: The routine \verb"isodeserver" is then called to manage any associations. ! 85: As a result, ! 86: the \verb"ros_init" routine will be informed of new associations, ! 87: the \verb"ros_work" routine will be informed of network activity, ! 88: and the \verb"ros_lose" routine will be advised if network listening fails. ! 89: ! 90: The \verb"ros_init" routine is also straight-forward. ! 91: First, \verb"AcInit" is called to recapture the ACSE-state, ! 92: then the user-defined association acceptance routine is called (if any). ! 93: This routine should return either \verb"ACS_ACCEPT" if the association is to ! 94: be accepted, ! 95: or either ! 96: \begin{quote}\tt ! 97: ACS\_TRANSIENT, ACS\_PERMANENT,\\ ! 98: \end{quote} ! 99: otherwise ! 100: (these latter two codes are discussed in Table~\ref{AcSAPreasons} on ! 101: page~\pageref{AcSAPreasons} of \volone/). ! 102: The routine \verb"AcAssocResponse" is then called to deal with the incoming ! 103: association. ! 104: The arguments are strictly boilerplate: ! 105: they will work unaltered for most applications. ! 106: If the association was accepted, ! 107: then the routine \verb"RoSetService" is used to tell the remote operations ! 108: library to use the presentation service as the underlying service. ! 109: ! 110: The routine \verb"ros_work" is called when activity occurs on an association, ! 111: and is somewhat complex. ! 112: The routine sets a global return vector using \man setjmp (3) ! 113: and then calls \verb"RyWait" to poll for the next operation-related event. ! 114: This usually results in one of the operations registered earlier being ! 115: dispatched immediately, ! 116: and then \verb"RyWait" will return \verb"NOTOK" ! 117: with an error condition of \verb"ROS_TIMER" indicating that there is no ! 118: more network activity pending. ! 119: Otherwise, the routine \verb"ros_indication" is called to handle ! 120: extraordinary conditions on the association. ! 121: If some error occurred during the handling of an invocation, ! 122: use of the routine \verb"ros_adios" will cause control to return to the ! 123: \verb"setjmp" call. ! 124: In this case, ! 125: several things happen. ! 126: First, ! 127: the user-defined association termination routine routine is called (if any). ! 128: This routine should note that the association is now abruptly terminated. ! 129: Next, ! 130: the \verb"AcUAbortRequest" routine is called to make sure that the association ! 131: is (ungracefully) released. ! 132: Following this, ! 133: the \verb"RyLose" routine is called to expunge any information regarding ! 134: queued operations from the run-time environment. ! 135: Finally, \verb"NOTOK" is returned to \verb"isodeserver", ! 136: which causes the association to be removed from the list of current ! 137: associations. ! 138: ! 139: The \verb"ros_indication" routine is used to handle uncommon events for an ! 140: association: user-rejections, provider-rejections, and association termination. ! 141: In all three cases, ! 142: the event is logged. ! 143: In the case of the initiator requesting that the association be terminated, ! 144: several things happen. ! 145: First, ! 146: the user-defined association termination routine is called (if any). ! 147: This routine should return either \verb"ACS_ACCEPT" if the association is to ! 148: be released, ! 149: or \verb"ACS_REJECT" if the termination is to be refused. ! 150: The routine \verb"AcRelResponse" is then called to deal with the request to ! 151: terminate the association. ! 152: If the termination was accepted, ! 153: then control returns to the \verb"setjmp" call in \verb"ros_work", ! 154: which finalizes things. ! 155: ! 156: The \verb"ros_lose" routine is simple: ! 157: the error condition is logged. ! 158: ! 159: \tgrindfile{ryresp-assoc} ! 160: \newpage ! 161: ! 162: \subsection {Operation Response} ! 163: When an operation is invoked, ! 164: its dispatch routine is called from the routine \verb"RyWait" ! 165: as described in Section~\ref{librosy:register} on ! 166: Page~\pageref{librosy:register}. ! 167: The boilerplate for a dispatch routine is fairly uniform. ! 168: A check is made to see if the invocation is linked to a previous invocation, ! 169: and the invocation is logged. ! 170: Any user-rejections are performed by the routine \verb"ureject" which is a ! 171: simple wrapper for the \verb"RyDsUReject" routine. ! 172: Next, the operation is attempted. ! 173: If it succeeded (as denoted by \verb"won"), ! 174: then a result is allocated, and initialized and returned to the initiator by ! 175: the \verb"RyDsResult" routine. ! 176: Otherwise, ! 177: an error is selected, ! 178: and ! 179: its parameter is allocated, initialized and returned to the initiator by the ! 180: \verb"error" routine which is a simple wrapper for the \verb"RyDsError" ! 181: routine. ! 182: Finally, ! 183: the argument is freed and the handler returns. ! 184: ! 185: \tgrindfile{ryresp-invoke} ! 186: \newpage ! 187: ! 188: \subsection {Error Handling} ! 189: These routines for the most part are all straight-forward. ! 190: \begin{describe} ! 191: \item[\verb"ros\_adios":] used to report a ROS error and terminate; ! 192: ! 193: \item[\verb"ros\_advise":] used to report a ROS error; ! 194: ! 195: \item[\verb"acs\_advise":] used to report an ACS error; ! 196: ! 197: \item[\verb"adios":] used to report an error and terminate; ! 198: ! 199: \item[\verb"advise":] used to report an error; ! 200: and, ! 201: ! 202: \end{describe} ! 203: \pgm{pepy} generate errors are normally caught by the routine ! 204: \verb"PY_advise"\index{PY\_advise} by using the \verb"-a" switch to ! 205: \pgm{pepy}. The \man librosy(3n) routines use these to build up error ! 206: message when \pgm{pepy} routines fail. ! 207: ! 208: \tgrindfile{ryresp-error} ! 209: \newpage ! 210: ! 211: \subsection {An Example} ! 212: An example of a responder written using this boilerplate is ! 213: shown in Section~\ref{passwd:responder} on page~\pageref{passwd:responder}.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.