home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / glibc-1.06 / mach / __msg_server.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-24  |  3.7 KB  |  138 lines

  1. /* 
  2.  * Mach Operating System
  3.  * Copyright (c) 1991,1990 Carnegie Mellon University
  4.  * All Rights Reserved.
  5.  * 
  6.  * Permission to use, copy, modify and distribute this software and its
  7.  * documentation is hereby granted, provided that both the copyright
  8.  * notice and this permission notice appear in all copies of the
  9.  * software, derivative works or modified versions, and any portions
  10.  * thereof, and that both notices appear in supporting documentation.
  11.  * 
  12.  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
  13.  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
  14.  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  15.  * 
  16.  * Carnegie Mellon requests users of this software to return to
  17.  * 
  18.  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
  19.  *  School of Computer Science
  20.  *  Carnegie Mellon University
  21.  *  Pittsburgh PA 15213-3890
  22.  * 
  23.  * any improvements or extensions that they make and grant Carnegie Mellon
  24.  * the rights to redistribute these changes.
  25.  */
  26. /*
  27.  * HISTORY
  28.  * $Log:    mach_msg_server.c,v $
  29.  * Revision 2.4  91/05/14  17:53:22  mrt
  30.  *     Correcting copyright
  31.  * 
  32.  * Revision 2.3  91/02/14  14:17:47  mrt
  33.  *     Added new Mach copyright
  34.  *     [91/02/13  12:44:20  mrt]
  35.  * 
  36.  * Revision 2.2  90/08/06  17:23:58  rpd
  37.  *     Created.
  38.  * 
  39.  */
  40.  
  41. #include <mach/boolean.h>
  42. #include <mach/kern_return.h>
  43. #include <mach/port.h>
  44. #include <mach/message.h>
  45. #include <mach/mig_errors.h>
  46.  
  47. #include <stdlib.h>        /* For malloc and free.  */
  48.  
  49. /*
  50.  *    Routine:    mach_msg_server
  51.  *    Purpose:
  52.  *        A simple generic server function.
  53.  */
  54.  
  55. mach_msg_return_t
  56. __mach_msg_server_timeout(demux, max_size, rcv_name, option, timeout)
  57.      boolean_t (*demux)();
  58.      mach_msg_size_t max_size;
  59.      mach_port_t rcv_name;
  60.      mach_msg_option_t option;
  61.      mach_msg_timeout_t timeout;
  62. {
  63.     register mig_reply_header_t *bufRequest, *bufReply, *bufTemp;
  64.     register mach_msg_return_t mr;
  65.  
  66.     bufRequest = (mig_reply_header_t *) malloc(max_size);
  67.     if (bufRequest == 0)
  68.     return KERN_RESOURCE_SHORTAGE;
  69.     bufReply = (mig_reply_header_t *) malloc(max_size);
  70.     if (bufReply == 0)
  71.     return KERN_RESOURCE_SHORTAGE;
  72.  
  73.     for (;;) {
  74.       get_request:
  75.     mr = __mach_msg(&bufRequest->Head, MACH_RCV_MSG|option,
  76.             0, max_size, rcv_name,
  77.             timeout, MACH_PORT_NULL);
  78.     while (mr == MACH_MSG_SUCCESS) {
  79.         /* we have a request message */
  80.  
  81.         (void) (*demux)(&bufRequest->Head, &bufReply->Head);
  82.  
  83.         if (bufReply->RetCode != KERN_SUCCESS) {
  84.         if (bufReply->RetCode == MIG_NO_REPLY)
  85.             goto get_request;
  86.  
  87.         /* don't destroy the reply port right,
  88.            so we can send an error message */
  89.         bufRequest->Head.msgh_remote_port = MACH_PORT_NULL;
  90.         __mach_msg_destroy(&bufRequest->Head);
  91.         }
  92.  
  93.         if (bufReply->Head.msgh_remote_port == MACH_PORT_NULL) {
  94.         /* no reply port, so destroy the reply */
  95.         if (bufReply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX)
  96.             __mach_msg_destroy(&bufReply->Head);
  97.  
  98.         goto get_request;
  99.         }
  100.  
  101.         /* send reply and get next request */
  102.  
  103.         bufTemp = bufRequest;
  104.         bufRequest = bufReply;
  105.         bufReply = bufTemp;
  106.  
  107.         mr = __mach_msg(&bufRequest->Head,
  108.                 MACH_SEND_MSG|MACH_RCV_MSG|option,
  109.                 bufRequest->Head.msgh_size, max_size, rcv_name,
  110.                 timeout, MACH_PORT_NULL);
  111.     }
  112.  
  113.     /* a message error occurred */
  114.  
  115.     if (mr != MACH_SEND_INVALID_DEST)
  116.         break;
  117.  
  118.     /* the reply can't be delivered, so destroy it */
  119.     __mach_msg_destroy(&bufRequest->Head);
  120.     }
  121.  
  122.     free((char *) bufRequest);
  123.     free((char *) bufReply);
  124.     return mr;
  125. }
  126.  
  127.  
  128. mach_msg_return_t
  129. __mach_msg_server (demux, max_size, rcv_name)
  130.      boolean_t (*demux) ();
  131.      mach_msg_size_t max_size;
  132.      mach_port_t rcv_name;
  133. {
  134.   return __mach_msg_server_timeout (demux, max_size, rcv_name,
  135.                     MACH_MSG_OPTION_NONE,
  136.                     MACH_MSG_TIMEOUT_NONE);
  137. }
  138.