jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

88 lines
2.7KB

  1. /*
  2. Copyright (C) 2021 Peter Bridgman
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU Lesser General Public License as published by
  5. the Free Software Foundation; either version 2.1 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. #include "JackMachSemaphoreServer.h"
  16. #include "JackMachUtils.h"
  17. #include "JackConstants.h"
  18. #include "JackTools.h"
  19. #include "JackError.h"
  20. #include <mach/message.h>
  21. #define jack_mach_error(kern_result, message) \
  22. jack_mach_error_uncurried("JackMachSemaphoreServer", kern_result, message)
  23. namespace Jack
  24. {
  25. bool JackMachSemaphoreServer::Execute() {
  26. jack_log("JackMachSemaphoreServer::Execute: %s", fName);
  27. /* Setup a message struct in our local stack frame which we can receive messages into and send
  28. * messages from. */
  29. struct {
  30. mach_msg_header_t hdr;
  31. mach_msg_trailer_t trailer;
  32. } msg;
  33. // Block until we receive a message on the fServerReceive port.
  34. mach_msg_return_t recv_err = mach_msg(
  35. &msg.hdr,
  36. MACH_RCV_MSG,
  37. 0,
  38. sizeof(msg),
  39. fServerReceive,
  40. MACH_MSG_TIMEOUT_NONE,
  41. MACH_PORT_NULL
  42. );
  43. if (recv_err != MACH_MSG_SUCCESS) {
  44. jack_mach_error(recv_err, "receive error");
  45. return true; // Continue processing more connections
  46. }
  47. /* We're going to reuse the message struct that we received the message into to send a reply.
  48. * Setup the semaphore send port that we want to give to the client as the local port... */
  49. msg.hdr.msgh_local_port = fSemaphore;
  50. /*
  51. * ... to be returned by copy (_COPY_SEND), to a destination that is _SEND_ONCE that we no
  52. * longer require. That destination will have been set by the client as their local_port, so
  53. * will now already be the remote_port in the message we received (nifty, eh?).
  54. */
  55. msg.hdr.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, MACH_MSG_TYPE_COPY_SEND);
  56. mach_msg_return_t send_err = mach_msg(
  57. &msg.hdr,
  58. MACH_SEND_MSG,
  59. sizeof(msg.hdr), // no trailer on send
  60. 0,
  61. MACH_PORT_NULL,
  62. MACH_MSG_TIMEOUT_NONE,
  63. MACH_PORT_NULL);
  64. if (send_err != MACH_MSG_SUCCESS) {
  65. jack_mach_error(send_err, "send error");
  66. }
  67. return true;
  68. }
  69. } // end of namespace