]> git.ipfire.org Git - thirdparty/glibc.git/blame - mach/msgserver.c
2001-04-07 Roland McGrath <roland@frob.com>
[thirdparty/glibc.git] / mach / msgserver.c
CommitLineData
6c2a1e81 1/* Copyright (C) 1993, 1994, 1995, 1996, 2001 Free Software Foundation, Inc.
6d52618b 2 This file is part of the GNU C Library.
28f540f4 3
6d52618b
UD
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
28f540f4 8
6d52618b
UD
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
28f540f4 13
6d52618b
UD
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If not,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. */
28f540f4
RM
18
19/* Based on CMU's mach_msg_server.c revision 2.4 of 91/05/14, and thus
20 under the following copyright. Rewritten by Roland McGrath (FSF)
21 93/12/06 to use stack space instead of malloc, and to handle
22 large messages with MACH_RCV_LARGE. */
23
19c3f208 24/*
28f540f4
RM
25 * Mach Operating System
26 * Copyright (c) 1991,1990 Carnegie Mellon University
27 * All Rights Reserved.
19c3f208 28 *
28f540f4
RM
29 * Permission to use, copy, modify and distribute this software and its
30 * documentation is hereby granted, provided that both the copyright
31 * notice and this permission notice appear in all copies of the
32 * software, derivative works or modified versions, and any portions
33 * thereof, and that both notices appear in supporting documentation.
19c3f208 34 *
28f540f4
RM
35 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
36 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
37 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19c3f208 38 *
28f540f4 39 * Carnegie Mellon requests users of this software to return to
19c3f208 40 *
28f540f4
RM
41 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
42 * School of Computer Science
43 * Carnegie Mellon University
44 * Pittsburgh PA 15213-3890
19c3f208 45 *
28f540f4
RM
46 * any improvements or extensions that they make and grant Carnegie Mellon
47 * the rights to redistribute these changes.
48 */
49/*
50 * HISTORY
51 * $Log$
6c2a1e81
RM
52 * Revision 1.6 2001/04/09 21:23:38 roland
53 * 2001-04-07 Roland McGrath <roland@frob.com>
54 *
55 * * mach/msgserver.c (__mach_msg_server_timeout): Add an assert.
56 *
6d52618b
UD
57 * Revision 1.5 1996/12/20 01:32:35 drepper
58 * Update from main archive 961219
59 *
60 * Revision 1.5 1996/12/19 20:23:45 drepper
61 * Spelling corrections.
62 *
19c3f208
RM
63 * Revision 1.4 1996/01/29 15:44:23 roland
64 * Declare DEMUX arg with prototype.
65 *
66 * Revision 1.3 1995/01/21 15:00:57 roland
28f540f4
RM
67 * Converted to use weak aliases with macros from libc-symbols.h.
68 *
69 * Revision 1.2 1994/10/10 07:20:14 roland
70 * Increase default MAX_SIZE to two pages.
71 *
72 * Revision 1.1 1993/12/06 23:25:25 roland
73 * entered into RCS
74 *
75 * Revision 2.4 91/05/14 17:53:22 mrt
76 * Correcting copyright
19c3f208 77 *
28f540f4
RM
78 * Revision 2.3 91/02/14 14:17:47 mrt
79 * Added new Mach copyright
80 * [91/02/13 12:44:20 mrt]
19c3f208 81 *
28f540f4
RM
82 * Revision 2.2 90/08/06 17:23:58 rpd
83 * Created.
19c3f208 84 *
28f540f4
RM
85 */
86
87
88#include <mach.h>
89#include <mach/mig_errors.h>
90#include <stdlib.h> /* For malloc and free. */
6c2a1e81 91#include <assert.h>
28f540f4
RM
92
93mach_msg_return_t
94__mach_msg_server_timeout (boolean_t (*demux) (mach_msg_header_t *request,
95 mach_msg_header_t *reply),
96 mach_msg_size_t max_size,
97 mach_port_t rcv_name,
98 mach_msg_option_t option,
99 mach_msg_timeout_t timeout)
100{
101 register mig_reply_header_t *request, *reply;
102 register mach_msg_return_t mr;
103
104 if (max_size == 0)
105 {
106 option |= MACH_RCV_LARGE;
107 max_size = 2 * __vm_page_size; /* Generic. Good? XXX */
108 }
109
110 request = __alloca (max_size);
111 reply = __alloca (max_size);
112
113 while (1)
114 {
115 get_request:
116 mr = __mach_msg (&request->Head, MACH_RCV_MSG|option,
117 0, max_size, rcv_name,
118 timeout, MACH_PORT_NULL);
119 while (mr == MACH_MSG_SUCCESS)
120 {
121 /* We have a request message.
122 Pass it to DEMUX for processing. */
123
124 (void) (*demux) (&request->Head, &reply->Head);
6c2a1e81 125 assert (reply->Head.msgh_size <= max_size);
28f540f4
RM
126
127 switch (reply->RetCode)
128 {
129 case KERN_SUCCESS:
130 /* Hunky dory. */
131 break;
132
133 case MIG_NO_REPLY:
134 /* The server function wanted no reply sent.
135 Loop for another request. */
136 goto get_request;
137
138 default:
139 /* Some error; destroy the request message to release any
140 port rights or VM it holds. Don't destroy the reply port
141 right, so we can send an error message. */
142 request->Head.msgh_remote_port = MACH_PORT_NULL;
143 __mach_msg_destroy (&request->Head);
144 break;
145 }
146
147 if (reply->Head.msgh_remote_port == MACH_PORT_NULL)
148 {
149 /* No reply port, so destroy the reply. */
150 if (reply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX)
151 __mach_msg_destroy (&reply->Head);
152 goto get_request;
153 }
154
155 /* Send the reply and the get next request. */
156
157 {
158 /* Swap the request and reply buffers. mach_msg will read the
159 reply message from the buffer we pass and write the new
160 request message to the same buffer. */
161 void *tmp = request;
162 request = reply;
163 reply = tmp;
164 }
165
166 mr = __mach_msg (&request->Head,
167 MACH_SEND_MSG|MACH_RCV_MSG|option,
168 request->Head.msgh_size, max_size, rcv_name,
169 timeout, MACH_PORT_NULL);
170 }
171
172 /* A message error occurred. */
173
174 switch (mr)
175 {
176 case MACH_RCV_TOO_LARGE:
177 /* The request message is larger than MAX_SIZE, and has not
6d52618b 178 been dequeued. The message header has the actual size of
28f540f4
RM
179 the message. We recurse here in hopes that the compiler
180 will optimize the tail-call and allocate some more stack
181 space instead of way too much. */
182 return __mach_msg_server_timeout (demux, request->Head.msgh_size,
183 rcv_name, option, timeout);
184
185 case MACH_SEND_INVALID_DEST:
186 /* The reply can't be delivered, so destroy it. This error
6d52618b 187 indicates only that the requester went away, so we
28f540f4
RM
188 continue and get the next request. */
189 __mach_msg_destroy (&request->Head);
190 break;
191
192 default:
193 /* Some other form of lossage; return to caller. */
194 return mr;
195 }
196 }
197}
198weak_alias (__mach_msg_server_timeout, mach_msg_server_timeout)
199
200mach_msg_return_t
201__mach_msg_server (demux, max_size, rcv_name)
19c3f208 202 boolean_t (*demux) (mach_msg_header_t *in, mach_msg_header_t *out);
28f540f4
RM
203 mach_msg_size_t max_size;
204 mach_port_t rcv_name;
205{
206 return __mach_msg_server_timeout (demux, max_size, rcv_name,
207 MACH_MSG_OPTION_NONE,
208 MACH_MSG_TIMEOUT_NONE);
209}
210weak_alias (__mach_msg_server, mach_msg_server)