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"
33 map
<mach_port_t
, JackMachServerChannel
*> JackMachServerChannel::fPortTable
;
35 JackMachServerChannel::JackMachServerChannel():fThread(this)
38 JackMachServerChannel::~JackMachServerChannel()
41 int JackMachServerChannel::Open(const char* server_name
, JackServer
* server
)
43 jack_log("JackMachServerChannel::Open");
44 char jack_server_entry_name
[512];
45 snprintf(jack_server_entry_name
, sizeof(jack_server_entry_name
), "%s.%d_%s", jack_server_entry
, JackTools::GetUID(), server_name
);
47 if (!fServerPort
.AllocatePort(jack_server_entry_name
, 16)) { // 16 is the max possible value
48 jack_error("Cannot check in Jack server");
52 if (fThread
.Start() != 0) {
53 jack_error("Cannot start Jack server listener");
58 fPortTable
[fServerPort
.GetPort()] = this;
62 void JackMachServerChannel::Close()
64 jack_log("JackMachServerChannel::Close");
66 fServerPort
.DestroyPort();
69 JackLockedEngine
* JackMachServerChannel::GetEngine()
71 return fServer
->GetEngine();
74 JackServer
* JackMachServerChannel::GetServer()
79 void JackMachServerChannel::ClientCheck(char* name
, char* name_res
, int protocol
, int options
, int* status
, int* result
)
81 *result
= GetEngine()->ClientCheck(name
, name_res
, protocol
, options
, status
);
84 void JackMachServerChannel::ClientOpen(char* name
, int pid
, mach_port_t
* private_port
, int* shared_engine
, int* shared_client
, int* shared_graph
, int* result
)
87 *result
= GetEngine()->ClientExternalOpen(name
, pid
, &refnum
, shared_engine
, shared_client
, shared_graph
);
90 mach_port_t port
= fServerPort
.AddPort();
92 fClientTable
[port
] = refnum
;
93 fPortTable
[port
] = this;
96 jack_error("Cannot create private client mach port");
100 jack_error("Cannot create new client");
104 void JackMachServerChannel::ClientClose(mach_port_t private_port
, int refnum
)
106 GetEngine()->ClientExternalClose(refnum
);
107 fClientTable
.erase(private_port
);
111 if ((res
= mach_port_destroy(mach_task_self(), private_port
)) != KERN_SUCCESS
) {
112 jack_error("server_rpc_jack_client_close mach_port_destroy %s", mach_error_string(res
));
116 void JackMachServerChannel::ClientKill(mach_port_t private_port
)
118 jack_log("JackMachServerChannel::ClientKill");
119 int refnum
= fClientTable
[private_port
];
121 fServer
->ClientKill(refnum
);
122 fClientTable
.erase(private_port
);
126 if ((res
= mach_port_destroy(mach_task_self(), private_port
)) != KERN_SUCCESS
) {
127 jack_error("server_rpc_jack_client_close mach_port_destroy %s", mach_error_string(res
));
131 boolean_t
JackMachServerChannel::MessageHandler(mach_msg_header_t
* Request
, mach_msg_header_t
* Reply
)
133 if (Request
->msgh_id
== MACH_NOTIFY_NO_SENDERS
) {
134 jack_log("MACH_NOTIFY_NO_SENDERS %ld", Request
->msgh_local_port
);
135 JackMachServerChannel
* channel
= JackMachServerChannel::fPortTable
[Request
->msgh_local_port
];
137 channel
->ClientKill(Request
->msgh_local_port
);
139 JackRPCEngine_server(Request
, Reply
);
144 bool JackMachServerChannel::Execute()
147 if ((res
= mach_msg_server(MessageHandler
, 1024, fServerPort
.GetPortSet(), 0)) != KERN_SUCCESS
) {
148 jack_log("JackMachServerChannel::Execute: err = %s", mach_error_string(res
));
150 //return (res == KERN_SUCCESS); mach_msg_server can fail if the client reply port is not valid anymore (crashed client)
154 } // end of namespace