  PROCEDURE [INLINE] dfp$determine_action_for_server
    (    p_cpu_queue_entry: ^dft$cpu_queue_entry;
         p_driver_queue_entry: ^dft$driver_queue_entry;
     VAR action_for_server: dft$action_for_server);

{  This procedure enforces one aspect of File Server protocol. That aspect is
{  to determine what action is to be performed by the server side task who's
{  queue entry has been processed by the driver, and to update the queue
{  entry's transaction_count and retransmission_count fields as per protocol.
{
{  The driver, after completing I/O for a server to client queue type, will
{  determine if the server task must be activated to perform some action.
{  The driver will signal that the server task must be activated when it has
{  completed one of the following I/O operations for a server to client queue
{  entry -
{    a. received a command buffer (stored in queue entry's receive_buffer).
{    b. processed a send_ready_for_data command (receive to page data buffers).
{    c. processed a send_data command (sent from page data buffers).
{  The signal from the driver is in the form of a one word pp response, which
{  is detected by procedure iop$process_io_completions and processed by
{  dfp$process_server_response. The one word pp response consists of a queue
{  index and queue entry index which together identify the server side queue
{  entry in question.
{
{  By comparing the transaction_count and retransmission_count in the cpu queue
{  entry with those in the last received command header (in receive buffer) and
{  by testing the driver queue entry flag driver_error_alert, this procedure
{  determines what processing the server side task is expected to perform.
{
{      DFP$DETERMINE_ACTION_FOR_SERVER (P_CPU_QUEUE_ENTRY,
{           P_DRIVER_QUEUE_ENTRY,  ACTION_FOR_SERVER)
{
{  P_CPU_QUEUE_ENTRY: (input) Pointer to the cpu queue entry.
{
{  P_DRIVER_QUEUE_ENTRY: (input) Pointer to the driver queue entry.
{
{  ACTION_FOR_SERVER: (output) This parameter is an ordinal which indicates
{       the type of processing to be performed for the queue entry.
{     DFC$NEW_REQUEST - Begin new transaction, server must process new request.
{
{     DFC$RETRANSMITTED_REQUEST - Same request as in previous transaction,
{          Server must send the request response to client again.
{
{     DFC$COMPLETE_REQUEST - The driver has completed input or output of page
{          data. Server must take appropriate action on wired page buffers.
{
{     DFC$COMPLETE_REQUEST_ON_ERROR - The driver was unable to perform the
{          the command specified by the server and the command involved page
{          data. Server must take appropriate action on wired page buffers.
{
{     DFC$TRANSACTION_OUT_OF_SEQUENCE - The transaction_count in the received
{          buffer_header is less than or more than one greater than that in
{          the cpu queue entry.


    VAR
      p_buffer_header: ^dft$buffer_header;

    { Determine reason for pp response to server side.
    IF p_driver_queue_entry^.flags.driver_error_alert THEN
      { The driver encounted an error while reading page data (processing
      { send_ready_for_data),or while writing the server's response and page
      { data (send_command and send_data).
      { Server must complete processing of request.
      { Errors detected when page data is not involved are processed in
      { dfp$process_server_response.
      action_for_server := dfc$complete_request_on_error;
    ELSE
      RESET p_cpu_queue_entry^.p_receive_buffer;
      NEXT p_buffer_header IN p_cpu_queue_entry^.p_receive_buffer;

      IF p_cpu_queue_entry^.transaction_count =
            p_buffer_header^.transaction_count THEN
        { This is not a new transaction from the client.
        IF p_cpu_queue_entry^.retransmission_count =
              p_buffer_header^.retransmission_count THEN
          { The driver's response is to signal server to perform request
          { completion processing.
          { The driver has input page data (processed send_ready_for_data), or
          { has output response and page data (processed send_command and
          { send_data).
          { Server must complete processing of request.
          action_for_server := dfc$complete_request;
        ELSE
          { This is the same request received and processed earlier. The client
          { has retransmitted the request because it did not receive the
          { server's response.
          { The retransmission_count in the buffer_header is copied to cpu
          { queue.
          action_for_server := dfc$retransmitted_request;
          p_cpu_queue_entry^.retransmission_count :=
                p_buffer_header^.retransmission_count;
        IFEND;

      ELSEIF p_cpu_queue_entry^.transaction_count + 1 =
            p_buffer_header^.transaction_count THEN
        { The transaction_count received for this request is one greater than
        { that of the previous request.
        { This condition indicates the start of a new transaction.
        { Server must execute new request from client.
        { The cpu queue entry transaction_count is incremented by one.
        { The retransmission_count in the buffer_header is copied to cpu queue.
        action_for_server := dfc$new_request;
        p_cpu_queue_entry^.retransmission_count :=
              p_buffer_header^.retransmission_count;
        p_cpu_queue_entry^.transaction_count :=
              p_buffer_header^.transaction_count;
      ELSE
        { The transaction_count received for this request is less than or
        { greater than that expected. This is an abnormal condition.
        action_for_server := dfc$transaction_out_of_sequence;
      IFEND;
    IFEND;

  PROCEND dfp$determine_action_for_server;

?? PUSH (LISTEXT := ON) ??
*copyc dfd$request_package
*copyc dft$action_for_server
*copyc dft$cpu_queue
*copyc dfd$driver_queue_types
?? POP ??




