Browse Source

Make JackMachSemaphore more robust, dont use thread_terminate

Fixes #841
tags/v1.9.21
falkTX 3 years ago
parent
commit
45042beac5
4 changed files with 58 additions and 18 deletions
  1. +21
    -12
      macosx/JackMachSemaphore.mm
  2. +9
    -5
      macosx/JackMachSemaphoreServer.h
  3. +23
    -1
      macosx/JackMachSemaphoreServer.mm
  4. +5
    -0
      macosx/JackMachThread.mm

+ 21
- 12
macosx/JackMachSemaphore.mm View File

@@ -305,7 +305,7 @@ bool JackMachSemaphore::ConnectInput(const char* client_name, const char* server
} else { } else {
fSemaphore = msg.hdr.msgh_remote_port; fSemaphore = msg.hdr.msgh_remote_port;


jack_log("JackMachSemaphore::Connect: OK, name = %s ", fName);
jack_log("JackMachSemaphore::Connect: OK, name = %s", fName);
return true; return true;
} }
} }
@@ -353,17 +353,22 @@ bool JackMachSemaphore::Disconnect()
// Server side : destroy the JackGlobals // Server side : destroy the JackGlobals
void JackMachSemaphore::Destroy() void JackMachSemaphore::Destroy()
{ {
const mach_port_t task = mach_task_self();
kern_return_t res; kern_return_t res;
mach_port_t task = mach_task_self();


if (fSemaphore == MACH_PORT_NULL) { if (fSemaphore == MACH_PORT_NULL) {
jack_error("JackMachSemaphore::Destroy semaphore is MACH_PORT_NULL; already destroyed?"); jack_error("JackMachSemaphore::Destroy semaphore is MACH_PORT_NULL; already destroyed?");
return; return;
} }


if (fSemServer && fSemServer->Invalidate()) {
fServicePort = MACH_PORT_NULL;
fSemaphore = MACH_PORT_NULL;
}

if (fThreadSemServer) { if (fThreadSemServer) {
if (fThreadSemServer->Kill() < 0) {
jack_error("JackMachSemaphore::Destroy failed to kill semaphore server thread...");
if (fThreadSemServer->Stop() < 0) {
jack_error("JackMachSemaphore::Destroy failed to stop semaphore server thread...");
// Oh dear. How sad. Never mind. // Oh dear. How sad. Never mind.
} }


@@ -378,16 +383,20 @@ void JackMachSemaphore::Destroy()
delete server; delete server;
} }


if ((res = mach_port_destroy(task, fServicePort)) != KERN_SUCCESS) {
jack_mach_error(res, "failed to destroy IPC port");
} else {
fServicePort = MACH_PORT_NULL;
if (fServicePort != MACH_PORT_NULL) {
if ((res = mach_port_destroy(task, fServicePort)) != KERN_SUCCESS) {
jack_mach_error(res, "failed to destroy IPC port");
} else {
fServicePort = MACH_PORT_NULL;
}
} }


if ((res = semaphore_destroy(mach_task_self(), fSemaphore)) != KERN_SUCCESS) {
jack_mach_error(res, "failed to destroy semaphore");
} else {
fSemaphore = MACH_PORT_NULL;
if (fSemaphore != MACH_PORT_NULL) {
if ((res = semaphore_destroy(mach_task_self(), fSemaphore)) != KERN_SUCCESS) {
jack_mach_error(res, "failed to destroy semaphore");
} else {
fSemaphore = MACH_PORT_NULL;
}
} }


jack_log("JackMachSemaphore::Destroy: OK, name = %s", fName); jack_log("JackMachSemaphore::Destroy: OK, name = %s", fName);


+ 9
- 5
macosx/JackMachSemaphoreServer.h View File

@@ -34,21 +34,25 @@ class SERVER_EXPORT JackMachSemaphoreServer : public JackRunnableInterface
{ {
private: private:
/*! \brief The semaphore send right that will be dispatched to clients. */ /*! \brief The semaphore send right that will be dispatched to clients. */
semaphore_t fSemaphore;
const semaphore_t fSemaphore;


/*! \brief The port on which we will listen for IPC messages. */ /*! \brief The port on which we will listen for IPC messages. */
mach_port_t fServerReceive;
const mach_port_t fServerReceive;


/*! \brief A pointer to a null-terminated string buffer that will be read to obtain the /*! \brief A pointer to a null-terminated string buffer that will be read to obtain the
* server name for reporting purposes. Not managed at all by this type. */ * server name for reporting purposes. Not managed at all by this type. */
char* fName;
const char* const fName;

/*! \brief Whether thread should keep running. */
bool fRunning;


public: public:
JackMachSemaphoreServer(semaphore_t semaphore, mach_port_t server_recv, char* name):
fSemaphore(semaphore), fServerReceive(server_recv), fName(name)
JackMachSemaphoreServer(semaphore_t semaphore, mach_port_t server_recv, const char* name):
fSemaphore(semaphore), fServerReceive(server_recv), fName(name), fRunning(true)
{} {}


bool Execute() override; bool Execute() override;
bool Invalidate();
}; };


} // end of namespace } // end of namespace


+ 23
- 1
macosx/JackMachSemaphoreServer.mm View File

@@ -52,9 +52,14 @@ bool JackMachSemaphoreServer::Execute() {
MACH_PORT_NULL MACH_PORT_NULL
); );


// this error is expected when deleting ports, we get notified that they somehow changed
if (recv_err == MACH_RCV_PORT_CHANGED) {
return fRunning;
}

if (recv_err != MACH_MSG_SUCCESS) { if (recv_err != MACH_MSG_SUCCESS) {
jack_mach_error(recv_err, "receive error"); jack_mach_error(recv_err, "receive error");
return true; // Continue processing more connections
return fRunning; // Continue processing more connections
} }


/* We're going to reuse the message struct that we received the message into to send a reply. /* We're going to reuse the message struct that we received the message into to send a reply.
@@ -81,6 +86,23 @@ bool JackMachSemaphoreServer::Execute() {
jack_mach_error(send_err, "send error"); jack_mach_error(send_err, "send error");
} }


return fRunning;
}

bool JackMachSemaphoreServer::Invalidate() {
fRunning = false;

const mach_port_t task = mach_task_self();
kern_return_t res;

if ((res = mach_port_destroy(task, fServerReceive)) != KERN_SUCCESS) {
jack_mach_error(res, "failed to destroy IPC port");
}

if ((res = semaphore_destroy(task, fSemaphore)) != KERN_SUCCESS) {
jack_mach_error(res, "failed to destroy semaphore");
}

return true; return true;
} }




+ 5
- 0
macosx/JackMachThread.mm View File

@@ -160,6 +160,8 @@ int JackMachThread::GetParams(jack_native_thread_t thread, UInt64* period, UInt6


int JackMachThread::Kill() int JackMachThread::Kill()
{ {
#if 0
// NOTE: starting macOS 12, this code no longer works
if (fThread != (jack_native_thread_t)NULL) { // If thread has been started if (fThread != (jack_native_thread_t)NULL) { // If thread has been started
jack_log("JackMachThread::Kill"); jack_log("JackMachThread::Kill");
mach_port_t machThread = pthread_mach_thread_np(fThread); mach_port_t machThread = pthread_mach_thread_np(fThread);
@@ -170,6 +172,9 @@ int JackMachThread::Kill()
} else { } else {
return -1; return -1;
} }
#else
return JackPosixThread::Kill();
#endif
} }


int JackMachThread::AcquireRealTime() int JackMachThread::AcquireRealTime()


Loading…
Cancel
Save