2 Copyright (C) 2004-2008 Grame
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 #include "JackTools.h"
21 #include "JackMachServerChannel.h"
22 #include "JackRPCEngineServer.c"
23 #include "JackError.h"
24 #include "JackServer.h"
25 #include "JackLockedEngine.h"
26 #include "JackNotification.h"
27 #include "JackServerGlobals.h"
34 map
<mach_port_t
, JackMachServerChannel
*> JackMachServerChannel::fPortTable
;
36 JackMachServerChannel::JackMachServerChannel():fThread(this)
39 JackMachServerChannel::~JackMachServerChannel()
42 int JackMachServerChannel::Open(const char* server_name
, JackServer
* server
)
44 jack_log("JackMachServerChannel::Open");
45 char jack_server_entry_name
[512];
46 snprintf(jack_server_entry_name
, sizeof(jack_server_entry_name
), "%s.%d_%s", jack_server_entry
, JackTools::GetUID(), server_name
);
48 if (!fServerPort
.AllocatePort(jack_server_entry_name
, 16)) { // 16 is the max possible value
49 jack_error("Cannot check in Jack server");
54 fPortTable
[fServerPort
.GetPort()] = this;
58 void JackMachServerChannel::Close()
60 jack_log("JackMachServerChannel::Close");
62 fServerPort
.DestroyPort();
65 int JackMachServerChannel::Start()
67 if (fThread
.Start() != 0) {
68 jack_error("Cannot start Jack server listener");
75 JackLockedEngine
* JackMachServerChannel::GetEngine()
77 return fServer
->GetEngine();
80 JackServer
* JackMachServerChannel::GetServer()
85 void JackMachServerChannel::ClientCheck(char* name
, char* name_res
, int protocol
, int options
, int* status
, int* result
)
87 *result
= GetEngine()->ClientCheck(name
, name_res
, protocol
, options
, status
);
90 void JackMachServerChannel::ClientOpen(char* name
, int pid
, mach_port_t
* private_port
, int* shared_engine
, int* shared_client
, int* shared_graph
, int* result
)
93 *result
= GetEngine()->ClientExternalOpen(name
, pid
, &refnum
, shared_engine
, shared_client
, shared_graph
);
96 mach_port_t port
= fServerPort
.AddPort();
98 fClientTable
[port
] = refnum
;
99 fPortTable
[port
] = this;
100 *private_port
= port
;
102 jack_error("Cannot create private client mach port");
106 jack_error("Cannot create new client");
110 void JackMachServerChannel::ClientClose(mach_port_t private_port
, int refnum
)
112 GetEngine()->ClientExternalClose(refnum
);
113 fClientTable
.erase(private_port
);
117 if ((res
= mach_port_destroy(mach_task_self(), private_port
)) != KERN_SUCCESS
) {
118 jack_error("server_rpc_jack_client_close mach_port_destroy %s", mach_error_string(res
));
122 void JackMachServerChannel::ClientKill(mach_port_t private_port
)
124 jack_log("JackMachServerChannel::ClientKill");
125 int refnum
= fClientTable
[private_port
];
127 fServer
->ClientKill(refnum
);
128 fClientTable
.erase(private_port
);
132 if ((res
= mach_port_destroy(mach_task_self(), private_port
)) != KERN_SUCCESS
) {
133 jack_error("server_rpc_jack_client_close mach_port_destroy %s", mach_error_string(res
));
137 boolean_t
JackMachServerChannel::MessageHandler(mach_msg_header_t
* Request
, mach_msg_header_t
* Reply
)
139 if (Request
->msgh_id
== MACH_NOTIFY_NO_SENDERS
) {
140 jack_log("MACH_NOTIFY_NO_SENDERS %ld", Request
->msgh_local_port
);
141 JackMachServerChannel
* channel
= JackMachServerChannel::fPortTable
[Request
->msgh_local_port
];
143 channel
->ClientKill(Request
->msgh_local_port
);
145 JackRPCEngine_server(Request
, Reply
);
150 bool JackMachServerChannel::Execute()
155 if ((res
= mach_msg_server(MessageHandler
, 1024, fServerPort
.GetPortSet(), 0)) != KERN_SUCCESS
) {
156 jack_log("JackMachServerChannel::Execute: err = %s", mach_error_string(res
));
161 } catch (JackQuitException
& e
) {
162 jack_log("JackMachServerChannel::Execute JackQuitException");
167 } // end of namespace