Browse Source

Make JackMachSemaphore more robust, dont use thread_terminate

Fixes #841
tags/v1.9.21
falkTX 1 year 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 {
fSemaphore = msg.hdr.msgh_remote_port;

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

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

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

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.
}

@@ -378,16 +383,20 @@ void JackMachSemaphore::Destroy()
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);


+ 9
- 5
macosx/JackMachSemaphoreServer.h View File

@@ -34,21 +34,25 @@ class SERVER_EXPORT JackMachSemaphoreServer : public JackRunnableInterface
{
private:
/*! \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. */
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
* 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:
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 Invalidate();
};

} // end of namespace


+ 23
- 1
macosx/JackMachSemaphoreServer.mm View File

@@ -52,9 +52,14 @@ bool JackMachSemaphoreServer::Execute() {
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) {
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.
@@ -81,6 +86,23 @@ bool JackMachSemaphoreServer::Execute() {
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;
}



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

int JackMachThread::AcquireRealTime()


Loading…
Cancel
Save