Il 05/07/23 09:59, Damien Zammit ha scritto:
diff --git a/libirqhelp/irqhelp.c b/libirqhelp/irqhelp.c new file mode 100644 index 000000000..bafae6cf1 --- /dev/null +++ b/libirqhelp/irqhelp.c +void * +irqhelp_server_loop(void *arg) +{ + struct irq *irq = (struct irq *)arg; + + if (!irq) + { + printf("irqhelp cannot start this irq thread\n"); + return NULL; + } + + int interrupt_demuxer (mach_msg_header_t *inp, + mach_msg_header_t *outp) + { + device_intr_notification_t *n = (device_intr_notification_t *) inp; + + ((mig_reply_header_t *) outp)->RetCode = MIG_NO_REPLY; + if (n->intr_header.msgh_id != DEVICE_INTR_NOTIFY) + return 0; /* not an interrupt */ + + /* FIXME: id <-> gsi now has an indirection, assuming 1:1 */ + if (n->id != irq->gsi) + return 0; /* interrupt not for us */ + + /* wait if irq disabled */ + pthread_mutex_lock (&irq->irqlock); + while (!irq->enabled) + pthread_cond_wait (&irq->irqcond, &irq->irqlock); + pthread_mutex_unlock (&irq->irqlock); > + + /* call handler */ + irq->handler(irq->context); + + /* ACK interrupt */ + device_intr_ack (irqdev, irq->port, MACH_MSG_TYPE_MAKE_SEND); + + if (irq->shutdown) + { + mach_port_deallocate(mach_task_self (), irq->port); + irq->port = MACH_PORT_NULL; + pthread_cond_destroy(&irq->irqcond); + pthread_mutex_destroy(&irq->irqlock); + free(irq); + pthread_exit(NULL);
This would prevent the thread calling irqhelp_server_loop() to do some cleanup. Looking at the implementation in glibc (in mach/msgserver.c), maybe one way would be to set a bad reply message, that would cause an error different from MACH_SEND_INVALID_DEST or MACH_RCV_TOO_LARGE, so the server loop will return with this error code. It's a bit hacky but I don't know if there is another way, since the demuxer return code seems ignored.
Luca