88 lines
2.7 KiB
Plaintext
88 lines
2.7 KiB
Plaintext
/*
|
|
Copyright (C) 2021 Peter Bridgman
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
the Free Software Foundation; either version 2.1 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
#include "JackMachSemaphoreServer.h"
|
|
#include "JackMachUtils.h"
|
|
#include "JackConstants.h"
|
|
#include "JackTools.h"
|
|
#include "JackError.h"
|
|
|
|
#include <mach/message.h>
|
|
|
|
#define jack_mach_error(kern_result, message) \
|
|
jack_mach_error_uncurried("JackMachSemaphoreServer", kern_result, message)
|
|
|
|
namespace Jack
|
|
{
|
|
|
|
bool JackMachSemaphoreServer::Execute() {
|
|
jack_log("JackMachSemaphoreServer::Execute: %s", fName);
|
|
|
|
/* Setup a message struct in our local stack frame which we can receive messages into and send
|
|
* messages from. */
|
|
struct {
|
|
mach_msg_header_t hdr;
|
|
mach_msg_trailer_t trailer;
|
|
} msg;
|
|
|
|
// Block until we receive a message on the fServerReceive port.
|
|
mach_msg_return_t recv_err = mach_msg(
|
|
&msg.hdr,
|
|
MACH_RCV_MSG,
|
|
0,
|
|
sizeof(msg),
|
|
fServerReceive,
|
|
MACH_MSG_TIMEOUT_NONE,
|
|
MACH_PORT_NULL
|
|
);
|
|
|
|
if (recv_err != MACH_MSG_SUCCESS) {
|
|
jack_mach_error(recv_err, "receive error");
|
|
return true; // Continue processing more connections
|
|
}
|
|
|
|
/* We're going to reuse the message struct that we received the message into to send a reply.
|
|
* Setup the semaphore send port that we want to give to the client as the local port... */
|
|
msg.hdr.msgh_local_port = fSemaphore;
|
|
|
|
/*
|
|
* ... to be returned by copy (_COPY_SEND), to a destination that is _SEND_ONCE that we no
|
|
* longer require. That destination will have been set by the client as their local_port, so
|
|
* will now already be the remote_port in the message we received (nifty, eh?).
|
|
*/
|
|
msg.hdr.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, MACH_MSG_TYPE_COPY_SEND);
|
|
|
|
mach_msg_return_t send_err = mach_msg(
|
|
&msg.hdr,
|
|
MACH_SEND_MSG,
|
|
sizeof(msg.hdr), // no trailer on send
|
|
0,
|
|
MACH_PORT_NULL,
|
|
MACH_MSG_TIMEOUT_NONE,
|
|
MACH_PORT_NULL);
|
|
|
|
if (send_err != MACH_MSG_SUCCESS) {
|
|
jack_mach_error(send_err, "send error");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
} // end of namespace
|