4
This program is free software; you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation; either version 2 of the License, or
7
(at your option) any later version.
9
This program 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
12
GNU General Public License for more details.
14
You should have received a copy of the GNU General Public License
15
along with this program; if not, write to the Free Software
16
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
Grame Research Laboratory, 9, rue du Garet 69001 Lyon - France
25
#include <mach/mach_error.h>
26
#include <servers/bootstrap.h>
27
#include <jack/internal.h>
28
#include <jack/engine.h>
29
#include <libjack/local.h> /* JOQ: fix me */
32
RPC without time out can put the jack server in a blocked state
33
(waiting for the client answer) when a client is killed. The
34
mach_msg function does not return any error in this case. Using
35
time out solve the problem but does not seems really satisfactory.
38
#define WAIT 2500 /* in millisecond */
41
jack_client_resume(jack_client_internal_t *client)
43
mach_msg_header_t *head = &client->message.header;
46
if (!client->running) {
47
err = mach_msg (head, MACH_RCV_MSG, 0, sizeof(client->message),
48
client->serverport, 0, MACH_PORT_NULL);
50
jack_error("jack_client_resume: priming receive error: %s\n",
51
mach_error_string(err));
54
client->running = TRUE;
56
/* remote port is already the send-once he sent us */
57
head->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, 0);
58
head->msgh_local_port = MACH_PORT_NULL;
59
head->msgh_size = sizeof(mach_msg_header_t);
61
err = mach_msg(head, (MACH_SEND_MSG|MACH_RCV_MSG|
62
MACH_SEND_TIMEOUT|MACH_RCV_TIMEOUT),
63
sizeof(*head), sizeof(client->message),
64
client->serverport, WAIT, MACH_PORT_NULL);
70
case MACH_SEND_TIMED_OUT:
71
jack_error("MACH_SEND_TIMED_OUT %s\n",
72
client->control->name);
75
case MACH_RCV_TIMED_OUT:
76
jack_error("MACH_RCV_TIMED_OUT %s\n",
77
client->control->name);
80
case MACH_SEND_INVALID_DEST:
81
jack_error("MACH_SEND_INVALID_DEST %s\n",
82
client->control->name);
87
jack_error("jack_client_resume: send error for %s\n",
88
mach_error_string(err));
97
jack_client_suspend(jack_client_t * client)
100
mach_msg_header_t * head = &client->message.header;
102
head->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND,
103
MACH_MSG_TYPE_MAKE_SEND_ONCE);
104
head->msgh_remote_port = client->serverport;
105
head->msgh_local_port = client->replyport;
106
head->msgh_size = sizeof(mach_msg_header_t);
108
err = mach_msg(head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_SEND_TIMEOUT,
109
sizeof(mach_msg_header_t), sizeof(client->message),
110
client->replyport, WAIT, MACH_PORT_NULL);
113
jack_error("jack_client_suspend: RPC error: %s\n",
114
mach_error_string(err));
122
allocate_mach_serverport(jack_engine_t * engine, jack_client_internal_t *client)
125
snprintf(buf, 256, "JackMachPort_%d", engine->portnum);
127
if (mach_port_allocate(engine->servertask, MACH_PORT_RIGHT_RECEIVE,
128
&client->serverport)){
129
jack_error("allocate_mach_serverport: can't allocate mach port");
132
if (mach_port_insert_right(engine->servertask, client->serverport,
133
client->serverport, MACH_MSG_TYPE_MAKE_SEND)){
134
jack_error("allocate_mach_serverport: error inserting mach rights");
137
if (bootstrap_register(engine->bp, buf, client->serverport)){
138
jack_error("allocate_mach_serverport: can't check in mach port");
141
client->portnum = engine->portnum;
146
allocate_mach_clientport(jack_client_t * client, int portnum)
149
snprintf(buf, 256, "JackMachPort_%d", portnum);
151
if (bootstrap_look_up(client->bp, buf, &client->serverport)){
152
jack_error ("allocate_mach_clientport: can't find mach server port");
156
if (mach_port_allocate(client->clienttask, MACH_PORT_RIGHT_RECEIVE,
157
&client->replyport)){
158
jack_error("allocate_mach_clientport: can't allocate mach port");