home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / glibc-1.06 / mach / __msg_dest.c next >
Encoding:
C/C++ Source or Header  |  1991-10-22  |  3.9 KB  |  148 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_destroy.c,v $
  29.  * Revision 2.4  91/05/14  17:53:15  mrt
  30.  *     Correcting copyright
  31.  * 
  32.  * Revision 2.3  91/02/14  14:17:43  mrt
  33.  *     Added new Mach copyright
  34.  *     [91/02/13  12:44:15  mrt]
  35.  * 
  36.  * Revision 2.2  90/08/06  17:24:22  rpd
  37.  *     Created.
  38.  * 
  39.  */
  40.  
  41. #include <mach/port.h>
  42. #include <mach/message.h>
  43. #include <mach_init.h>
  44.  
  45. static void mach_msg_destroy_port();
  46. static void mach_msg_destroy_memory();
  47.  
  48. /*
  49.  *    Routine:    mach_msg_destroy
  50.  *    Purpose:
  51.  *        Deallocates all port rights and out-of-line memory
  52.  *        found in a received message.
  53.  */
  54.  
  55. void
  56. __mach_msg_destroy(msg)
  57.     mach_msg_header_t *msg;
  58. {
  59.     mach_msg_bits_t mbits = msg->msgh_bits;
  60.  
  61.     /*
  62.      *    The msgh_local_port field doesn't hold a port right.
  63.      *    The receive operation consumes the destination port right.
  64.      */
  65.  
  66.     mach_msg_destroy_port(msg->msgh_remote_port, MACH_MSGH_BITS_REMOTE(mbits));
  67.  
  68.     if (mbits & MACH_MSGH_BITS_COMPLEX) {
  69.     vm_offset_t saddr;
  70.     vm_offset_t eaddr;
  71.  
  72.     saddr = (vm_offset_t) (msg + 1);
  73.     eaddr = (vm_offset_t) msg + msg->msgh_size;
  74.  
  75.     while (saddr < eaddr) {
  76.         mach_msg_type_long_t *type;
  77.         mach_msg_type_name_t name;
  78.         mach_msg_type_size_t size;
  79.         mach_msg_type_number_t number;
  80.         boolean_t is_inline;
  81.         vm_size_t length;
  82.         vm_offset_t addr;
  83.  
  84.         type = (mach_msg_type_long_t *) saddr;
  85.         is_inline = type->msgtl_header.msgt_inline;
  86.         if (type->msgtl_header.msgt_longform) {
  87.             name = type->msgtl_name;
  88.             size = type->msgtl_size;
  89.             number = type->msgtl_number;
  90.             saddr += sizeof(mach_msg_type_long_t);
  91.         } else {
  92.             name = type->msgtl_header.msgt_name;
  93.             size = type->msgtl_header.msgt_size;
  94.             number = type->msgtl_header.msgt_number;
  95.             saddr += sizeof(mach_msg_type_t);
  96.         }
  97.  
  98.         /* calculate length of data in bytes, rounding up */
  99.         length = ((((number * size) + 7) >> 3) + 3) &~ 3;
  100.  
  101.         addr = is_inline ? saddr : * (vm_offset_t *) saddr;
  102.  
  103.         if (MACH_MSG_TYPE_PORT_ANY(name)) {
  104.         mach_port_t *ports = (mach_port_t *) addr;
  105.         mach_msg_type_number_t i;
  106.  
  107.         for (i = 0; i < number; i++)
  108.             mach_msg_destroy_port(*ports++, name);
  109.         }
  110.  
  111.         if (is_inline) {
  112.         /* inline data sizes round up to int boundaries */
  113.         saddr += length;
  114.         } else {
  115.         mach_msg_destroy_memory(addr, length);
  116.         saddr += sizeof(vm_offset_t);
  117.         }
  118.     }
  119.     }
  120. }
  121.  
  122. static void
  123. mach_msg_destroy_port(port, type)
  124.     mach_port_t port;
  125.     mach_msg_type_name_t type;
  126. {
  127.     if (MACH_PORT_VALID(port)) switch (type) {
  128.       case MACH_MSG_TYPE_PORT_SEND:
  129.       case MACH_MSG_TYPE_PORT_SEND_ONCE:
  130.     (void) __mach_port_deallocate(__mach_task_self(), port);
  131.     break;
  132.  
  133.       case MACH_MSG_TYPE_PORT_RECEIVE:
  134.     (void) __mach_port_mod_refs(__mach_task_self(), port,
  135.                     MACH_PORT_RIGHT_RECEIVE, -1);
  136.     break;
  137.     }
  138. }
  139.  
  140. static void
  141. mach_msg_destroy_memory(addr, size)
  142.     vm_offset_t addr;
  143.     vm_size_t size;
  144. {
  145.     if (size > 0)
  146.     (void) __vm_deallocate(__mach_task_self(), addr, size);
  147. }
  148.