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