|
- /*
- 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
|